run method
Implementation
Future<int> run() async {
final allFilesResult = await this.allFiles;
if (allFilesResult case (_, final int code)) {
return code;
}
final (allFiles, _) = allFilesResult;
logger.detail('Found ${allFiles.length} files');
for (final file in allFiles) {
logger.detail(' - $file');
}
if (debug) await _wait(durations.short);
logger.detail('Resolving files');
final pendingHook = PendingHook(
hook.resolve(allFiles),
logger: logger,
);
if (pendingHook.topLevelTasks.every((e) => e.files.isEmpty)) {
logger.info(
darkGray.wrap('Skipping $hookName hook, no files match any tasks'),
);
return 0;
}
logger
..info(darkGray.wrap('Running $hookName hook'))
..detail('Preparing files');
final context = await gitService.prepareFiles(backup: hook.backupFiles);
if (debug) await _wait(durations.short);
if (context.hidePartiallyStaged) {
logger.detail(
'Hiding partially staged files '
'(${context.partiallyStagedFiles.length})',
);
await gitService.checkoutFiles(context.partiallyStagedFiles);
}
final labelMaker = LabelMaker(
stdout: stdout,
pendingHook: pendingHook,
nameOfHook: hookName,
debug: debug,
);
logger.detail('Starting tasks');
if (debug) await _wait(durations.short);
final progress = MultiLineProgress(createLabel: labelMaker.create)..start();
pendingHook.start();
await pendingHook.wait();
if (pendingHook.wasKilled) {
progress
..dispose()
..print();
logger.detail('Hook was killed');
} else {
await progress.closeNextFrame();
logger
..detail('Tasks finished')
..flush()
..write('\n');
}
Future<void> finish() async {
logger.detail('deleting patch');
await gitService.deletePatch();
logger.detail('restoring merge statuses');
gitService.restoreMergeStatuses(
msg: context.mergeMsg,
mode: context.mergeMode,
head: context.mergeHead,
);
if (debug) await _wait(durations.short);
logger.detail('dropping stash');
await gitService.dropBackupStash();
}
Future<int> fail() async {
final stash = context.stashHash;
if (stash == null) {
return 1;
}
logger.detail('Forcing hard reset to HEAD');
await gitService.restoreStash();
if (debug) await _wait(durations.long);
logger.detail('making sure all deleted files stay deleted '
'(${context.deletedFiles.length})');
if (debug) await _wait(durations.short);
await gitService.ensureDeletedFiles(context.deletedFiles);
await finish();
return 1;
}
var failed = false;
for (final task in pendingHook.topLevelTasks) {
if (task.code case final int code when code != 0) {
failed = true;
logger.detail(
'Task failed: ${task.resolvedTask.original.resolvedName}',
);
}
if (failed) {
logger
..detail('Task failed, stopping')
..flush();
return await fail();
}
}
if (hook.diffArgs.isEmpty) {
logger.detail('Applying modifications');
if (debug) await _wait(durations.short);
await gitService.applyModifications(context.nonStagedFiles);
if (debug) await _wait(durations.long);
} else {
logger.detail('Skipping modifications due to diffArgs being set');
}
if (context.hidePartiallyStaged) {
logger.detail('Restoring unstaged changes');
if (!await gitService.applyPatch()) {
logger.err('Failed to restore unstaged changes due to merge conflicts');
if (debug) await _wait(durations.long);
await fail();
}
}
await finish();
if (hook.allowEmpty) {
logger.detail('--FINISHED--');
return 0;
}
final files = await gitService.diffFiles(
diffArgs: hook.diffArgs,
diffFilters: hook.diffFilters,
);
if (files != null && files.isEmpty) {
logger
..info('No changes to commit')
..detail('--FINISHED--');
return 1;
}
logger.detail('--FINISHED--');
return 0;
}