diff --git a/src/extension/extension-host.ts b/src/extension/extension-host.ts index 63d4723f716..706bf3ae78a 100644 --- a/src/extension/extension-host.ts +++ b/src/extension/extension-host.ts @@ -165,6 +165,25 @@ const githubBranchUrlProvider = { }, }; +const githubCommitUrlProvider = { + extensionUrl: (host: ExtensionHost) => { + if (host.modifier && isCommitSha(host.modifier)) { + return `https://github.com/${host.organization}/${host.repo}/archive/${host.modifier}${archiveExt}`; + } + }, + archiveSubdir: (host: ExtensionHost) => { + const baseDir = `${host.repo}-${host.modifier}`; + if (host.subdirectory) { + return baseDir + "/" + host.subdirectory; + } else { + return baseDir; + } + }, + learnMoreUrl: (host: ExtensionHost) => { + return `https://github.com/${host.organization}/${host.repo}/tree/${host.modifier}#readme`; + }, +}; + // The github extension source const kGithubExtensionSource: ExtensionHostSource = { parse: (name: string) => { @@ -184,6 +203,7 @@ const kGithubExtensionSource: ExtensionHostSource = { urlProviders: [ githubLatestUrlProvider, githubTagUrlProvider, + githubCommitUrlProvider, githubBranchUrlProvider, ], }; @@ -218,7 +238,7 @@ const kGithubArchiveUrlSource: ExtensionHostSource = { }; const kGithubArchiveUrlRegex = - /https?\:\/\/github.com\/([a-zA-Z0-9-_\.]+?)\/([a-zA-Z0-9-_\.]+?)\/archive\/refs\/(?:tags|heads)\/(.+)(?:\.tar\.gz|\.zip)$/; + /https?\:\/\/github.com\/([a-zA-Z0-9-_\.]+?)\/([a-zA-Z0-9-_\.]+?)\/archive\/(?:refs\/(?:tags|heads)\/)?(.+)(?:\.tar\.gz|\.zip)$/; function tagSubDirectory(tag?: string) { // Strip the leading 'v' from tag names @@ -229,6 +249,11 @@ function tagSubDirectory(tag?: string) { } } +function isCommitSha(modifier?: string): boolean { + if (!modifier) return false; + return /^[a-f0-9]{7,40}$/i.test(modifier); +} + function makeResolvers( source: ExtensionHostSource, ): ExtensionNameResolver[] { diff --git a/tests/smoke/extensions/install.test.ts b/tests/smoke/extensions/install.test.ts index d770a0bfdad..7527d74a34c 100644 --- a/tests/smoke/extensions/install.test.ts +++ b/tests/smoke/extensions/install.test.ts @@ -66,9 +66,12 @@ const extUrls = [ "quarto-ext/lightbox@cool", "quarto-ext/lightbox@v0.1.4", "quarto-ext/lightbox@test/use-in-quarto-cli", + "quarto-ext/lightbox@a738ff253fd46dd0cdd6aa992178cb7561b70251", + "quarto-ext/lightbox@a738ff2", "https://github.com/quarto-ext/lightbox/archive/refs/tags/v0.1.4.tar.gz", "https://github.com/quarto-ext/lightbox/archive/refs/heads/main.tar.gz", "https://github.com/quarto-ext/lightbox/archive/refs/heads/cool.tar.gz", + "https://github.com/quarto-ext/lightbox/archive/a738ff253fd46dd0cdd6aa992178cb7561b70251.tar.gz", ]; if (!isLinux) { @@ -77,6 +80,7 @@ if (!isLinux) { "https://github.com/quarto-ext/lightbox/archive/refs/tags/v0.1.4.zip", "https://github.com/quarto-ext/lightbox/archive/refs/heads/main.zip", "https://github.com/quarto-ext/lightbox/archive/refs/heads/cool.zip", + "https://github.com/quarto-ext/lightbox/archive/a738ff253fd46dd0cdd6aa992178cb7561b70251.zip", ], ); }