Skip to content

Commit

Permalink
feat(git): add support for :: in #committish (#91)
Browse files Browse the repository at this point in the history
This iterates on the spec outlined by @coreyfarrel in
#46.

For each :: separated item:
  * If the item has no : then it is a commit-ish
  * If the item has : then split into name and value.
    * If the name is semver then do semver lookup of ref or tag
    * If the name is path then use the value as the subdir to install from.
    * If the name is unknown then warn that the name-value pair is being ignored.

This loop errors if duplicate values are found.
Unknown values log a warning instead of erroring.

Co-authored-by: sspiff <sspiff@users.noreply.github.com>
  • Loading branch information
wraithgar and sspiff authored Jun 22, 2022
1 parent cb07a48 commit 246f1e9
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 4 deletions.
44 changes: 40 additions & 4 deletions lib/npa.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const semver = require('semver')
const path = global.FAKE_WINDOWS ? require('path').win32 : require('path')
const validatePackageName = require('validate-npm-package-name')
const { homedir } = require('os')
const log = require('proc-log')

const isWindows = process.platform === 'win32' || global.FAKE_WINDOWS
const hasSlashes = isWindows ? /\\|[/]/ : /[/]/
Expand Down Expand Up @@ -120,6 +121,7 @@ function Result (opts) {
}
this.gitRange = opts.gitRange
this.gitCommittish = opts.gitCommittish
this.gitSubdir = opts.gitSubdir
this.hosted = opts.hosted
}

Expand Down Expand Up @@ -155,11 +157,45 @@ Result.prototype.toJSON = function () {
}

function setGitCommittish (res, committish) {
if (committish != null && committish.length >= 7 && committish.slice(0, 7) === 'semver:') {
res.gitRange = decodeURIComponent(committish.slice(7))
if (!committish) {
res.gitCommittish = null
} else {
res.gitCommittish = committish === '' ? null : committish
return res
}

// for each :: separated item:
for (const part of committish.split('::')) {
// if the item has no : the n it is a commit-ish
if (!part.includes(':')) {
if (res.gitRange) {
throw new Error('cannot override existing semver range with a committish')
}
if (res.gitCommittish) {
throw new Error('cannot override existing committish with a second committish')
}
res.gitCommittish = part
continue
}
// split on name:value
const [name, value] = part.split(':')
// if name is semver do semver lookup of ref or tag
if (name === 'semver') {
if (res.gitCommittish) {
throw new Error('cannot override existing committish with a semver range')
}
if (res.gitRange) {
throw new Error('cannot override existing semver range with a second semver range')
}
res.gitRange = decodeURIComponent(value)
continue
}
if (name === 'path') {
if (res.gitSubdir) {
throw new Error('cannot override existing path with a second path')
}
res.gitSubdir = `/${value}`
continue
}
log.warn('npm-package-arg', `ignoring unknown key "${name}"`)
}

return res
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
],
"dependencies": {
"hosted-git-info": "^5.0.0",
"proc-log": "^2.0.1",
"semver": "^7.3.5",
"validate-npm-package-name": "^4.0.0"
},
Expand Down
55 changes: 55 additions & 0 deletions test/basic.js
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,41 @@ t.test('basic', function (t) {
raw: 'user/foo#semver:^1.2.3',
},

'user/foo#path:dist': {
name: null,
escapedName: null,
type: 'git',
saveSpec: 'github:user/foo#path:dist',
fetchSpec: null,
gitCommittish: null,
gitSubdir: '/dist',
raw: 'user/foo#path:dist',
},

'user/foo#1234::path:dist': {
name: null,
escapedName: null,
type: 'git',
saveSpec: 'github:user/foo#1234::path:dist',
fetchSpec: null,
gitCommittish: '1234',
gitRange: null,
gitSubdir: '/dist',
raw: 'user/foo#1234::path:dist',
},

'user/foo#notimplemented:value': {
name: null,
escapedName: null,
type: 'git',
saveSpec: 'github:user/foo#notimplemented:value',
fetchSpec: null,
gitCommittish: null,
gitRange: null,
gitSubdir: null,
raw: 'user/foo#notimplemented:value',
},

'git+file://path/to/repo#1.2.3': {
name: null,
escapedName: null,
Expand Down Expand Up @@ -705,5 +740,25 @@ t.test('error message', t => {
message: 'Invalid package name "lodash.has " of package "lodash.has @^4": name cannot contain leading or trailing spaces; name can only contain URL-friendly characters.',
})

t.throws(() => npa('user/foo#1234::semver:^1.2.3'), {
message: 'cannot override existing committish with a semver range',
})

t.throws(() => npa('user/foo#semver:^1.2.3::1234'), {
message: 'cannot override existing semver range with a committish',
})

t.throws(() => npa('user/foo#path:skipped::path:dist'), {
message: 'cannot override existing path with a second path',
})

t.throws(() => npa('user/foo#1234::5678'), {
message: 'cannot override existing committish with a second committish',
})

t.throws(() => npa('user/foo#semver:^1.0.0::semver:^2.0.0'), {
message: 'cannot override existing semver range with a second semver range',
})

t.end()
})

0 comments on commit 246f1e9

Please sign in to comment.