Open mxro opened 2 years ago
I made a script to sync versions for my yarn3 monorepo https://gist.github.com/rndD/044b6a00715710cdabf08d70452dbedb . Feel free to use it. I'm too lazy to make a package.
Nice script! I guess this could be added to this package?
Thanks for sharing @rndD, it works great. I've modified it to also support dev dependencies:
const fs =require('fs');
import { parseSyml } from '@yarnpkg/parsers';
const path = require('path');
let file = fs.readFileSync('yarn.lock', 'utf8');
let json = parseSyml(file);
// function make map with all packages and their versions.
// Json format:
// 'zen-observable-ts@npm:^1.2.0': {
// version: '1.2.3',
// resolution: 'zen-observable-ts@npm:1.2.3',
// dependencies: { 'zen-observable': '0.8.15' },
// checksum: '0548b555c67671f1240fb416755d2c27abf095b74a9e25c1abf23b2e15de40e6b076c678a162021358fe62914864eb9f0a57cd65e203d66c4988a08b220e6172',
// languageName: 'node',
// linkType: 'hard'
// },
const packagesInYarn = new Map();
for (const key of Object.keys(json)) {
const packageNVersions = key.split(',');
packageNVersions.forEach((packageNVersion) => {
packageNVersion = packageNVersion.trim();
const [packageName, version] = packageNVersion.split('@npm:');
const resolvedVersion = json[key].version;
packagesInYarn.set(`${packageName}|${version}`, resolvedVersion);
});
}
const processDeps = (deps:any) => {
let changed = false;
if (deps) {
Object.keys(deps).forEach((dep) => {
if (packagesInYarn.has(`${dep}|${deps[dep]}`)) {
const resolvedVersion = packagesInYarn.get(`${dep}|${deps[dep]}`);
if (resolvedVersion !== deps[dep]) {
deps[dep] = resolvedVersion;
changed = true;
}
}
});
}
return changed;
}
function findDivergeVersionsInPackageJson(rootDir: string) {
// read all package json in root except node_modules
const files = fs.readdirSync(rootDir);
for (const file of files) {
const filePath = path.join(rootDir, file);
const stat = fs.statSync(filePath);
if (stat.isDirectory() && file !== 'node_modules') {
findDivergeVersionsInPackageJson(filePath);
} else if (stat.isFile() && file === 'package.json') {
const packageJson = fs.readFileSync(filePath, 'utf8');
const parsedPackageJson = parseSyml(packageJson);
const {
dependencies: deps,
} = parsedPackageJson;
const changedDeps = processDeps(deps);
const changedDevDeps = processDeps(parsedPackageJson.devDependencies);
if (changedDeps || changedDevDeps) {
fs.writeFileSync(
filePath,
JSON.stringify(parsedPackageJson, null, 2) + `\r`,
);
}
}
}
}
findDivergeVersionsInPackageJson(process.cwd());
@laurent22 Nice! Thanks for sharing.
Thanks for sharing, that solution works for me @rndD @laurent22 !! 💯
I'm also share, the change of what I have to do to work in my project:
In package.json
:
"scripts": {
"lock": "yarn add @yarnpkg/parsers && npx ts-node yarn-lock-versions-to-package.ts"
}
Create new file (yarn-lock-versions-to-package.ts
) and paste the following:
const fs = require('fs');
const parseSyml = require('@yarnpkg/parsers').parseSyml;
const path = require('path');
let file = fs.readFileSync('yarn.lock', 'utf8');
let json = parseSyml(file);
const packagesInYarn = new Map();
for (const key of Object.keys(json)) {
const packageNVersions = key.split(',');
packageNVersions.forEach((packageNVersion) => {
packageNVersion = packageNVersion.trim();
const [packageName, version] = packageNVersion.split('@npm:');
const resolvedVersion = json[key].version;
packagesInYarn.set(`${packageName}|${version}`, resolvedVersion);
});
}
const processDeps = (deps:any) => {
let changed = false;
if (deps) {
Object.keys(deps).forEach((dep) => {
if (packagesInYarn.has(`${dep}|${deps[dep]}`)) {
const resolvedVersion = packagesInYarn.get(`${dep}|${deps[dep]}`);
if (resolvedVersion !== deps[dep]) {
deps[dep] = resolvedVersion;
changed = true;
}
}
});
}
return changed;
}
function findDivergeVersionsInPackageJson(rootDir: string) {
// read all package json in root except node_modules
const files = fs.readdirSync(rootDir);
for (const file of files) {
const filePath = path.join(rootDir, file);
const stat = fs.statSync(filePath);
if (stat.isDirectory() && file !== 'node_modules') {
findDivergeVersionsInPackageJson(filePath);
} else if (stat.isFile() && file === 'package.json') {
const packageJson = fs.readFileSync(filePath, 'utf8');
const parsedPackageJson = parseSyml(packageJson);
const {
dependencies: deps,
} = parsedPackageJson;
const changedDeps = processDeps(deps);
const changedDevDeps = processDeps(parsedPackageJson.devDependencies);
if (changedDeps || changedDevDeps) {
fs.writeFileSync(
filePath,
JSON.stringify(parsedPackageJson, null, 2) + `\r`,
);
}
}
}
}
findDivergeVersionsInPackageJson(process.cwd());
Finally, execute: yarn lock
.
Hope it works for you too!
Would this tool work for Yarn v2+ / Berry (https://yarnpkg.com/)?