Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for Yarn 2+ / Berry #23

Open
mxro opened this issue Jan 8, 2022 · 5 comments
Open

Support for Yarn 2+ / Berry #23

mxro opened this issue Jan 8, 2022 · 5 comments

Comments

@mxro
Copy link

mxro commented Jan 8, 2022

Would this tool work for Yarn v2+ / Berry (https://yarnpkg.com/)?

@rndD
Copy link

rndD commented Oct 27, 2022

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.

@mxro
Copy link
Author

mxro commented Oct 28, 2022

Nice script! I guess this could be added to this package?

@laurent22
Copy link

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());

@rndD
Copy link

rndD commented Nov 5, 2022

@laurent22 Nice! Thanks for sharing.

@jeremybacher
Copy link

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!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants