Skip to content

Commit 3ccbfb8

Browse files
committed
fix packageVersion for file protocol
1 parent bf8e1e7 commit 3ccbfb8

File tree

2 files changed

+103
-35
lines changed

2 files changed

+103
-35
lines changed

src/index.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ const appPath = getAppRootPath()
99

1010
var dashdashOptions = [
1111
{ name: "use-yarn", type: "bool" },
12+
{ name: "create-issue", type: "bool" },
1213
{ name: "case-sensitive-path-filtering", type: "bool" },
1314
{ name: "reverse", type: "bool" },
1415
{ names: ["help", "h"], type: "bool" },
@@ -74,6 +75,10 @@ if (argv.version) {
7475
appPath,
7576
argv.use_yarn ? "yarn" : null,
7677
)
78+
if (isDebug) {
79+
console.log(`patch-package/index: packageManager = ${packageManager}`)
80+
}
81+
7782
const createIssue = argv.create_issue
7883
packageNames.forEach((packagePathSpecifier: string) => {
7984
makePatch({

src/makePatch.ts

Lines changed: 98 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import chalk from "chalk"
22
import { join, dirname, resolve } from "./path"
3+
import { basename } from "path"
34
import { spawnSafeSync } from "./spawnSafe"
45
import { PackageManager } from "./detectPackageManager"
56
import { removeIgnoredFiles } from "./filterFiles"
@@ -25,7 +26,7 @@ import { resolveRelativeFileDependencies } from "./resolveRelativeFileDependenci
2526
import { getPackageResolution } from "./getPackageResolution"
2627
import { parsePatchFile } from "./patch/parse"
2728
import { gzipSync } from "zlib"
28-
//import { getPackageVersion } from "./getPackageVersion"
29+
import { getPackageVersion } from "./getPackageVersion"
2930
import {
3031
maybePrintIssueCreationPrompt,
3132
openIssueCreationLink,
@@ -34,6 +35,7 @@ import { quote as shlexQuote } from "shlex"
3435

3536
const isVerbose = global.patchPackageIsVerbose
3637
const isDebug = global.patchPackageIsDebug
38+
const isTest = process.env.NODE_ENV == 'test'
3739

3840
function printNoPackageFoundError(
3941
packageName: string,
@@ -73,6 +75,13 @@ export function makePatch({
7375
const packagePath = join(appPath, packageDetails.path)
7476
const packageJsonPath = join(packagePath, "package.json")
7577

78+
if (isDebug) {
79+
console.log(`patch-package/makePatch: appPath = ${appPath}`)
80+
console.log(`patch-package/makePatch: packagePath = ${packagePath}`)
81+
console.log(`patch-package/makePatch: appPackageJson:`)
82+
console.dir(appPackageJson)
83+
}
84+
7685
if (!existsSync(packageJsonPath)) {
7786
printNoPackageFoundError(packagePathSpecifier, packageJsonPath)
7887
process.exit(1)
@@ -102,6 +111,12 @@ export function makePatch({
102111

103112
console.info(chalk.grey("•"), "Creating temporary folder")
104113

114+
if (isDebug) {
115+
console.log(
116+
`patch-package/makePatch: tmpRepoNpmRoot = ${tmpRepoNpmRoot}`,
117+
)
118+
}
119+
105120
const resolvedVersion = getPackageResolution({
106121
packageDetails,
107122
packageManager,
@@ -124,36 +139,79 @@ export function makePatch({
124139
}),
125140
)
126141

127-
/*
142+
const declaredVersion = (() => {
143+
var v = resolvedVersion.version
144+
// https://docs.npmjs.com/cli/v7/configuring-npm/package-json
145+
// <protocol>://[<user>[:<password>]@]<hostname>[:<port>][:][/]<path>[#<commit-ish> | #semver:<semver>]
146+
// pnpm uses link: protocol instead of file:
147+
// TODO add more protocols?
148+
var m = v.match(/^(file|link|http|https|git|git\+https|git\+http|git\+ssh|git\+file|github):(.+)$/)
149+
if (m) {
150+
var protocol = m[1]
151+
var location = m[2]
152+
var isGit = protocol.startsWith('git')
153+
var gitCommit = isGit ? location.split('#').slice(-1)[0] : null
154+
if (isGit && !gitCommit) {
155+
throw new Error(`error: found wildcard git version ${v}. package.json must pin the exact version of ${packageDetails.name} in the format <protocol>:<packagePath>#<commitHash>`)
156+
}
157+
if (isGit) {
158+
return { full: v, protocol, location, gitCommit }
159+
}
160+
else {
161+
// sample: https://registry.yarnpkg.com/left-pad/-/left-pad-1.3.0.tgz#5b8a3a7765dfe001261dde915589e782f8c94d1e
162+
// hash is sha1sum of tgz file
163+
// -> use version number from package's package.json
164+
var version = getPackageVersion(join(resolve(packageDetails.path), "package.json"))
165+
if (isVerbose) {
166+
console.log(`patch-package/makePatch: warning: using version ${version} from ${packageDetails.name}/package.json`)
167+
}
168+
return { version }
169+
}
170+
}
171+
if (!v.match(/^[0-9]+\.[0-9]+\.[0-9]+/)) {
172+
throw new Error(`error: found wildcard version. package.json must pin the exact version of ${packageDetails.name} in the format <package>@<major>.<minor>.<patch>`)
173+
}
174+
return { full: v, version: v }
175+
})()
176+
177+
const packageVersion = (
178+
declaredVersion.version || declaredVersion.gitCommit || declaredVersion.full
179+
)
180+
128181
// originCommit is more precise than pkg.version
129182
if (isDebug) {
130-
console.log(
131-
`patch-package/makePatch: resolvedVersion.originCommit = ${resolvedVersion.originCommit}`,
132-
)
133-
console.log(
134-
`patch-package/makePatch: resolvedVersion.version = ${resolvedVersion.version}`,
135-
)
183+
//console.log(`patch-package/makePatch: resolvedVersion.originCommit = ${resolvedVersion.originCommit}`)
184+
console.log(`patch-package/makePatch: resolvedVersion.version = ${resolvedVersion.version}`)
185+
console.log(`patch-package/makePatch: packageVersion = ${packageVersion}`)
136186
}
137-
const packageVersion =
138-
resolvedVersion.originCommit ||
139-
getPackageVersion(join(resolve(packageDetails.path), "package.json"))
140-
*/
187+
188+
//const packageVersion =
189+
// resolvedVersion.originCommit ||
190+
// getPackageVersion(join(resolve(packageDetails.path), "package.json"))
141191

142192
// this is broken when installing from git -> version can be a pseudo-version like 1.0.0-canary
143193
//const packageVersion = getPackageVersion(join(resolve(packageDetails.path), "package.json"))
144194

145-
const packageVersion = resolvedVersion.version
195+
// TODO rename resolvedVersion -> declaredVersion
196+
197+
// FIXME false positive
198+
// test integration-tests/create-issue/create-issue.test.ts
199+
// -> patching left-pad prompts to submit an issue
200+
// https://registry.yarnpkg.com/left-pad/-/left-pad-1.3.0.tgz#5b8a3a7765dfe001261dde915589e782f8c94d1e
201+
// hash is sha checksum of tgz file -> just use the version 1.3.0
202+
/*
203+
const packageVersion = (
204+
!resolvedVersion.version.match(/^(file:|link:)/) ? resolvedVersion.version :
205+
getPackageVersion(join(resolve(packageDetails.path), "package.json"))
206+
)
207+
*/
146208

147209
if (isDebug) {
210+
console.log(`patch-package/makePatch: resolvedVersion.version = ${resolvedVersion.version}`)
211+
console.log(`patch-package/makePatch: getPackageVersion -> ${getPackageVersion(join(resolve(packageDetails.path), "package.json"))}`)
148212
console.log(`patch-package/makePatch: packageVersion = ${packageVersion}`)
149-
console.log(
150-
`patch-package/makePatch: package path = ${packageDetails.path}`,
151-
)
152-
console.log(
153-
`patch-package/makePatch: package path resolved = ${resolve(
154-
packageDetails.path,
155-
)}`,
156-
)
213+
console.log(`patch-package/makePatch: package path = ${packageDetails.path}`)
214+
console.log(`patch-package/makePatch: package path resolved = ${resolve(packageDetails.path)}`)
157215
}
158216

159217
// copy .npmrc/.yarnrc in case packages are hosted in private registry
@@ -375,9 +433,11 @@ export function makePatch({
375433
// patchfiles are parsed in patch/parse.ts function parsePatchLines
376434
// -> header comments are ignored
377435
let diffHeader = ""
378-
diffHeader += `# generated by patch-package ${patchPackageVersion} on ${new Date().toLocaleString(
379-
"lt",
380-
)}\n`
436+
const dateStr = (
437+
isTest ? '1980-01-01 00:00:00' : // mock date
438+
new Date().toLocaleString("lt")
439+
)
440+
diffHeader += `# generated by patch-package ${patchPackageVersion} on ${dateStr}\n`
381441
diffHeader += `#\n`
382442
const prettyArgv = process.argv.slice()
383443
if (prettyArgv[0].match(/node/)) {
@@ -390,14 +450,26 @@ export function makePatch({
390450
diffHeader += `# ${prettyArgv.map((a) => shlexQuote(a)).join(" ")}\n`
391451
diffHeader += `#\n`
392452
diffHeader += `# declared package:\n`
393-
diffHeader += `# ${packageDetails.name}: ${resolvedVersion.version}\n` // TODO rename to declaredVersion
453+
// TODO rename resolvedVersion.version to declaredVersion
454+
const declaredPackageStr = (
455+
isTest ? (() => {
456+
const v = resolvedVersion.version
457+
const b = basename(v)
458+
if (b != v) return `file:/mocked/path/to/${b}` // mock path // TODO keep the relative path? as declared in /package.json. see getPackageResolution "resolve relative file path"
459+
return v
460+
})() :
461+
resolvedVersion.version
462+
)
463+
diffHeader += `# ${packageDetails.name}: ${declaredPackageStr}\n`
464+
/* redundant. this is visible from command, sample: npx patch-package wrap-ansi/string-width -> packageNames: wrap-ansi, string-width
394465
if (packageDetails.packageNames.length > 1) {
395466
diffHeader += `#\n`
396467
diffHeader += `# package names:\n`
397468
packageDetails.packageNames.forEach((packageName) => {
398469
diffHeader += `# ${packageName}\n`
399470
})
400471
}
472+
*/
401473
diffHeader += `#\n`
402474

403475
const patchFileName = createPatchFileName({
@@ -438,18 +510,9 @@ function createPatchFileName({
438510
packageDetails: PackageDetails
439511
packageVersion: string
440512
}) {
441-
const packageVersionFilename = packageVersion.includes("#")
442-
? packageVersion.split("#")[1] // extract commit hash
443-
: packageVersion.replace(/\//g, "_")
444-
if (isVerbose) {
445-
console.log(
446-
`patch-package/makePatch: packageVersion ${packageVersion} -> packageVersionFilename ${packageVersionFilename}`,
447-
)
448-
}
449-
450513
const packageNames = packageDetails.packageNames
451514
.map((name) => name.replace(/\//g, "+"))
452515
.join("++")
453516

454-
return `${packageNames}+${packageVersionFilename}.patch`
517+
return `${packageNames}+${packageVersion}.patch`
455518
}

0 commit comments

Comments
 (0)