prepare static method
Resolves ref in projectDir's repository and stages its files under
stagingRoot. Fetches first (unless fetch is false), so a branch is
built as it is on the remote.
Implementation
static Future<RefSource> prepare({
required String projectDir,
required String ref,
required Directory stagingRoot,
bool fetch = true,
}) async {
final git = _Git(projectDir);
final top = await git.output(['rev-parse', '--show-toplevel']);
if (top == null) {
throw BuildException(
'--ref needs the project to be in a git repository.',
fix: 'Run the build without --ref, or from the repository.',
);
}
if (fetch) {
final fetched = await git
.run(['fetch', '--quiet'], timeout: const Duration(seconds: 90));
if (!fetched) {
Logger.warning('Could not fetch from the remote (offline?): building '
'"$ref" as this computer last saw it.');
}
}
final notes = <String>[];
final resolved = await _resolve(git, ref, notes);
final commit = await git
.output(['rev-parse', '--verify', '--quiet', '$resolved^{commit}']);
if (commit == null) {
throw BuildException(
'"$ref" is not a branch, tag or commit in this repository.',
fix: 'Check the name with "git branch -a" or "git tag".',
);
}
final tree = Directory(p.join(stagingRoot.path, poolName(ref), 'source'));
if (tree.existsSync()) tree.deleteSync(recursive: true);
tree.createSync(recursive: true);
// The project may be a folder inside the repository ("apps/bank/").
final prefix = await git.output(['rev-parse', '--show-prefix']) ?? '';
final treeish = prefix.isEmpty
? commit
: '$commit:${prefix.substring(0, prefix.length - 1)}';
// From the top: run in a subfolder, git archive only exports that
// subfolder of the tree it is given.
await _extract(top, treeish, tree);
if (File(p.join(tree.path, '.gitmodules')).existsSync()) {
notes.add('This repository has git submodules, which --ref builds '
"don't include. Build without --ref if the app needs them.");
}
final copied = await _addLocalFiles(git, projectDir, tree);
if (copied > 0) {
notes.add('Added $copied local-only file(s) from the working copy '
'(client .env/.secrets, keystores and other git-ignored files).');
}
return RefSource._(
ref: ref,
resolvedRef: resolved,
commit: commit,
tree: tree,
notes: notes,
);
}