diff --git a/CHANGELOG.md b/CHANGELOG.md index 319a6e2f7..3bc636028 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Unreleased +### Features + +- Added `gitRevision:short` placeholder option to `--sourceLinkTemplate` option, #2529. + Links generated by TypeDoc will now default to using the non-short git revision. + +### Thanks! + +- @xuhdev + ## v0.25.12 (2024-03-10) ### Features diff --git a/src/lib/converter/utils/repository.ts b/src/lib/converter/utils/repository.ts index 23fbbecc3..07cba5e9e 100644 --- a/src/lib/converter/utils/repository.ts +++ b/src/lib/converter/utils/repository.ts @@ -32,12 +32,13 @@ export class AssumedRepository implements Repository { getURL(fileName: string, line: number): string | undefined { const replacements = { gitRevision: this.gitRevision, + "gitRevision:short": this.gitRevision.substring(0, 8), path: fileName.substring(this.path.length + 1), line, }; return this.sourceLinkTemplate.replace( - /\{(gitRevision|path|line)\}/g, + /\{(gitRevision|gitRevision:short|path|line)\}/g, (_, key) => replacements[key as never], ); } @@ -93,12 +94,13 @@ export class GitRepository implements Repository { const replacements = { gitRevision: this.gitRevision, + "gitRevision:short": this.gitRevision.substring(0, 8), path: fileName.substring(this.path.length + 1), line, }; return this.urlTemplate.replace( - /\{(gitRevision|path|line)\}/g, + /\{(gitRevision|gitRevision:short|path|line)\}/g, (_, key) => replacements[key as never], ); } @@ -122,13 +124,7 @@ export class GitRepository implements Repository { const topLevel = git("-C", path, "rev-parse", "--show-toplevel"); if (topLevel.status !== 0) return; - gitRevision ||= git( - "-C", - path, - "rev-parse", - "--short", - "HEAD", - ).stdout.trim(); + gitRevision ||= git("-C", path, "rev-parse", "HEAD").stdout.trim(); if (!gitRevision) return; // Will only happen in a repo with no commits. let urlTemplate: string | undefined; diff --git a/src/test/Repository.test.ts b/src/test/Repository.test.ts index c68821fd0..9294729de 100644 --- a/src/test/Repository.test.ts +++ b/src/test/Repository.test.ts @@ -1,5 +1,12 @@ -import { guessSourceUrlTemplate } from "../lib/converter/utils/repository"; -import { strictEqual as equal } from "assert"; +import { + GitRepository, + guessSourceUrlTemplate, +} from "../lib/converter/utils/repository"; +import { strictEqual as equal, ok } from "assert"; +import { tempdirProject } from "@typestrong/fs-fixture-builder"; +import { spawnSync } from "child_process"; +import { TestLogger } from "./TestLogger"; +import { join } from "path"; describe("Repository", function () { describe("guessSourceUrlTemplate helper", () => { @@ -99,4 +106,56 @@ describe("Repository", function () { equal(guessSourceUrlTemplate(mockRemotes), undefined); }); }); + + describe("getURL", () => { + const project = tempdirProject(); + function git(...args: string[]) { + const env = { + GIT_AUTHOR_NAME: "test", + GIT_AUTHOR_EMAIL: "test@example.com", + GIT_AUTHOR_DATE: "2024-03-31T22:04:50.119Z", + GIT_COMMITTER_NAME: "test", + GIT_COMMITTER_EMAIL: "test@example.com", + GIT_COMMITTER_DATE: "2024-03-31T22:04:50.119Z", + }; + return spawnSync("git", ["-C", project.cwd, ...args], { + encoding: "utf-8", + windowsHide: true, + env, + }); + } + + afterEach(() => { + project.rm(); + }); + + it("Handles replacements", function () { + project.addFile("test.js", "console.log('hi!')"); + project.write(); + + git("init", "-b", "test"); + git("add", "."); + git("commit", "-m", "Test commit"); + git( + "remote", + "add", + "origin", + "git@github.com:TypeStrong/typedoc.git", + ); + + const repo = GitRepository.tryCreateRepository( + project.cwd, + "{gitRevision}/{gitRevision:short}/{path}/{line}", + "", // revision, empty to get from repo + "origin", // remote + new TestLogger(), + ); + + ok(repo); + equal( + repo.getURL(join(project.cwd, "test.js"), 1), + "b53cc55bcdd9bc5920787a1d4a4a15fa24123b04/b53cc55b/test.js/1", + ); + }); + }); });