@@ -9,6 +9,7 @@ const semver = require('semver')
99const path = global . FAKE_WINDOWS ? require ( 'path' ) . win32 : require ( 'path' )
1010const validatePackageName = require ( 'validate-npm-package-name' )
1111const { homedir } = require ( 'os' )
12+ const log = require ( 'proc-log' )
1213
1314const isWindows = process . platform === 'win32' || global . FAKE_WINDOWS
1415const hasSlashes = isWindows ? / \\ | [ / ] / : / [ / ] /
@@ -120,6 +121,7 @@ function Result (opts) {
120121 }
121122 this . gitRange = opts . gitRange
122123 this . gitCommittish = opts . gitCommittish
124+ this . gitSubdir = opts . gitSubdir
123125 this . hosted = opts . hosted
124126}
125127
@@ -155,11 +157,45 @@ Result.prototype.toJSON = function () {
155157}
156158
157159function setGitCommittish ( res , committish ) {
158- if ( committish != null && committish . length >= 7 && committish . slice ( 0 , 7 ) === 'semver:' ) {
159- res . gitRange = decodeURIComponent ( committish . slice ( 7 ) )
160+ if ( ! committish ) {
160161 res . gitCommittish = null
161- } else {
162- res . gitCommittish = committish === '' ? null : committish
162+ return res
163+ }
164+
165+ // for each :: separated item:
166+ for ( const part of committish . split ( '::' ) ) {
167+ // if the item has no : the n it is a commit-ish
168+ if ( ! part . includes ( ':' ) ) {
169+ if ( res . gitRange ) {
170+ throw new Error ( 'cannot override existing semver range with a committish' )
171+ }
172+ if ( res . gitCommittish ) {
173+ throw new Error ( 'cannot override existing committish with a second committish' )
174+ }
175+ res . gitCommittish = part
176+ continue
177+ }
178+ // split on name:value
179+ const [ name , value ] = part . split ( ':' )
180+ // if name is semver do semver lookup of ref or tag
181+ if ( name === 'semver' ) {
182+ if ( res . gitCommittish ) {
183+ throw new Error ( 'cannot override existing committish with a semver range' )
184+ }
185+ if ( res . gitRange ) {
186+ throw new Error ( 'cannot override existing semver range with a second semver range' )
187+ }
188+ res . gitRange = decodeURIComponent ( value )
189+ continue
190+ }
191+ if ( name === 'path' ) {
192+ if ( res . gitSubdir ) {
193+ throw new Error ( 'cannot override existing path with a second path' )
194+ }
195+ res . gitSubdir = `/${ value } `
196+ continue
197+ }
198+ log . warn ( 'npm-package-arg' , `ignoring unknown key "${ name } "` )
163199 }
164200
165201 return res
0 commit comments