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

[rush] Add a "rush build" CLI parameter for building a project's dependencies but NOT the project #2354

Closed
RIP21 opened this issue Nov 13, 2020 · 16 comments · Fixed by #2422
Closed
Labels
enhancement The issue is asking for a new feature or design change

Comments

@RIP21
Copy link

RIP21 commented Nov 13, 2020

Summary

Quote from the Zulp discussion:

Hi. What I want to achieve is that there is a flag that enables to build / run some command for all the dependencies of the module, but not the module itself.
I know there is --from which will run command for all modules that are dependent from some package. And --to that will run command for all modules on which module is dependent.
But the problem with it is that both of those commands are including the mentioned module.
What's my use-case? I want to build all dependencies of the particular app, but I don't want to build the app itself, as I first want to run lint, tests, and other commands, and only after everything is good, I want to run build for the app itself. For now, I'm working around that using versions policies that I use as a sort of tag to map library packages as a library and build them all (even tho my app may not use those deps) using --to-version-policy flag.

Maybe the introduction of some tags will be a nice thing?

Link to the discussion: https://rushstack.zulipchat.com/#narrow/stream/262513-general/topic/Build.20deps.20but.20app

Proposed solution by @octogonz was to add --from-but-not or --dependencies-only flags.

I prefer --dependencies-only and --dependents-only flags as they just sound better and kinda easier to understand than --from and --to that are pretty hard to get used to TBH :) --for-dependencies-of and --for-dependents-of or smth similar is a bit more verbose maybe, but IMO easier to get :)

Thanks! Hopefully this will be added soon :)

@octogonz octogonz added enhancement The issue is asking for a new feature or design change needs design The next step is for someone to propose the details of an approach for solving the problem labels Nov 13, 2020
@wbern
Copy link
Contributor

wbern commented Nov 16, 2020

How about --for and --of as aliases?

@iclanton
Copy link
Member

I prefer the --dependencies-only and --dependents-only names as well.

Maybe an --exclude flag? Although that would allow people to construct a command that may be guaranteed to fail. Maybe that's okay?

This is probably a pretty straightforward change once we get the design right.

@octogonz
Copy link
Collaborator

octogonz commented Dec 1, 2020

I'm realizing that I would use this feature heavily.

Suppose you're working on a webpack project:

$ git pull
$ rush install
$ rush build --to web-app
$ heft start

The rush build command above might spend 10 seconds bundling web-app, only to have heft start redo that same work for its watch mode.

An option like rush build --to-but-not web-app would avoid that wasted work. If this is a very common scenario, we should try to make the CLI concise.

@octogonz
Copy link
Collaborator

octogonz commented Dec 2, 2020

We should also consider how the commands would combine. Today you can do:

# Build two different projects
$ rush build --to my-app --to my-service 

For the watch mode scenario, if my-service isn't part of the watch mode, then I might do:

# This isn't possible with a blanket "--exclude"
$ rush build --to-but-not my-app --to my-service 

Or if I'll be doing watch mode for both of them, then I'd want:

# Here I need to specify "-but-not" twice, so it needs to be concise
$ rush build --to-but-not my-app --to-but-not my-service 

Some naming alternatives:

  • rush build --to-but-not project and rush build --from-but-not project
  • rush build --to-excluding project and rush build --from-excluding project
  • rush build --to-except project and rush build --from-except project

Maybe the short names could be -T and -F?

I prefer --dependencies-only and --dependents-only flags as they just sound better and kinda easier to understand

Hmm... The appeal of --from and --to is that they're short words, and they indicate the direction of flow (or so I thought 😁).

If we were using --dependencies and --dependents, would this be alongside other options like --to and --to-version-policy? Or would we rename those options?

How about --for and --of as aliases?

Aliases increase the amount of stuff people need to learn, without adding benefits. If each person uses their preferred set of aliases, then it's more difficult for other people to understand examples or docs that they share.

If we decide that a different name really is more clear, it would be preferable to actually deprecate the old name and eventually remove it, rather than introducing aliases.

@octogonz
Copy link
Collaborator

octogonz commented Dec 2, 2020

After more thought, I'd like to propose this design:

Inclusive:

  • rush build --to my-app with short name rush build -t my-app
  • rush build --from my-app with short name rush build -f my-app

Non-inclusive:

  • rush build --to-except my-app with short name rush build -T my-app
  • rush build --from-except my-app with short name rush build -F my-app

Some issues with other suggestions:

  • --dependencies/--dependents doesn't have a natural short name pattern
  • it also doesn't align with --to-version-policy or other future switches that might follow this naming pattern
  • If --exclude's argument is explicit (rush --to my-app --exclude my-app), that's too much duplication
  • If --exclude's argument is implicit (rush --to my-app --exclude), that cannot handle the mixed case of rush --to-except my-app --to my-service

@octogonz octogonz changed the title [rush] Add --dependecies-only --dependents-only parameters to run commands for all to/from but one. [rush] Add a "rush build" CLI parameter for building a project's dependencies but NOT the project Dec 2, 2020
@iclanton
Copy link
Member

