Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add GitLab source linking #1761

Merged
merged 3 commits into from
Oct 25, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
### Features

- Added support for GitHub enterprise projects with a `githubprivate.com` domain, #1743.
- Added support for GitLab repositories, #1728.

### Bug Fixes

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,17 +49,17 @@ export class Repository {
project?: string;

/**
* The hostname for this GitHub or Bitbucket project.
* The hostname for this GitHub/Bitbucket/.etc project.
*
* Defaults to: `github.com` (for normal, public GitHub instance projects)
*
* Or the hostname for an enterprise version of GitHub, e.g. `github.acme.com`
* Can be the hostname for an enterprise version of GitHub, e.g. `github.acme.com`
* (if found as a match in the list of git remotes).
*/
hostname = "github.com";

/**
* Whether this is a GitHub or Bitbucket repository.
* Whether this is a GitHub, Bitbucket, or other type of repository.
*/
type: RepositoryType = RepositoryType.GitHub;

Expand Down Expand Up @@ -89,6 +89,10 @@ export class Repository {
match = /(bitbucket.org)[:/]([^/]+)\/(.*)/.exec(repoLinks[i]);
}

if (!match) {
match = /(gitlab.com)[:/]([^/]+)\/(.*)/.exec(repoLinks[i]);
}

if (match) {
this.hostname = match[1];
this.user = match[2];
Expand All @@ -103,9 +107,13 @@ export class Repository {
}
}

if (this.hostname.includes("bitbucket.org"))
if (this.hostname.includes("bitbucket.org")) {
this.type = RepositoryType.Bitbucket;
else this.type = RepositoryType.GitHub;
} else if (this.hostname.includes("gitlab.com")) {
this.type = RepositoryType.GitLab;
} else {
this.type = RepositoryType.GitHub;
}

let out = git("-C", path, "ls-files");
if (out.status === 0) {
Expand Down Expand Up @@ -149,10 +157,13 @@ export class Repository {
`https://${this.hostname}`,
this.user,
this.project,
this.type === "github" ? "blob" : "src",
this.type === RepositoryType.GitLab ? "-" : undefined,
this.type === RepositoryType.Bitbucket ? "src" : "blob",
this.branch,
fileName.substr(this.path.length + 1),
].join("/");
]
.filter((s) => !!s)
.join("/");
}

/**
Expand Down Expand Up @@ -190,6 +201,7 @@ export class Repository {
switch (repositoryType) {
default:
case RepositoryType.GitHub:
case RepositoryType.GitLab:
return "L" + lineNumber;
case RepositoryType.Bitbucket:
return "lines-" + lineNumber;
Expand All @@ -201,8 +213,8 @@ export class Repository {
* A handler that watches for repositories with GitHub origin and links
* their source files to the related GitHub pages.
*/
@Component({ name: "git-hub" })
export class GitHubPlugin extends ConverterComponent {
@Component({ name: "source-link" })
export class SourceLinkPlugin extends ConverterComponent {
/**
* List of known repositories.
*/
Expand Down
2 changes: 1 addition & 1 deletion src/lib/converter/plugins/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
export { CategoryPlugin } from "./CategoryPlugin";
export { CommentPlugin } from "./CommentPlugin";
export { DecoratorPlugin } from "./DecoratorPlugin";
export { GitHubPlugin } from "./GitHubPlugin";
export { SourceLinkPlugin } from "./SourceLinkPlugin";
export { GroupPlugin } from "./GroupPlugin";
export { ImplementsPlugin } from "./ImplementsPlugin";
export { PackagePlugin } from "./PackagePlugin";
Expand Down
1 change: 1 addition & 0 deletions src/lib/models/sources/repository.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export enum RepositoryType {
GitHub = "github",
Bitbucket = "bitbucket",
GitLab = "gitlab",
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import * as github from "../lib/converter/plugins/GitHubPlugin";
import { Repository } from "../lib/converter/plugins/SourceLinkPlugin";
import { RepositoryType } from "../lib/models";
import { strictEqual as equal } from "assert";

describe("Repository", function () {
describe("constructor", function () {
it("defaults to github.com hostname", function () {
const repository = new github.Repository("", "", []);
const repository = new Repository("", "", []);

equal(repository.hostname, "github.com");
equal(repository.type, RepositoryType.GitHub);
Expand All @@ -14,7 +14,7 @@ describe("Repository", function () {
it("handles a personal GitHub HTTPS URL", function () {
const mockRemotes = ["https://github.com/joebloggs/foobar.git"];

const repository = new github.Repository("", "", mockRemotes);
const repository = new Repository("", "", mockRemotes);

equal(repository.hostname, "github.com");
equal(repository.user, "joebloggs");
Expand All @@ -25,7 +25,7 @@ describe("Repository", function () {
it("handles an enterprise GitHub URL", function () {
const mockRemotes = ["git@github.acme.com:joebloggs/foobar.git"];

const repository = new github.Repository("", "", mockRemotes);
const repository = new Repository("", "", mockRemotes);

equal(repository.hostname, "github.acme.com");
equal(repository.user, "joebloggs");
Expand All @@ -38,7 +38,7 @@ describe("Repository", function () {
"ssh://org@bigcompany.githubprivate.com/joebloggs/foobar.git",
];

const repository = new github.Repository("", "", mockRemotes);
const repository = new Repository("", "", mockRemotes);

equal(repository.hostname, "bigcompany.githubprivate.com");
equal(repository.user, "joebloggs");
Expand All @@ -51,7 +51,7 @@ describe("Repository", function () {
"https://joebloggs@bitbucket.org/joebloggs/foobar.git",
];

const repository = new github.Repository("", "", mockRemotes);
const repository = new Repository("", "", mockRemotes);

equal(repository.hostname, "bitbucket.org");
equal(repository.user, "joebloggs");
Expand All @@ -62,13 +62,35 @@ describe("Repository", function () {
it("handles a Bitbucket SSH URL", function () {
const mockRemotes = ["git@bitbucket.org:joebloggs/foobar.git"];

const repository = new github.Repository("", "", mockRemotes);
const repository = new Repository("", "", mockRemotes);

equal(repository.hostname, "bitbucket.org");
equal(repository.user, "joebloggs");
equal(repository.project, "foobar");
equal(repository.type, RepositoryType.Bitbucket);
});

it("handles a GitLab HTTPS URL", function () {
const mockRemotes = ["https://gitlab.com/joebloggs/foobar.git"];

const repository = new Repository("", "", mockRemotes);

equal(repository.hostname, "gitlab.com");
equal(repository.user, "joebloggs");
equal(repository.project, "foobar");
equal(repository.type, RepositoryType.GitLab);
});

it("handles a GitLab SSH URL", function () {
const mockRemotes = ["git@gitlab.com:joebloggs/foobar.git"];

const repository = new Repository("", "", mockRemotes);

equal(repository.hostname, "gitlab.com");
equal(repository.user, "joebloggs");
equal(repository.project, "foobar");
equal(repository.type, RepositoryType.GitLab);
});
});

describe("getURL", () => {
Expand All @@ -78,7 +100,7 @@ describe("Repository", function () {
it("returns a GitHub URL", function () {
const mockRemotes = ["https://github.com/joebloggs/foobar.git"];

const repository = new github.Repository(
const repository = new Repository(
repositoryPath,
"main",
mockRemotes
Expand All @@ -96,7 +118,7 @@ describe("Repository", function () {
"https://joebloggs@bitbucket.org/joebloggs/foobar.git",
];

const repository = new github.Repository(
const repository = new Repository(
repositoryPath,
"main",
mockRemotes
Expand All @@ -108,5 +130,21 @@ describe("Repository", function () {
"https://bitbucket.org/joebloggs/foobar/src/main/src/index.ts"
);
});

it("returns a GitLab URL", function () {
const mockRemotes = ["https://gitlab.com/joebloggs/foobar.git"];

const repository = new Repository(
repositoryPath,
"main",
mockRemotes
);
repository.files = [filePath];

equal(
repository.getURL(filePath),
"https://gitlab.com/joebloggs/foobar/-/blob/main/src/index.ts"
);
});
});
});