JamieMason / syncpack

Consistent dependency versions in large JavaScript Monorepos.
https://jamiemason.github.io/syncpack/
MIT License
1.32k stars 43 forks source link

feat(format): lint formatting of a single file #226

Open jameshearttech opened 2 weeks ago

jameshearttech commented 2 weeks ago

I use lint-staged in local development for linting files in Git staging prior to commit. I would like to lint package.json files using syncpack using the same approach. It would be great if I could do something like pnpm exec syncpack lint /path/to/package.json and it would override --source using the config from the root project in the monorepo.

JamieMason commented 2 weeks ago

Hey @jameshearttech, As you mentioned, you can target specific files with --source like so: syncpack format --source some/package.json, but it only tends to make sense with format and list.

For linting single files there are probably a few things missing as syncpack is expecting to check that a whole project is correct.

What kind of things did you have in mind for a single file? That its formatting matches? Or something more?

jameshearttech commented 2 weeks ago

@JamieMason I looked through the help for each command. Looks like --source works for every command except lint. I believe lint is the only command that checks formatting. Is that right?

JamieMason commented 2 weeks ago

What kind of things did you have in mind for a single file? That its formatting matches? Or something more?

I think you're saying you only want to check formatting and that sounds good, I'll take a look so that can be supported for single files.

Thanks a lot

jameshearttech commented 2 weeks ago

What kind of things did you have in mind for a single file?

I apologize for not being more concise. What does syncpack do? Please correct me if I'm wrong.

Check formatting: syncpack lint seems to check formatting but does not support --source. Fix formatting: syncpack format --source

Check semver ranges: syncpack lint-semver-ranges --source Fix semver ranges: syncpack fix-mismatches --source

Check versions: syncpack list-mismatches --source Fix versions: syncpack fix-mismatches --source

Here's a mock up of my lint-staged configuration.

// lint-staged.config.mjs
export default {
    check: {
        '*.{js,cjs,mjs}': ['eslint', 'prettier --check'],
        '*.{scss,css,json,yaml,yml,html}': ['prettier --check'],
        '*.md': ['remark', 'prettier --check'],
        'package.json': [
            // 'syncpack check-format --source',
            'syncpack lint-semver-ranges --source',
            'syncpack list-mismatches --source'
        ]
    },
    fix: {
        '*.{js,cjs,mjs}': ['eslint --fix', 'prettier --write'],
        '*.{scss,css,json,yaml,yml,html}': ['prettier --write'],
        '*.md': ['remark --output', 'prettier --write'],
        'package.json': ['syncpack format --source', 'syncpack fix-mismatches --source']
    }
};
JamieMason commented 2 weeks ago

Thanks a lot for this detail @jameshearttech and yes you're absolutely right, your lint-staged config looks good but there are some gaps in syncpack, I'll summarise:

What syncpack can/can't do currently:

If you or someone reading this has multiple package.json files, I would check all package.json files whenever any of them change, which should be possible with something like:

// lint-staged.config.mjs
export default {
  check: {
    "*.{js,cjs,mjs}": ["eslint", "prettier --check"],
    "*.{scss,css,json,yaml,yml,html}": ["prettier --check"],
    "*.md": ["remark", "prettier --check"],
    "**/package.json": () => "syncpack lint",
  },
  fix: {
    "*.{js,cjs,mjs}": ["eslint --fix", "prettier --write"],
    "*.{scss,css,json,yaml,yml,html}": ["prettier --write"],
    "*.md": ["remark --output", "prettier --write"],
    "**/package.json": () => ["syncpack format", "syncpack fix-mismatches"],
  },
};

For the missing functionality of checking formatting of a single file, I'm working on a rewrite in #222 and will make that possible as part of that work. I'll keep this open to track that.

Let me know if I've missed anything, thanks.

jameshearttech commented 2 weeks ago

I'm using pnpm so syncpack uses workspaces and I don't necessarily need to use globs, but good to clarify for future readers.

JamieMason commented 2 weeks ago

Can you clarify what you mean, are you referring to the globs in the lint-staged config? or globs that you might pass to syncpack via --source?

jameshearttech commented 1 week ago

Oh, I was thinking of the globs I might pass to syncpack via --source, but these globs are in the lint-staged config. Why did you write "**/package.json": () => "syncpack lint",?