iclanton commented Dec 2, 2020

I like --to-except/-T and --from-except/-F.

@RIP21
Copy link
Author

RIP21 commented Dec 2, 2020

@octogonz I agree that your naming, being slightly confusing at the beginning once you get used to is nice because of its shortness.

Same, I agree on aliasing, that it's nice to keep stuff limited for the sake of consistency and less stuff to support.

Having ability to run rush with 2-3 -tos is critical indeed too (is output of this one got any better? As all except one of the outputs to console was used to be swallowed?) as it's what I'm using a lot. Especially for microfrontends, when I need to run parent and few sibling apps in the same time.

@octogonz
Copy link
Collaborator

octogonz commented Dec 2, 2020

As all except one of the outputs to console was used to be swallowed?

Can you give more detail about this? I'm not sure what you're referring to.

Also have you looked at rush-select? It might help: #2265

@RIP21
Copy link
Author

RIP21 commented Dec 2, 2020

@octogonz if I do rush start -v -f 'one-app' -f 'another-app'
I see the console output only of one-app the another-app is getting swallowed even tho running.

It says

Starting "rush start"

Selected 2 projects:
  one-app
  another-app

Executing a maximum of 16 simultaneous processes...

==[ one-app ]=======================================[ 1 of 2 ]==
... output of one-app ...

But I never see the output of another-app

Maybe I'm doing something wrong? Also is there any shortcuts with -t and -f so I can write not the @company/full-name
but let say just -f name and it will guess as there is no other packages that has word name in it, so it will run it. Or I'm missing something here again? :)

@octogonz
Copy link
Collaborator

octogonz commented Dec 8, 2020

if I do rush start -v -f 'one-app' -f 'another-app'
I see the console output only of one-app the another-app is getting swallowed even tho running.

This problem is unrelated to issue #2354.

What does your rush start custom command do? If it enters an infinite loop (e.g. by invoking heft start for watch mode), then this isn't expected to work. Rush's console stream collator waits for processes to terminate before displaying their output. We could consider generalizing it (i.e. provide a command-line.json setting to indicate "bulk" custom commands that invoke processes that never terminate), but you should create a separate GitHub issue to discuss the design.

However if your goal is more like "the watch mode for Webpack/Jest should work across multiple projects in a monorepo" there's already a specific issue #1202 proposing that. Its solution is much more focused and complex than merely "processes that never terminate." Earlier this summer we agreed on a design that will solve it, but nobody has had time to work on it yet.

Also is there any shortcuts with -t and -f so I can write not the @company/full-name
but let say just -f name and it will guess as there is no other packages that has word name in it, so it will run it.

You can omit the NPM scope, e.g. write rush build -f full-name instead of rush build @company/full-name. But it can't be shortened to just name.

@dmichon-msft
Copy link
Contributor

I'm working on a prototype of this at present because I will need it to approach #1202 / #1122.

What would be the expected behavior of:

rush build --to-except A --to-except B

If A depends on B?

  1. This is an error
  2. We exclude B and all projects that depend on it, even if they are also dependencies of A
  3. We exclude B but still build projects that depend on it if they are also dependencies of A
  4. We build B anyway

I'm not entirely clear on if (2) or (3) makes the most sense.

I'm also looking to change the behavior of:

rush build --from A --to B

To mean "build all projects between A (inclusive) and B (inclusive)" instead of the current "build the union of all projects that depend on A and all projects that depend on B"

@octogonz octogonz removed the needs design The next step is for someone to propose the details of an approach for solving the problem label Jan 11, 2021
@RIP21
Copy link
Author

RIP21 commented Jan 23, 2021

Can't wait for this feature to be merged :)

@octogonz
Copy link
Collaborator

FYI the PR raised some unexpected design questions. An entire meeting was dedicated to that topic on Thursday 🙂, which straightened everything out, so it should get merged very soon.

@octogonz
Copy link
Collaborator

We had a long design discussion about this today.

Here's the final spec that we came up with:

rush build --to project
rush build -t project

rush build --to-except project
rush build -T project

rush build --from project
rush build -f project

rush build --only project
rush build -o project

rush build --impacted-by project
rush build -i project

rush build --impacted-by-except project
rush build -I project

# And this command's short name is changed from "-o" to "-c" to avoid conflicting with "--only":
rush build --changed-projects-only
rush build -c 

With this design, --from now builds all dependencies. And --impacted-by is the weird special case that means "Build X and any projects that might be broken by changes to X, but not their dependencies."

@RIP21
Copy link
Author

RIP21 commented Feb 1, 2021

@octogonz when it will be published BTW? :)

@octogonz
Copy link
Collaborator

octogonz commented Feb 2, 2021

It was released with Rush 5.38.0

@iclanton iclanton moved this to Closed in Bug Triage Aug 15, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement The issue is asking for a new feature or design change
Projects
Archived in project
Development

Successfully merging a pull request may close this issue.

5 participants