ubon
Version:
Security scanner for AI-generated React/Next.js and Python apps. Catches hardcoded secrets, accessibility issues, and vulnerabilities that traditional linters miss.
88 lines (87 loc) • 3.53 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getChangedFilesSince = getChangedFilesSince;
exports.getRecentCommitHashes = getRecentCommitHashes;
exports.ensureGitRepo = ensureGitRepo;
exports.createBranchCommitPush = createBranchCommitPush;
exports.tryOpenPullRequest = tryOpenPullRequest;
const child_process_1 = require("child_process");
function getChangedFilesSince(ref, cwd) {
try {
const out = (0, child_process_1.execSync)(`git diff --name-only ${ref}`, { cwd, encoding: 'utf8' });
return out.split('\n').map(s => s.trim()).filter(Boolean);
}
catch {
return [];
}
}
function getRecentCommitHashes(depth, cwd) {
try {
const out = (0, child_process_1.execSync)(`git rev-list --max-count=${depth} HEAD`, { cwd, encoding: 'utf8' });
return out.split('\n').map(s => s.trim()).filter(Boolean);
}
catch {
return [];
}
}
function ensureGitRepo(cwd) {
try {
(0, child_process_1.execSync)('git rev-parse --is-inside-work-tree', { cwd, stdio: 'ignore' });
return true;
}
catch {
return false;
}
}
function createBranchCommitPush(options) {
const base = options.baseBranch || 'main';
const branch = options.featureBranch;
try {
// Ensure up-to-date
try {
(0, child_process_1.execSync)('git fetch --all --prune', { cwd: options.cwd, stdio: 'ignore' });
}
catch { }
// Create and switch to feature branch
(0, child_process_1.execSync)(`git checkout -B ${branch} ${base}`, { cwd: options.cwd, stdio: 'inherit' });
// Stage and commit
(0, child_process_1.execSync)('git add -A', { cwd: options.cwd, stdio: 'inherit' });
// If nothing to commit, skip commit step
try {
(0, child_process_1.execSync)(`git commit -m "${options.title.replace(/"/g, '\\"')}"`, { cwd: options.cwd, stdio: 'inherit' });
}
catch { }
// Push branch
(0, child_process_1.execSync)(`git push -u origin ${branch}`, { cwd: options.cwd, stdio: 'inherit' });
// Get repo url
const remote = (0, child_process_1.execSync)('git config --get remote.origin.url', { cwd: options.cwd, encoding: 'utf8' }).trim();
const remoteUrl = remote.replace(/^git@github.com:/, 'https://github.com/').replace(/\.git$/, '');
return { pushed: true, remoteUrl };
}
catch {
return { pushed: false };
}
}
function tryOpenPullRequest(cwd, base, head, title, body) {
// Try with GitHub CLI if available
try {
(0, child_process_1.execSync)('gh --version', { cwd, stdio: 'ignore' });
const args = ['pr', 'create', '-B', base, '-H', head, '-t', JSON.stringify(title)];
if (body)
args.push('-b', JSON.stringify(body));
(0, child_process_1.execSync)(`gh ${args.join(' ')}`, { cwd, stdio: 'inherit' });
// Best-effort; URL is printed by gh
return { created: true };
}
catch { }
// Fallback: provide compare URL
try {
const remote = (0, child_process_1.execSync)('git config --get remote.origin.url', { cwd, encoding: 'utf8' }).trim();
const remoteUrl = remote.replace(/^git@github.com:/, 'https://github.com/').replace(/\.git$/, '');
const url = `${remoteUrl}/compare/${base}...${head}?expand=1&title=${encodeURIComponent(title)}`;
return { created: false, url };
}
catch {
return { created: false };
}
}