Skip to content
Snippets Groups Projects
GitRepository.ts 2.90 KiB
import axios from "axios";

export const requiredRepositoryFiles = [
  "main.nf",
  "CHANGELOG.md",
  "README.md",
  "nextflow_schema.json",
];

export function determineGitIcon(repo_url?: string): string {
  let gitProvider = "git-alt";
  if (repo_url != null) {
    if (repo_url.includes("github")) {
      gitProvider = "github";
    } else if (repo_url.includes("gitlab")) {
      gitProvider = "gitlab";
    } else if (repo_url.includes("bitbucket")) {
      gitProvider = "bitbucket";
    }
  }
  return "fa-brands fa-".concat(gitProvider);
}

export abstract class GitRepository {
  protected repo: URL;
  protected gitCommitHash: string;
  protected constructor(repoUrl: string, gitCommitHash: string) {
    this.repo = new URL(repoUrl);
    this.gitCommitHash = gitCommitHash;
  }
  async checkFileExist(filepath: string): Promise<boolean> {
    try {
      await axios.head(this.fileUrl(filepath));
    } catch (e) {
      return false;
    }
    return true;
  }

  async checkFilesExist(
    files: string[],
    raiseError = false
  ): Promise<boolean[]> {
    const checks = Promise.all(
      files.map((filepath) => this.checkFileExist(filepath))
    );
    const results = await checks;
    if (raiseError) {
      const missingFiles = files.filter((file, index) => !results[index]);
      if (missingFiles.length > 0) {
        throw new Error(missingFiles.reduce((a, b) => a + "," + b));
      }
    }
    return results;
  }
  protected abstract fileUrl(filepath: string): string;

  static buildRepository(
    repoUrl: string,
    gitCommitHash: string
  ): GitRepository {
    if (repoUrl.includes("github")) {
      return new GithubRepository(repoUrl, gitCommitHash);
    } else if (repoUrl.includes("gitlab")) {
      return new GitlabRepository(repoUrl, gitCommitHash);
    }
    throw new Error(`Repository is not supported.`);
  }
}
class GithubRepository extends GitRepository {
  private readonly account: string;
  private readonly repoName: string;
  constructor(repoUrl: string, gitCommitHash: string) {
    super(repoUrl, gitCommitHash);
    const pathParts = this.repo.pathname.slice(1).split("/");
    this.account = pathParts[0];
    this.repoName = pathParts[1];
  }

  fileUrl(filepath: string): string {
    return `https://raw.githubusercontent.com/${this.account}/${this.repoName}/${this.gitCommitHash}/${filepath}`;
  }
}

class GitlabRepository extends GitRepository {
  private readonly account: string[];
  private readonly repoName: string;
  constructor(repoUrl: string, gitCommitHash: string) {
    super(repoUrl, gitCommitHash);
    const pathParts = this.repo.pathname.slice(1).split("/");
    this.account = pathParts.slice(0, pathParts.length - 2);
    this.repoName = pathParts[pathParts.length - 1];
  }

  fileUrl(filepath: string): string {
    return `https://${this.repo.host}/${this.account.reduce((a, b) =>
      a.concat(`/${b}`)
    )}/${this.repoName}/-/raw/${this.gitCommitHash}/${filepath}`;
  }
}