Skip to content

Commit

Permalink
Merge branch 'main' into v2
Browse files Browse the repository at this point in the history
  • Loading branch information
mislav committed Jun 23, 2022
2 parents 9750a11 + 5983bb6 commit 33989a8
Show file tree
Hide file tree
Showing 2 changed files with 143 additions and 12 deletions.
83 changes: 83 additions & 0 deletions src/calculate-download-checksum-test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import test from 'ava'
import { URL } from 'url'
import {
parseArchiveUrl,
parseReleaseDownloadUrl,
} from './calculate-download-checksum'

test('calculate-download-checksum parseArchiveUrl', (t) => {
const tests = [
{
url: 'https://github.com/mislav/will_paginate/archive/v3.3.1.zip',
wants: {
owner: 'mislav',
repo: 'will_paginate',
ref: 'v3.3.1',
ext: '.zip',
},
},
{
url: 'https://github.com/cli/cli/archive/refs/tags/v2.13.0.tar.gz',
wants: {
owner: 'cli',
repo: 'cli',
ref: 'refs/tags/v2.13.0',
ext: '.tar.gz',
},
},
{
url: 'https://github.com/john-u/smartthings-cli/archive/refs/tags/@smartthings/cli@1.0.0-beta.9.tar.gz',
wants: {
owner: 'john-u',
repo: 'smartthings-cli',
ref: 'refs/tags/@smartthings/cli@1.0.0-beta.9',
ext: '.tar.gz',
},
},
]
tests.forEach((tt) => {
const archive = parseArchiveUrl(new URL(tt.url))
if (archive == null) {
t.fail(`did not match: ${tt.url}`)
return
}
t.is(tt.wants.owner, archive.owner)
t.is(tt.wants.repo, archive.repo)
t.is(tt.wants.ref, archive.ref)
t.is(tt.wants.ext, archive.ext)
})
})

test('calculate-download-checksum parseReleaseDownloadUrl', (t) => {
const tests = [
{
url: 'https://github.com/john-u/smartthings-cli/releases/download/%40smartthings%2Fcli%401.0.0-beta.9/smartthings-macos.tar.gz',
wants: {
owner: 'john-u',
repo: 'smartthings-cli',
tagname: '@smartthings/cli@1.0.0-beta.9',
name: 'smartthings-macos.tar.gz',
},
},
{
url: 'https://github.com/john-u/smartthings-cli/releases/download/@smartthings/cli@1.0.0-beta.9/smartthings-macos.tar.gz',
wants: {
owner: 'john-u',
repo: 'smartthings-cli',
tagname: '@smartthings/cli@1.0.0-beta.9',
name: 'smartthings-macos.tar.gz',
},
},
]
tests.forEach((tt) => {
const asset = parseReleaseDownloadUrl(new URL(tt.url))
if (asset == null) {
t.fail(`did not match: ${tt.url}`)
return
}
t.is(tt.wants.owner, asset.owner)
t.is(tt.wants.repo, asset.repo)
t.is(tt.wants.tagname, asset.tagname)
t.is(tt.wants.name, asset.name)
})
})
72 changes: 60 additions & 12 deletions src/calculate-download-checksum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,10 @@ function stream(
async function resolveDownload(apiClient: API, url: URL): Promise<URL> {
if (url.hostname == 'github.com') {
const api = apiClient.rest
const archive = url.pathname.match(
/^\/([^/]+)\/([^/]+)\/archive\/([^/]+)(\.tar\.gz|\.zip)$/
)
const archive = parseArchiveUrl(url)
if (archive != null) {
const [, owner, repo, ref, ext] = archive
const res = await (ext == '.zip'
const { owner, repo, ref } = archive
const res = await (archive.ext == '.zip'
? api.repos.downloadZipballArchive
: api.repos.downloadTarballArchive)({
owner,
Expand All @@ -57,15 +55,16 @@ async function resolveDownload(apiClient: API, url: URL): Promise<URL> {
return new URL(loc.replace('/legacy.', '/'))
}

const release = url.pathname.match(
/^\/([^/]+)\/([^/]+)\/releases\/download\/([^/]+)\/(.+)$/
)
if (release != null) {
const [, owner, repo, tag, path] = release
const download = parseReleaseDownloadUrl(url)
if (download != null) {
const { owner, repo } = download
const tag = download.tagname
const res = await api.repos.getReleaseByTag({ owner, repo, tag })
const asset = res.data.assets.find((a) => a.name == path)
const asset = res.data.assets.find((a) => a.name == download.name)
if (asset == null) {
throw new Error(`could not find asset '${path}' in '${tag}' release`)
throw new Error(
`could not find asset '${download.name}' in '${tag}' release`
)
}
const assetRes = await apiClient.request(asset.url, {
headers: { accept: 'application/octet-stream' },
Expand All @@ -78,6 +77,55 @@ async function resolveDownload(apiClient: API, url: URL): Promise<URL> {
return url
}

type archive = {
owner: string
repo: string
ref: string
ext: string
}

export function parseArchiveUrl(url: URL): archive | null {
const match = url.pathname.match(
/^\/([^/]+)\/([^/]+)\/archive\/(.+)(\.tar\.gz|\.zip)$/
)
if (match == null) {
return null
}
return {
owner: match[1],
repo: match[2],
ref: match[3],
ext: match[4],
}
}

type asset = {
owner: string
repo: string
tagname: string
name: string
}

export function parseReleaseDownloadUrl(url: URL): asset | null {
const match = url.pathname.match(
/^\/([^/]+)\/([^/]+)\/releases\/download\/(.+)$/
)
if (match == null) {
return null
}
const parts = match[3].split('/')
if (parts.length < 2) {
return null
}
const name = parts.pop() || ''
return {
owner: match[1],
repo: match[2],
tagname: decodeURIComponent(parts.join('/')),
name: name,
}
}

function log(url: URL): void {
const params = Array.from(url.searchParams.keys())
const q = params.length > 0 ? `?${params.join(',')}` : ''
Expand Down

0 comments on commit 33989a8

Please sign in to comment.