const assert = require('node:assert/strict') const { execFileSync } = require('node:child_process') const fs = require('node:fs/promises') const os = require('node:os') const path = require('node:path') const { build } = require('esbuild') const failures = [] function runGit(cwd, ...args) { return execFileSync('git', ['-C', cwd, ...args], { windowsHide: true, encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'] }).trim() } async function check(name, verify) { try { await verify() console.log(`PASS ${name}`) } catch (error) { failures.push({ name, error }) console.error(`FAIL ${name}: ${error instanceof Error ? error.message : String(error)}`) } } async function main() { const repositoryRoot = path.resolve(__dirname, '..') const tempRoot = await fs.mkdtemp(path.join(os.tmpdir(), 'ycode-git-branch-')) const bundlePath = path.join(repositoryRoot, '.tmp', 'git-branch.cjs') try { await fs.mkdir(path.dirname(bundlePath), { recursive: true }) await build({ entryPoints: [path.join(repositoryRoot, 'src/main/git.ts')], bundle: true, platform: 'node', format: 'cjs', outfile: bundlePath, logLevel: 'silent' }) const { readGitBranch } = require(bundlePath) const repoPath = path.join(tempRoot, 'repo') const emptyRepoPath = path.join(tempRoot, 'empty-repo') const emptyPath = path.join(tempRoot, 'empty') const missingPath = path.join(tempRoot, 'missing') await Promise.all([ fs.mkdir(repoPath), fs.mkdir(emptyRepoPath), fs.mkdir(emptyPath) ]) runGit(repoPath, 'init', '-b', 'master') runGit(repoPath, 'config', 'user.name', 'YCode Test') runGit(repoPath, 'config', 'user.email', 'ycode-test@example.invalid') await fs.writeFile(path.join(repoPath, 'README.md'), 'git branch verification\n', 'utf8') runGit(repoPath, 'add', 'README.md') runGit(repoPath, 'commit', '-m', 'initial commit') await check('initialized master branch', async () => { const result = await readGitBranch(repoPath) assert.deepEqual(result, { repo: true, branch: 'master', detached: false, head: null }) }) runGit(repoPath, 'checkout', '-b', 'feature/x') await check('feature branch name', async () => { const result = await readGitBranch(repoPath) assert.equal(result.repo, true) assert.equal(result.branch, 'feature/x') assert.equal(result.detached, false) assert.equal(result.head, null) }) runGit(repoPath, 'checkout', '--detach') const expectedHead = runGit(repoPath, 'rev-parse', '--short', 'HEAD') await check('detached HEAD short SHA', async () => { const result = await readGitBranch(repoPath) assert.deepEqual(result, { repo: true, branch: null, detached: true, head: expectedHead }) }) await check('empty directory is outside Git', async () => { const result = await readGitBranch(emptyPath) assert.deepEqual(result, { repo: false, branch: null, detached: false, head: null }) }) await check('missing path is outside Git', async () => { const result = await readGitBranch(missingPath) assert.deepEqual(result, { repo: false, branch: null, detached: false, head: null }) }) runGit(emptyRepoPath, 'init', '-b', 'master') await check('initialized repository without commits', async () => { const result = await readGitBranch(emptyRepoPath) // An unborn HEAD still resolves through symbolic-ref to the initialized branch. assert.deepEqual(result, { repo: true, branch: 'master', detached: false, head: null }) }) } finally { await fs.rm(tempRoot, { recursive: true, force: true }) } if (failures.length) { console.error(`GIT_BRANCH_FAIL (${failures.length})`) for (const { name } of failures) console.error(`- ${name}`) process.exitCode = 1 } else { console.log('GIT_BRANCH_PASS') } } main().catch((error) => { console.error(`GIT_BRANCH_FAIL: ${error instanceof Error ? error.stack ?? error.message : String(error)}`) process.exitCode = 1 })