Skip to content

refactor: expose GitService and GitLab service in WrappedRepository

Tomas Vik (OOO back on 2024-09-23) requested to merge 341-easy-gitlab-service into main

This is a preparation for introducing MR repository(cache). This MR is building on top of #345 (closed) to provide an easy access to GitService and GitLabNewService.

This MR is separated into meaningful commits and I recommend reviewing it commit-by-commit.

The main pieces of this refactoring

Move instanceUrl to the WrappedRepository

This change accounts for most of the changed lines. We used to have a get_instance_url.ts helper that completely moved into the WrappedRepository (including tests).

The main benefit is reducing git code. We used to have code that run git remote -v and parsed the output to get all git remotes. Since we use the native VS Code Git extension, we can access this information synchronously with repository.state.remotes. That is a big win because synchronous code allows us to use get functions and creating more readable code.

Git remote code
async function fetch(cmd: string, repositoryRoot: string): Promise<string | null> {
  const [, ...args] = cmd.trim().split(' ');
  const { stdout } = await execa(gitExtensionWrapper.gitBinaryPath, args, {
    cwd: repositoryRoot,
    preferLocal: false,
  });
  return stdout;
}

async function fetchGitRemoteUrls(repositoryRoot: string): Promise<string[]> {
  const fetchGitRemotesVerbose = async (): Promise<string[]> => {
    const output = await fetch('git remote -v', repositoryRoot);

    return (output || '').split('\n');
  };

  const parseRemoteFromVerboseLine = (line: string) => {
    // git remote -v output looks like
    // origin[TAB]git@gitlab.com:gitlab-org/gitlab-vscode-extension.git[WHITESPACE](fetch)
    // the interesting part is surrounded by a tab symbol and a whitespace

    return line.split(/\t| /)[1];
  };

  const remotes = await fetchGitRemotesVerbose();
  const remoteUrls = remotes.map(remote => parseRemoteFromVerboseLine(remote)).filter(Boolean);

  // git remote -v returns a (fetch) and a (push) line for each remote,
  // so we need to remove duplicates
  return [...new Set(remoteUrls)];
}

Exposing gitService and gitLabService on WrappedRepository

The following snippet shows the simplified syntax that this MR introduces:

-  const gitService = createGitService(repository.rootFsPath);
-  const gitLabService = await createGitLabNewService(repository.rootFsPath);
-  const remote = await gitService.fetchGitRemote();
-  const snippets = await gitLabService.getSnippets(`${remote.namespace}/${remote.project}`);
+  const remote = await repository.gitService.fetchGitRemote();
+  const snippets = await repository.gitLabService.getSnippets(
+    `${remote.namespace}/${remote.project}`,
+  );

Related to #341 (closed)

Merge request reports