forked from heavy-duty/stoke
feat: resolve repository default branch
This commit is contained in:
parent
64b3d9df94
commit
ea6c1a4fe9
3 changed files with 48 additions and 9 deletions
|
|
@ -467,8 +467,6 @@ repo
|
||||||
if (!config || !config.url || !config.token) {
|
if (!config || !config.url || !config.token) {
|
||||||
throw new Error('Not authenticated. Run: stoke auth login');
|
throw new Error('Not authenticated. Run: stoke auth login');
|
||||||
}
|
}
|
||||||
if (!options.branch) throw new Error('--branch is required');
|
|
||||||
|
|
||||||
const base = config.url.replace(/\/+$/, '');
|
const base = config.url.replace(/\/+$/, '');
|
||||||
const forgeUrl = `${base}/${encodeURIComponent(options.owner)}/${encodeURIComponent(options.repo)}.git`;
|
const forgeUrl = `${base}/${encodeURIComponent(options.owner)}/${encodeURIComponent(options.repo)}.git`;
|
||||||
const result = syncRepository({
|
const result = syncRepository({
|
||||||
|
|
@ -477,7 +475,11 @@ repo
|
||||||
branch: options.branch,
|
branch: options.branch,
|
||||||
env: gitAuthEnv({ ...config, url: base }),
|
env: gitAuthEnv({ ...config, url: base }),
|
||||||
});
|
});
|
||||||
|
if (result.changed) {
|
||||||
console.log(`${result.branch} ${result.oldSha}..${result.newSha}`);
|
console.log(`${result.branch} ${result.oldSha}..${result.newSha}`);
|
||||||
|
} else {
|
||||||
|
console.log(`${result.branch} is up to date at ${result.newSha}`);
|
||||||
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(`Repository sync failed: ${err.message}`);
|
console.error(`Repository sync failed: ${err.message}`);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,15 @@ function syncRepository({ forgeUrl, upstreamUrl, branch, env }) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
runGit(['init', '--bare', directory], { cwd: directory, env });
|
runGit(['init', '--bare', directory], { cwd: directory, env });
|
||||||
|
if (!branch) {
|
||||||
|
const symbolicHead = runGit(['ls-remote', '--symref', forgeUrl, 'HEAD'], {
|
||||||
|
cwd: directory,
|
||||||
|
env,
|
||||||
|
}).stdout;
|
||||||
|
const match = symbolicHead.match(/^ref:\s+refs\/heads\/(.+)\s+HEAD$/m);
|
||||||
|
if (!match) throw new Error('Could not resolve the forge repository default branch');
|
||||||
|
branch = match[1];
|
||||||
|
}
|
||||||
runGit(['fetch', '--no-tags', forgeUrl, `refs/heads/${branch}:${forgeRef}`], {
|
runGit(['fetch', '--no-tags', forgeUrl, `refs/heads/${branch}:${forgeRef}`], {
|
||||||
cwd: directory,
|
cwd: directory,
|
||||||
env,
|
env,
|
||||||
|
|
@ -45,7 +54,7 @@ function syncRepository({ forgeUrl, upstreamUrl, branch, env }) {
|
||||||
env,
|
env,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return { branch, oldSha, newSha };
|
return { branch, oldSha, newSha, changed: oldSha !== newSha };
|
||||||
} finally {
|
} finally {
|
||||||
fs.rmSync(directory, { recursive: true, force: true });
|
fs.rmSync(directory, { recursive: true, force: true });
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -55,17 +55,18 @@ function fixture() {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function runSync(fx, extra = []) {
|
function runSync(fx, extra = [], { branch = 'main' } = {}) {
|
||||||
return spawnSync(process.execPath, [
|
const args = [
|
||||||
CLI,
|
CLI,
|
||||||
'repo',
|
'repo',
|
||||||
'sync',
|
'sync',
|
||||||
'-o', 'o',
|
'-o', 'o',
|
||||||
'-r', 'r',
|
'-r', 'r',
|
||||||
'--from', `file://${fx.upstreamRepo}`,
|
'--from', `file://${fx.upstreamRepo}`,
|
||||||
'--branch', 'main',
|
];
|
||||||
...extra,
|
if (branch) args.push('--branch', branch);
|
||||||
], {
|
args.push(...extra);
|
||||||
|
return spawnSync(process.execPath, args, {
|
||||||
encoding: 'utf8',
|
encoding: 'utf8',
|
||||||
env: { ...process.env, STOKE_CONFIG_FILE: fx.config },
|
env: { ...process.env, STOKE_CONFIG_FILE: fx.config },
|
||||||
});
|
});
|
||||||
|
|
@ -83,3 +84,30 @@ test('repo sync fast-forwards an undiverged forge branch', () => {
|
||||||
fx.cleanup();
|
fx.cleanup();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('repo sync resolves an omitted branch from the forge symbolic HEAD', () => {
|
||||||
|
const fx = fixture();
|
||||||
|
try {
|
||||||
|
const result = runSync(fx, [], { branch: null });
|
||||||
|
|
||||||
|
assert.equal(result.status, 0, result.stderr);
|
||||||
|
assert.equal(git(['rev-parse', 'refs/heads/main'], fx.forgeRepo), fx.newSha);
|
||||||
|
assert.match(result.stdout, new RegExp(`main ${fx.oldSha}\\.\\.${fx.newSha}`));
|
||||||
|
} finally {
|
||||||
|
fx.cleanup();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test('repo sync reports an already-current branch as a no-op', () => {
|
||||||
|
const fx = fixture();
|
||||||
|
try {
|
||||||
|
assert.equal(runSync(fx).status, 0);
|
||||||
|
const result = runSync(fx);
|
||||||
|
|
||||||
|
assert.equal(result.status, 0, result.stderr);
|
||||||
|
assert.equal(git(['rev-parse', 'refs/heads/main'], fx.forgeRepo), fx.newSha);
|
||||||
|
assert.match(result.stdout, new RegExp(`main is up to date at ${fx.newSha}`));
|
||||||
|
} finally {
|
||||||
|
fx.cleanup();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue