readGitMetadata function

Future<GitMetadata?> readGitMetadata(
  1. String projectDirectory, {
  2. GitCommandRunner runGitCommand = _runGitCommand,
  3. CommandLogger? logger,
})

Reads GitMetadata for the git repository containing projectDirectory.

Returns null when projectDirectory is not inside a git repository, or when the git executable is not available. Individual fields are null when the corresponding information cannot be determined (for example, in a repository without any commits).

When a logger is provided, the reason for skipping git metadata is recorded as a debug message.

Implementation

Future<GitMetadata?> readGitMetadata(
  final String projectDirectory, {
  final GitCommandRunner runGitCommand = _runGitCommand,
  final CommandLogger? logger,
}) async {
  final ProcessResult isInsideWorkTreeResult;
  try {
    isInsideWorkTreeResult = await runGitCommand(const [
      'rev-parse',
      '--is-inside-work-tree',
    ], projectDirectory);
  } on ProcessException {
    logger?.debug(
      'Skipping git commit metadata: the `git` executable was not found.',
    );
    return null;
  }

  if (isInsideWorkTreeResult.exitCode != 0 ||
      _stdoutString(isInsideWorkTreeResult)?.trim() != 'true') {
    logger?.debug(
      'Skipping git commit metadata: the project directory is not inside a '
      'git repository.',
    );
    return null;
  }

  final commitHash = await _gitOutput(runGitCommand, const [
    'rev-parse',
    '--short',
    'HEAD',
  ], projectDirectory);
  final commitMessage = await _gitOutput(runGitCommand, const [
    'log',
    '-1',
    '--pretty=%s',
  ], projectDirectory);
  final branch = await _gitOutput(runGitCommand, const [
    'branch',
    '--show-current',
  ], projectDirectory);
  final status = await _gitOutput(runGitCommand, const [
    'status',
    '--porcelain',
  ], projectDirectory);

  return GitMetadata(
    commitHash: _nullIfEmpty(commitHash),
    commitMessage: _nullIfEmpty(commitMessage),
    branch: _nullIfEmpty(branch),
    hasUncommittedChanges: status != null && status.isNotEmpty,
  );
}