[Feature] Adds --scope and --ignore support for bootstrap, exec, run, clean and ls#386
Conversation
|
So, this was based on asini/asini#8 which had some other changes not in Lerna which I've just realised came from #365. Lots of this was verbatim from the asini merge but there are a couple of differences from what was taken from #365. More than happy to help merge these two together in which ever order, just give me a yell. 👍 |
|
|
||
| runPreparations() { | ||
| const scope = this.flags.scope || (this.configFlags && this.configFlags.scope); | ||
| const ignore = this.flags.ignore || (this.configFlags && this.configFlags.ignore); |
There was a problem hiding this comment.
The .configFlags is only set in Bootstrap right now.
|
|
||
| The `ignore` flag, when used with the `bootstrap` command, can also be set in `lerna.json` under the `bootstrapConfig` key. The command-line flag will take precendence over this option. This flag is supported in `bootstrap` and `exec` commands. | ||
|
|
||
| **Note**: If both `scope` and `ignore` are provided to `exec` command, `scope` takes precedence. |
There was a problem hiding this comment.
An intended side effect of this change is that scope wont take precedence anymore. Is there any reason to take precedence when you could simply obey both and throw an error if they would result in no packages being selected? I don't think it would be a common use case to be using both at the same time, but this would make more sense to me.
There was a problem hiding this comment.
(More than happy to change it though, just felt more consistent)
There was a problem hiding this comment.
In life in general, explicit exclusions tend to take precedence over explicit inclusions. I think this is a reasonable change. I would perhaps print a warning/confirmation that X number of packages would be in scope but were excluded? Better to be explicit with your user. Does it still throw if no packages are selected?
There was a problem hiding this comment.
Yup, still throws the error.
Yea, a warning might be nice for that. If you were using both at the same time I imagine you must already know that they will have overlap (or you would have just used 1 right?), but it would still make sense from a logging point of view
Scoping to packages that match "package-1*"
Ignoring packages that match "*-a"
1 package would have been scoped but is ignored:
-- "package-1-a"
There was a problem hiding this comment.
True, you would presumably know what you're getting yourself into. Lerna doesn't log the names anywhere else, so a count is probably sufficient.
There was a problem hiding this comment.
@lukebatchelor When we developed the feature I suggested ignore to trump scope: #168 (comment) - not sure why and when that might have changed.
There was a problem hiding this comment.
@joscha It changed in this PR, hopefully. Looking through that convo, I don't see a reason you cant accept both flags (as in this PR) and throw an error if the result would return no packages.
Useful for cases like
npm install --ignore-scripts && lerna bootstrap --scope "ak*" --ignore "ak-editor*"There was a problem hiding this comment.
Ignore should definitely take precedence over scope.
There was a problem hiding this comment.
Just to make sure we're saying the same thing, scope wont override ignore in this case. They work together. Scope is a whitelist, ignore is a blacklist. If scope exists, then no other packages other than the ones in scope are included. If ignore exists, no packages matched by ignore will get included.
So, if you were matched by both, you would still get ignored.
|
@hzoo, @thejameskyle, Is there anything else I should do for this to get merged? I've got the next 3 days to be able to work on this pretty freely, and was hoping to do any iteration on this one, starting work merging it with #365 (my PR borrows quite a lot of the refactoring from that), and looking how we might do something with #388, probably/possibly using #384 |
|
@hzoo / @thejameskyle can we merge this? Working around/waiting for prepublishing the entire world is making me sad. :( |
| * @param {String} filters.ignore glob The glob to filter the package name against | ||
| * @return {Array.<Package>} The packages with a name matching the glob | ||
| */ | ||
| static getFilteredPackages(packages, {scope, ignore}) { |
There was a problem hiding this comment.
I would perhaps rename this to make it a bit more obviously different than filterPackages.
There was a problem hiding this comment.
getScopedAndIgnoredPackages maybe? :/
I'll have a think of a better name
There was a problem hiding this comment.
Or maybe something along the lines of applyFilteringRules or something. Yeah, naming is hard. :(
There was a problem hiding this comment.
If filterPackages isn't used elsewhere maybe it should be private like _filterPackages and make this method filterPackages
| - `lerna`: the current version of Lerna being used. | ||
| - `version`: the current version of the repository. | ||
| - `publishConfig.ignore`: an array of globs that won't be included in `lerna updated/publish`. Use this to prevent publishing a new version unnecessarily for changes, such as fixing a `README.md` typo. | ||
| - `bootstrapConfig.ignore`: an glob that won't be bootstrapped when running the `lerna bootstrap` command. |
There was a problem hiding this comment.
Should we mention scope here too?
There was a problem hiding this comment.
Ah, I think my original intention was to remove the the scope from bootstrapConfig as it didnt exists previously and I wasnt sure if that was a deliberate choice or not.
Happy to defer to the maintainers though, adding docs for scope here (I have a feeling it would be a rare usecase?) or removing the scope functionality I added here.
There was a problem hiding this comment.
I think between (1) functionality consistency and (2) the fact that there is a use-case for "permanent" ignore rules, supporting permanent scope rules is a good idea. Principle of least surprise, and all that.
|
|
||
| get packageGraph() { | ||
| if (!this._packageGraph) { | ||
| this.buildPackageGraph(); |
There was a problem hiding this comment.
Shouldn't these be called with arguments? I see buildPackageGraph is called in runPreparations, but that seems a bit like spooky action at a distance.
Perhaps Repository should only cache packages/packageGraph and filtering should be performed explicitly by the task that wants to filter (i.e. Command, as it does now).
There was a problem hiding this comment.
Hmmm.. I liked the idea of pulling the filtering out of the commands just to make them consistent. Maybe these getters should each take optional { scope, ignore } flags?
There was a problem hiding this comment.
Honestly it was done like this to match asini's PR (which originated from here), so I'd be happy for it to be either way
There was a problem hiding this comment.
So the big argument against this structure is that these are getters, but depending on the order that you invoke repository.packageGraph and repository.buildPackageGraph(...), you can end up with permanently different values for packageGraph (or one of the other fields controlled by this). Spooky!
There's also a hand-wavier argument about who should be responsible for filtering; I figured that the "Repository" class should probably be a predictable, consistent, immutable representation of the state of the repo, and filtering should be applied elsewhere, namely, in the commands themselves. If you just pulled out the filtering behavior of buildPackageGraph to the root Command you should still get it across commands, yeah?
Lastly, you can't pass arguments to getters!
There was a problem hiding this comment.
@lukebatchelor please fix the above before merging!
There was a problem hiding this comment.
Cool, ended up doing exactly what you said and moved the responsibility in PackageUtilities and it only gets called in one place still (Command.js).
Much better!
|
Sorry this was left around, rebase and I'll merge |
…strap, exec, run, clean and ls commands
…clean and bootstrap commands
… responsibility from Repository
d11fff8 to
f14420a
Compare
|
Rebased and refactored. Just hoping Appveyor decides to play nicely today... ... |
|
@seansfkelley Wold you be able to do a quick review of this if you have time? |
|
Ah, has to be an owner. Could you take a look when you're ready @thejameskyle ? |
|
@thejameskyle Just bumping this again. When you're free, cheers! |
|
@thejameskyle I've also updated the follow up to this #390 and that should be ready to go too. Cheers 🍻 |
gigabo
left a comment
There was a problem hiding this comment.
This LGTM. It wound up nicer than the Asini version. :)
@lukebatchelor It's fallen out of date with master again. One more rebase?
|
Thanks @lukebatchelor merging should be fine. Going to squash it onto master either way. 👹 FWIW the "fix each conflict of each commit manually" thing is actually a feature of rebasing. It allows the resulting commits to apply cleanly on top of the new base for a linear history. It can be a pain when there are a lot of them, but sometimes I find it's actually easier to see how they should be resolved when they pop up in the context of the individual commits that introduced them. So, in Asini we followed this change set up with asini/asini#15 and then asini/asini#18. Would you be interested in/willing to port those over here? 😁 |
|
This thread has been automatically locked because there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
Some refactoring to make --scope and --ignore more consistent across commands.
Fixes #383