wclr / yalc

Work with yarn/npm packages locally like a boss.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Can `yalc check` check only files staged in the current commit?

AlanSl opened this issue · comments

I'm looking to see if it's possible to set up a precommit script that checks package.json files for yalc dependencies but only if those changed are staged in the commit in question. Same principle as with projects like lint-staged.

This project is a monorepo with lots of workspaces that setup up different testing environments for projects from other repositories and I'd like to make it as easy as possible to yalc in updates, make and commit changes in the external repo, make and commit changes in this repo, then clean up all the yalcing when finished.yalc check is a very useful safeguard but currently it's a bit of a nuisance that yalc check prevents innocent commits that don't include package.json files, preventing committing changes during testing from yalced dependencies.

I've tried:

  • Calling yalc check from lint-staged, but this doesn't work because lint-staged works by passing filenames and yalc check doesn't take filenames as arguments (I think lint-staged would work if the command accepted a syntax like yalc check /path/to/package.json where the optional argument(s) if present replace the working directory file lookup)

  • Adding the --commit flag, like yalc check --commit (or in my context "git:pre-commit": "npm exec --workspaces yalc check --commit"), but this fails with an error:

    TypeError: Cannot read property 'toString' of null
    at Object.checkManifest (.../.config/yarn/global/node_modules/yalc/src/check.js:55:13)
    at Object.handler (.../.config/yarn/global/node_modules/yalc/src/yalc.js:300:17)

    Looking at the source it's not clear to me how the --commit flag is supposed to work; execSync is run twice, the output of the first call is turned into a string then discarded, then the output of the second call is turned into an array and filtered, but the filtered array appears to be unused?

Never mind! I found a way to make yalc check and lint-staged work well together.

Just add the yalc check line in your lint staged config file on rules specific to yalc.lock and the package.json file(s) that can have yalc dependencies written into them. For example:

// in lint-staged.config.js
module.exports = {
  // your normal lint staged rules here, for example:
  '*.{js,jsx}': 'npm run lint:fix',
  // block any commit that contains a yalc.lock anywhere
  'yalc.lock': 'yalc check',
  // if you're in a monorepo with multiple package.jsons you can allow commits to ones
  // that aren't rewritten by yalc by only including paths here to ones that are
  './package.json': 'yalc check',
}

This will allow commits to other files while yalc is in place but won't allow commits to the yalc-rewritten package.json or any commits of yalc.lock until you run yalc remove --all to clean up. Yalc check still runs on all files, staged or otherwise, but it only runs if the relevant files are staged in a given commit.

There's a small limitation that you can't stage and commit individual line changes to a package.json file that also contains unstaged yalc dependency rewrites, but I think that's a pretty small limitation.