Skip to content

Commit

Permalink
Try yarn v4 support
Browse files Browse the repository at this point in the history
  • Loading branch information
davegaeddert committed Mar 5, 2024
1 parent 3b62a4b commit 248cc0f
Show file tree
Hide file tree
Showing 9 changed files with 333 additions and 31 deletions.
99 changes: 68 additions & 31 deletions src/lockfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ export class Lockfile {
return path.basename(this.path) === 'package-lock.json'
}

isYarn4() {
return shell.exec('yarn --version').stdout.startsWith('4.')
}

generate() {
if (this.isYarnLock()) {
return this.generateYarnLock()
Expand All @@ -61,9 +65,13 @@ export class Lockfile {
}

generateYarnLock() {
shell.exec(
`cd ${this.dirPath} && yarn install --ignore-scripts --ignore-engines --ignore-platform`
)
if (this.isYarn4()) {
shell.exec(`cd ${this.dirPath} && yarn install --mode=update-lockfile`)
} else {
shell.exec(
`cd ${this.dirPath} && yarn install --ignore-scripts --ignore-engines --ignore-platform`
)
}
}

generatePackageLock() {
Expand All @@ -86,16 +94,20 @@ export class Lockfile {
}

updateYarnLock() {
try {
shell.exec(
`cd ${this.dirPath} && yarn upgrade --ignore-scripts --ignore-engines --ignore-platform`
)
} catch (e) {
// may throw an 'Outdated lockfile' error, meaning install has to be run first
this.generateYarnLock()
shell.exec(
`cd ${this.dirPath} && yarn upgrade --ignore-scripts --ignore-engines --ignore-platform`
)
if (this.isYarn4()) {
shell.exec(`cd ${this.dirPath} && yarn up --mode=update-lockfile`)
} else {
try {
shell.exec(
`cd ${this.dirPath} && yarn upgrade --ignore-scripts --ignore-engines --ignore-platform`
)
} catch (e) {
// may throw an 'Outdated lockfile' error, meaning install has to be run first
this.generateYarnLock()
shell.exec(
`cd ${this.dirPath} && yarn upgrade --ignore-scripts --ignore-engines --ignore-platform`
)
}
}
}

Expand Down Expand Up @@ -126,33 +138,58 @@ export class Lockfile {

convertYarnLockToSchema() {
console.log('Converting yarn.lock to lockfile in dependencies-schema')
// TODO windows line endings are currently broken: https://github.com/yarnpkg/yarn/issues/5214
const file = fs.readFileSync(this.path, 'utf8').replace(/\r/g, '')
const yarnLockfileResults = yarnLockfile.parse(file)

const dependenciesForSchema = {}

for (const dep in yarnLockfileResults.object) {
const info = yarnLockfile.explodeEntry(
dep,
yarnLockfileResults.object[dep]
if (this.isYarn4()) {
const output = shell.exec(
`cd ${this.dirPath} && yarn info --all --recursive --json`
)
for (const line of output.split('\n')) {
if (line === '') continue
const info = JSON.parse(line)

const manifestConstraint = this.manifestConstraintForDependency(info.name)
// Skip anything that doesn't look like it's from npm for now...
if (info.value.indexOf('@npm:') === -1) continue

if (manifestConstraint && dep !== info.name + '@' + manifestConstraint) {
// make sure we're getting the version that should be installed
// in the root (not for a nested dependency) by only getting those that have
// the package.json constraint in them
continue
const name = info.value.split('@')[0]
const version = info.children.Version;
const is_transitive = this.manifestConstraintForDependency(name) === undefined
dependenciesForSchema[name] = {
version: { name: version },
is_transitive: is_transitive,
source: "npm",
}
}
} else {

// TODO windows line endings are currently broken: https://github.com/yarnpkg/yarn/issues/5214
const file = fs.readFileSync(this.path, 'utf8').replace(/\r/g, '')
const yarnLockfileResults = yarnLockfile.parse(file)

for (const dep in yarnLockfileResults.object) {
const info = yarnLockfile.explodeEntry(
dep,
yarnLockfileResults.object[dep]
)

dependenciesForSchema[info.name] = {
version: { name: info.version },
// constraint: dep.replace(`${info.name}@`, ''), // simply keep the comma separated ranges without the name@ parts
is_transitive: manifestConstraint === undefined,
source: info.registry,
const manifestConstraint = this.manifestConstraintForDependency(info.name)

if (manifestConstraint && dep !== info.name + '@' + manifestConstraint) {
// make sure we're getting the version that should be installed
// in the root (not for a nested dependency) by only getting those that have
// the package.json constraint in them
continue
}

dependenciesForSchema[info.name] = {
version: { name: info.version },
// constraint: dep.replace(`${info.name}@`, ''), // simply keep the comma separated ranges without the name@ parts
is_transitive: manifestConstraint === undefined,
source: info.registry,
}
}

}

return {
Expand Down
102 changes: 102 additions & 0 deletions tests/yarn4/dependencies.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
{
"lockfiles": {
"yarn.lock": {
"current": {
"dependencies": {
"js-tokens": {
"version": {
"name": "4.0.0"
},
"is_transitive": true,
"source": "npm"
},
"loose-envify": {
"version": {
"name": "1.4.0"
},
"is_transitive": true,
"source": "npm"
},
"react": {
"version": {
"name": "18.2.0"
},
"source": "npm"
},
"react-dom": {
"version": {
"name": "18.2.0"
},
"source": "npm"
},
"scheduler": {
"version": {
"name": "0.23.0"
},
"is_transitive": true,
"source": "npm"
}
},
"fingerprint": "1bbc320984a9b15bfaddb19be2aadcde"
},
"updated": {
"dependencies": {
"js-tokens": {
"version": {
"name": "4.0.0"
},
"is_transitive": true,
"source": "npm"
},
"loose-envify": {
"version": {
"name": "1.4.0"
},
"is_transitive": true,
"source": "npm"
},
"react": {
"version": {
"name": "18.2.0"
},
"source": "npm"
},
"react-dom": {
"version": {
"name": "18.2.0"
},
"source": "npm"
},
"scheduler": {
"version": {
"name": "0.23.0"
},
"is_transitive": true,
"source": "npm"
}
},
"fingerprint": "1bbc320984a9b15bfaddb19be2aadcde"
}
}
},
"manifests": {
"package.json": {
"current": {
"dependencies": {
"react": {
"constraint": "^18",
"source": "npm"
},
"react-dom": {
"constraint": "^18",
"source": "npm"
}
}
},
"lockfile_path": "yarn.lock",
"updated": {
"dependencies": {}
}
}
}
}
9 changes: 9 additions & 0 deletions tests/yarn4/deps_tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
tests:

- name: yarn4
repo: repo
diff: repo_updated
diff_args:
- "-x"
- ".yarn"
data: dependencies.json
2 changes: 2 additions & 0 deletions tests/yarn4/repo/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.yarn
.pnp.cjs
12 changes: 12 additions & 0 deletions tests/yarn4/repo/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"name": "test",
"version": "0.1.0",
"private": true,
"dependencies": {
"react": "^18"
},
"devDependencies": {
"react-dom": "^18"
},
"packageManager": "yarn@4.1.1"
}
63 changes: 63 additions & 0 deletions tests/yarn4/repo/yarn.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# This file is generated by running "yarn install" inside your project.
# Manual changes might be lost - proceed with caution!

__metadata:
version: 8
cacheKey: 10c0

"js-tokens@npm:^3.0.0 || ^4.0.0":
version: 4.0.0
resolution: "js-tokens@npm:4.0.0"
checksum: 10c0/e248708d377aa058eacf2037b07ded847790e6de892bbad3dac0abba2e759cb9f121b00099a65195616badcb6eca8d14d975cb3e89eb1cfda644756402c8aeed
languageName: node
linkType: hard

"loose-envify@npm:^1.1.0":
version: 1.4.0
resolution: "loose-envify@npm:1.4.0"
dependencies:
js-tokens: "npm:^3.0.0 || ^4.0.0"
bin:
loose-envify: cli.js
checksum: 10c0/655d110220983c1a4b9c0c679a2e8016d4b67f6e9c7b5435ff5979ecdb20d0813f4dec0a08674fcbdd4846a3f07edbb50a36811fd37930b94aaa0d9daceb017e
languageName: node
linkType: hard

"react-dom@npm:^18":
version: 18.2.0
resolution: "react-dom@npm:18.2.0"
dependencies:
loose-envify: "npm:^1.1.0"
scheduler: "npm:^0.23.0"
peerDependencies:
react: ^18.2.0
checksum: 10c0/66dfc5f93e13d0674e78ef41f92ed21dfb80f9c4ac4ac25a4b51046d41d4d2186abc915b897f69d3d0ebbffe6184e7c5876f2af26bfa956f179225d921be713a
languageName: node
linkType: hard

"react@npm:^18":
version: 18.2.0
resolution: "react@npm:18.2.0"
dependencies:
loose-envify: "npm:^1.1.0"
checksum: 10c0/b562d9b569b0cb315e44b48099f7712283d93df36b19a39a67c254c6686479d3980b7f013dc931f4a5a3ae7645eae6386b4aa5eea933baa54ecd0f9acb0902b8
languageName: node
linkType: hard

"scheduler@npm:^0.23.0":
version: 0.23.0
resolution: "scheduler@npm:0.23.0"
dependencies:
loose-envify: "npm:^1.1.0"
checksum: 10c0/b777f7ca0115e6d93e126ac490dbd82642d14983b3079f58f35519d992fa46260be7d6e6cede433a92db70306310c6f5f06e144f0e40c484199e09c1f7be53dd
languageName: node
linkType: hard

"test@workspace:.":
version: 0.0.0-use.local
resolution: "test@workspace:."
dependencies:
react: "npm:^18"
react-dom: "npm:^18"
languageName: unknown
linkType: soft
2 changes: 2 additions & 0 deletions tests/yarn4/repo_updated/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.yarn
.pnp.cjs
12 changes: 12 additions & 0 deletions tests/yarn4/repo_updated/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"name": "test",
"version": "0.1.0",
"private": true,
"dependencies": {
"react": "^18"
},
"devDependencies": {
"react-dom": "^18"
},
"packageManager": "yarn@4.1.1"
}
Loading

0 comments on commit 248cc0f

Please sign in to comment.