Skip to content

[Feature] Adds --scope and --ignore support for bootstrap, exec, run, clean and ls#386

Merged
gigabo merged 12 commits intolerna:masterfrom
lukebatchelor:spike-scope-bootsrap
Dec 13, 2016
Merged

[Feature] Adds --scope and --ignore support for bootstrap, exec, run, clean and ls#386
gigabo merged 12 commits intolerna:masterfrom
lukebatchelor:spike-scope-bootsrap

Conversation

@lukebatchelor
Copy link
Copy Markdown
Contributor

@lukebatchelor lukebatchelor commented Oct 21, 2016

Some refactoring to make --scope and --ignore more consistent across commands.

Fixes #383

@lukebatchelor
Copy link
Copy Markdown
Contributor Author

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. 👍

Comment thread src/Command.js

runPreparations() {
const scope = this.flags.scope || (this.configFlags && this.configFlags.scope);
const ignore = this.flags.ignore || (this.configFlags && this.configFlags.ignore);
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The .configFlags is only set in Bootstrap right now.

Comment thread README.md

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.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(More than happy to change it though, just felt more consistent)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Contributor

@joscha joscha Oct 23, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lukebatchelor When we developed the feature I suggested ignore to trump scope: #168 (comment) - not sure why and when that might have changed.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@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*"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ignore should definitely take precedence over scope.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that's right.

@lukebatchelor
Copy link
Copy Markdown
Contributor Author

@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

@seansfkelley
Copy link
Copy Markdown
Contributor

@hzoo / @thejameskyle can we merge this? Working around/waiting for prepublishing the entire world is making me sad. :(

Comment thread src/PackageUtilities.js Outdated
* @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}) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would perhaps rename this to make it a bit more obviously different than filterPackages.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getScopedAndIgnoredPackages maybe? :/

I'll have a think of a better name

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or maybe something along the lines of applyFilteringRules or something. Yeah, naming is hard. :(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If filterPackages isn't used elsewhere maybe it should be private like _filterPackages and make this method filterPackages

Comment thread README.md
- `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.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we mention scope here too?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added 👍

Comment thread src/Repository.js

get packageGraph() {
if (!this._packageGraph) {
this.buildPackageGraph();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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!

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lukebatchelor please fix the above before merging!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For sure!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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!

@jamiebuilds jamiebuilds changed the title Adds --scope and --ignore support for bootstrap, exec, run, clean and ls [Feature] Adds --scope and --ignore support for bootstrap, exec, run, clean and ls Nov 16, 2016
@jamiebuilds
Copy link
Copy Markdown
Contributor

Sorry this was left around, rebase and I'll merge

@lukebatchelor
Copy link
Copy Markdown
Contributor Author

Rebased and refactored. Just hoping Appveyor decides to play nicely today... ...

@lukebatchelor
Copy link
Copy Markdown
Contributor Author

@seansfkelley Wold you be able to do a quick review of this if you have time?

@lukebatchelor
Copy link
Copy Markdown
Contributor Author

Ah, has to be an owner. Could you take a look when you're ready @thejameskyle ?

@lukebatchelor
Copy link
Copy Markdown
Contributor Author

@thejameskyle Just bumping this again. When you're free, cheers!

@lukebatchelor
Copy link
Copy Markdown
Contributor Author

@thejameskyle I've also updated the follow up to this #390 and that should be ready to go too.

Cheers 🍻

Copy link
Copy Markdown
Contributor

@gigabo gigabo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This LGTM. It wound up nicer than the Asini version. :)

@lukebatchelor It's fallen out of date with master again. One more rebase?

@lukebatchelor
Copy link
Copy Markdown
Contributor Author

😎 Should be ready @gigabo

I merged master instead of rebasing, is that okay? Last time I rebased I had to fix each conflict of each commit manually for some reason. Didnt want to have to do that again for this and #390.

(If anyone knows what I might be doing wrong, that would be great too!)

@gigabo
Copy link
Copy Markdown
Contributor

gigabo commented Dec 13, 2016

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? 😁

@gigabo gigabo merged commit d707386 into lerna:master Dec 13, 2016
@lock
Copy link
Copy Markdown

lock Bot commented Dec 27, 2018

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.

@lock lock Bot locked as resolved and limited conversation to collaborators Dec 27, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants