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

Consolidation of multiple similar libraries #10

Open
keithamus opened this issue Oct 16, 2015 · 43 comments
Open

Consolidation of multiple similar libraries #10

keithamus opened this issue Oct 16, 2015 · 43 comments

Comments

@keithamus
Copy link

Hi @mysticatea and @k88hudson! Thanks for your hard work with npm-run-all!

I maintain a similar library - the functionality is slightly different but it shares a lot of common functionality with npm-run-all. My library is called parallelshell - which I maintain with @paulpflug. I am also aware of a few other libraries that attempt to solve the problem of properly parallelising npm (or shell) tasks:

We're all trying to reach the same goal - run npm tasks quickly and easily in parallel (and sometimes serially), and have them log & exit in ways you'd expect. For the most part, each of us (I presume) has convergently developed these solutions. While it's great that we're all solving this problem, its bad that we're all solving it...

The point

I think we should combine forces, to make one canonical parallelisation tool. Personally, I see no point in continuing development of both parallelshell and npm-run-all - we may as well just have one. Having said that, I'm still using parallelshell because it solves particular bugs that I (and @paulpflug) have solved (with great pain) which npm-run-all is yet to solve.

The way I see it - I'm happy (as long as @paulpflug is) to port the fixes we have developed in parallelshell, over to npm-run-all rather than expend effort developing the features I want from npm-run-all inside of parallelshell. I dont want to speak for all other developers (@paulpflug, @kimmobrunfeldt, @luv2code, @royriojas, @spion, and @reggi) - but I for one would certainly like for all of these projects to consolidate under one label. If and when these projects converge, I'd like everyone of the original authors/contributors to be a contributor of the new project - to ensure that it remains well maintained. How does this sound to you?

FYI, I chose to file this issue here - rather than any of the other projects - because I think this project has the best name. By and large they are pretty much all interchangeable (or certainly could be with a bit of development).

Summary

  • npm-run-all and parallelshell are very similar (as are other projects)
  • We should develop one
  • (IMO) All of the maintainers of the other projects should all be core contributors of this project, and deprecate their respective projects.
  • Everyone is happy and users have one well developed tool to chose from.
@luv2code
Copy link

I'm okay with unifying into this project.

@paulpflug
Copy link

👍

@spion
Copy link

spion commented Oct 16, 2015

Yeah, I just figured out #6 :(

I was thinking of writing an alternate implementation that uses the data from package.json but doesn't rely on npm run at all - especially given that npm run seems to be so slow (or is it just slow for me?)

In any case, I agree it would be best if the effort was concentrated, but personally I'm not sure what the direction should be...

@mysticatea
Copy link
Owner

Wow, really interesting.
I am grateful for your proposal.
I'd like to cooperate to make helpful tool for developers!

@spion I feel npm run is slow too. So I have been thinking that directly-spawn content of npm tasks. But it's very hard....

@royriojas
Copy link

👍 happy to merge, help or document :), I guess #6 is an issue that most of us have faced at some point, probably the most important thing a library that runs several things in parallel should have.

@keithamus
Copy link
Author

I would definitely say spawning from the package.json, rather than npm run is a good idea. parallelshell has been working on solving the problem of properly killing subshells and the processes running in them, and we have darkguy2008/parallelshell#30 which is going pretty well thanks to @paulpflug. I think we could take this and turn it into a PR for npm-run-all.

Not depending on npm run as an executable also opens us up to the ability to have npm-run-all run arbitrary scripts, not just npm ones - perhaps with a -e flag (e.g. npm-run-all build:* --sequential -e 'echo "done!"').

Also I think it'd be a good idea to see how npm run itself works. Here's the run-script command which mostly builds up which scripts to run (e.g. pre and post prefixes) - L159-167 build up the commands to run, and L166 is what each command runs (i.e. it calls the lifecycle command with the package json, command, working directory and true). lifecycle.js is basically all of the execution magic, including making all of the env vars, building the shell string and actually running the command. When it all comes down to it, all npm run is essentially doing export ${lots_of_env_vars}; sh -c ${npm_script_string}.

I would be interested in @othiym23 and @isaacs opinions about possibly modularising some of this - so we can all re-use the same piece of code for execution logic. They may well also have some insight for us as they wrote most of npm's lifecycle.js 😄 (although most of that code is 5 years old and so I'd understand if they've forgotten).

@kimmobrunfeldt
Copy link

I too think that merging these projects makes sense. One comment about the naming though. I chose a general name because concurrently is not tied to npm run scripts, you can also use the tool for any shell command.

@paulpflug
Copy link

How about we make 2 packages. the first focusing on sequential and parallel shell execution (name maybe 'parallelshell') and the second focusing on launching npm tasks (grep from project.json or similar)) while depending on the first for execution (name maybe 'npm-run')

I think that would be super transparent for the users and limits the necessary flag count.

@keithamus
Copy link
Author

I agree, that sounds like a good idea.

@reggi
Copy link

reggi commented Oct 18, 2015

Thanks @keithamus for putting this together. I love this idea. I too think that this should have a more general name and not be npm specific. Just to play devils advicate, I'd love this all to be within one project with special flags for npm specific functionality (e.x. --npm-run or --pkg-glob) , just a thought. I embrace a clean / clear UNIX based design, but keeping in mind that we're all node.js developers and that whatever this thing ends up being is going to be very tied to that ecosystem is important. However two commands as @paulpflug describes also makes sense. 👍. With all that said I'm looking forward to seeing this through and would love to help in any capacity.

@reggi
Copy link

reggi commented Oct 20, 2015

Just found these projects that touch on this stuff.

@k88hudson
Copy link
Contributor

Hey everyone, awesome to see this coming together 👍 npm scripts for the win!

Personally I see two separate but related goals here;

  1. To run tasks in parallel in a way that works on all platforms
  2. To provide a better syntax for organizing and running npm scripts or groups of npm scripts

Obviously Windows compatibility is a goal for both 1 and 2, so some code/ideas could be shared, but I would prefer to see them remain separately focused on their respective goals.

If anyone is interested, I know some people on npm/who work on the cli and I would be happy to reach out if they have suggestions, or if any of you want to provide some feedback.

Thanks so much @keithamus for opening this issue and for linking to everyone's projects, you are all awesome 💃 I'm giving another talk on npm scripts at View Source conf in November, and I can tell you more and more people are getting excited about doing front end automation this way thanks to your work and blog posts 😄

@k88hudson
Copy link
Contributor

In fact, I will definitely bring this up with the folks at npm. Thanks also @mysticatea for writing this :)

@keithamus
Copy link
Author

Hey @k88hudson! Thanks for the kind words. I definitely think feedback from the peeps at npm would help here.

Aside; @k88hudson I watched your (absolutely excellent) npm talk at Nordic.js which led me to npm-run-all and prompted this issue. Small world 🌏!

@paulpflug
Copy link

I thought about it a while, here is what I want:

  • one project - three cli's
  • the commands should be short and make no flags necessary in default mode
  • run-seq / run-para for running whatever in parallel or sequential
    (mainly for use in package.json, e.g.: {"scripts":"{"first":"run-seq 'echo 1' 'echo 2'"})
  • run-npm as a drop-in replacement for npm run with wildcards as a main feature. On console: run-npm watch:* would call all scripts starting with watch: in parallel. Calling run-npm watch should act as a shorthand for npm-run watch:* (yes I really want to save that line "watch":"Call all other watches" in package.json)
    Sadly npm-run is already taken.
  • advanced scripts featuring placeholders (example for package.json: {"adv-scripts":"first":"ENV=%1 echo %2"}, would be called this way npm-run first VAR1 'hello world')
    This will make it possible to create meta package.json, which holds scripts for several other projects: {"adv-scripts":"git:push":"cd %1 && git push"}
  • coffee-script - or anything else without curly brackets .. I hate them, mainly because of the german keyboard layout ;)

In my eyes a unsolved problem of all project-processing methods is to handle several projects. The worst case: Say I researched recently and found a new postprocessing tool far better than the other tool I used in 5 of my projects and now I want to migrate...
But even simple tasks like "bump the version of 4 projects and push them to github" is difficult.

Maybe we could collect what all others want and start putting a feature list together - so the development can start 😄

@keithamus
Copy link
Author

  • one project - three cli's
  • the commands should be short and make no flags necessary in default mode
  • run-seq / run-para for running whatever in parallel or sequential (mainly for use in package.json, e.g.: {"scripts":"{"first":"run-seq 'echo 1' 'echo 2'"})

On the surface this idea seems good; because having a mix of flags is a bit of a pain, and a bit hard to disambiguate. However when you consider the power of npm-run-all chaining multiple commands, you can see that npm-run-all currently does a better job:

$ npm-run-all --sequential a b c --parallel d e f --sequential g h i
# To do this with three commands:
$ run-series a b c && run-parallel d e f && run-series g h i
# Or
$ run-series 'run-sequential a b c' 'run-parallel d e f' 'run-sequential g h i'

I have some tasks in a project right now which are mix of sequential and parallel (build all the things, then watch the output with several tools and serve html all at once). npm-run-all facilitates this in - what I think - the easiest way possible.

Having said that I think it could end up being pretty hairy having command line, npm, sequential and parallel all wrapped in one lib. How about the following instead:

  • One project, two clis

  • The two commands are run-all and npm-run-all

  • run-all takes a set of strings, which are shell commands, and --series and --parallel commands which behave much like npm-run-all does now.

    $ run-all 'echo hello' 'echo world'
    hello world
    $ run-all 'sleep 1 && echo hello' 'echo world'
    hello world
    $ run-all --parallel 'sleep 1; echo hello' 'echo world'
    world hello
    $ run-all 'echo 1' --parallel 'sleep 2; echo 2' 'sleep 1; echo 3' 'echo 4'
    1 4 3 2
  • npm-run-all works pretty much as it always did; it matches the behaviour of run-all except it calls aliases for npm-scripts:

    $ npm-run-all test:* build:* --parallel watch:*
  • run-npm as a drop-in replacement for npm run with wildcards as a main feature. On console: run-npm watch:* would call all scripts starting with watch: in parallel. Calling run-npm watch should act as a shorthand for npm-run watch:* (yes I really want to save that line "watch":"Call all other watches" in package.json) Sadly npm-run is already taken.

I like the idea of npm-run watch defaulting to an alias for npm-run watch:* but we should make sure it is overridable. I imagine the logic to be a bit like this:

if packageJson.watch
  run packageJson.watch
elseif !packageJson.watch && packageJson.watch:*
  run --series packageJson.watch:*
  • advanced scripts featuring placeholders (example for package.json: {"adv-scripts":"first":"ENV=%1 echo %2"}, would be called this way npm-run first VAR1 'hello world') This will make it possible to create meta package.json, which holds scripts for several other projects: {"adv-scripts":"git:push":"cd %1 && git push"}

I'm going to disagree with this on a few points:

  • I think package.json#config is sufficient for metadata (although the environment variable is a little on the verbose side for my liking: $npm_package_config_<thing>).
  • If a package is so complex that it requires many config vars, it should probably be a script.
  • I think we need to be careful about exactly what we're implementing here. To me - the core feature set is "run commands in parallel in a cross compatible way" and "use that as a basis to quickly orchestrate a set of npm scripts". IMO anything else is scope-creep.
  • coffee-script - or anything else without curly brackets .. I hate them, mainly because of the german keyboard layout ;)

Ew no! Babel or bust!

In my eyes a unsolved problem of all project-processing methods is to handle several projects. The worst case: Say I researched recently and found a new postprocessing tool far better than the other tool I used in 5 of my projects and now I want to migrate...
But even simple tasks like "bump the version of 4 projects and push them to github" is difficult.

I agree, this is a problem (well, for my work its managing hundreds of components and keeping everything up to date and standardised across the board). I think this is an orthogonal problem though - mostly one of provisioning and less about orchestrating tasks.

@mysticatea
Copy link
Owner

I like the idea of run-all and npm-run-all.
The collection of small programs is definitely good, but package.json#scripts field has small area, so I'd like to keep compact notation of this tool.

coffee-script - or anything else without curly brackets .. I hate them, mainly because of the german keyboard layout

I was surprised by the location of brace's keys!
But this tool has many asynchronous loops, so I'd like to use async/await (an ES stage 3 proposal).

BTY, I think we should be looking at npm/npm#9970 .
I'm thinking maybe we should change the separator of Glob-like patterns of npm-run-all.


Though I will add collaborators of this repository, may I add all people who is joining this conversation?

And there are requests about making changes.

  • Doesn't commit changes to the master branch directly.
  • Creates a PR then other members review it.

@kimmobrunfeldt
Copy link

I like @paulpflug's idea of having separate CLI commands for parallel and sequential run.

In @keithamus' example:

$ npm-run-all --sequential a b c --parallel d e f --sequential g h i
# To do this with three commands:
$ run-series a b c && run-parallel d e f && run-series g h i
# Or
$ run-series 'run-sequential a b c' 'run-parallel d e f' 'run-sequential g h i'

I like 2nd(this is not an option because lack of windows support) and 3rd more because they explicitly state which steps are run sequentially and which are run parallel. The 1st command has implicit hidden information: all those substeps are run sequentially.

@keithamus
Copy link
Author

I think we have enough to get a prototype going. I'm going to make some time this weekend to get a first draft done and we can all see where to go from there.

@twhitbeck
Copy link

This sounds really good. Has there been any development on this? I'm currently using npm-run-all because it seems like it is going to be the destination project for all these similar efforts. The "one cross-platform, parallel script runner to rule them all". Any way I can help?

@corysimmons
Copy link

@keithamus Good on you for opening this Issue and burying your lib in exchange for working together for an even better one. GitHub needs more developers like you. 👍

Also, thank you for your article on switching to npm. I just made the switch because of it and it's beautiful over here.

Now if you'll excuse me, I have to go build yet another grid system to pollute the sea of grids with... :(

@mysticatea Oh and good job on this. Works like a charm!

@keithamus
Copy link
Author

Thanks for the kind words @corysimmons.

I know I said I'd get a draft done a couple of months ago - things got a bit in the way, but rest assured it is on my todo list (item number 3 😉) so I'll be pushing some code soon.

@paulpflug
Copy link

hey,

Because I needed more functionality, I created a tool yesterday. Now it is finished with unit tests but without much documentation yet.
Haven't run the tests on windows, though.

So here is the spawn wrapper better-spawn with all the things I learned from parallelshell.

And here the script-runner

Usage

usage: run [<options> [cmd..]..]

options:
-h, --help         output usage information
-v, --verbose      verbose logging (not implemented yet)

    --silent       suppress output of children
-t, --test         no runing only show process structure
-s, --sequential   following cmds will be run in sequenz
-p, --parallel     following cmds will be run in parallel
-i, --ignore       the following cmd will be ignored for --first, --wait and errors
-f, --first        only in parallel block: close all sibling processes after first exits (succes/error)
-w, --wait         only in parallel block: will not close sibling processes on error
-m, --master       only in parallel block: close all sibling processes when the following cmd exits. exitCode will only depend on master
-f, --first        close all sibling processes after first exits (succes/error)

run also looks in node_modules/.bin for cmds
run-para is a shorthand for run --parallel
run-seq is a longhand for run
run-npm will match cmd with npm script and replace them, usage of globs is allowed

run-npm currently uses minimatch, but I'm not fully statisfied

I thought about templating of scripts:
Say we have a script "test":"mocha :'1'"

npm run test # would run mocha
npm-run test # would run mocha
npm-run test(--watch) # would run mocha --watch

It would be not to hard to implement, but I can't think of a use case currently

@josh-endries
Copy link

Sorry to butt in. I came across parallelshell from an adventure in building with VS Code. It didn't work, so I went to its site, which led me here. Anyway...

Quoth the @kimmobrunfeldt:

In @keithamus' example:

$ npm-run-all --sequential a b c --parallel d e f --sequential g h i
# To do this with three commands:
$ run-series a b c && run-parallel d e f && run-series g h i
# Or
$ run-series 'run-sequential a b c' 'run-parallel d e f' 'run-sequential g h i'

I like 2nd(this is not an option because lack of windows support) and 3rd more because they explicitly state which steps are run sequentially and which are run parallel. The 1st command has implicit hidden information: all those substeps are run sequentially.

I'm confused as to your Windows comment. Using && works the same for me in Windows as it does in Unix/Linux--it runs the commands in series if the previous command succeeded. Maybe it changed with recent versions of Windows... What doesn't work the same is &. Also, what is the difference between run-series and run-sequential in the above example? Couldn't you just do run-sequential 'run-sequential a b c' 'run-parallel d e f' 'run-sequential g h i'? Honestly, with &&, I'm not sure run-series is even necessary, that's what && does (technically, that's what ; on Unix/Linux and & on Windows does; && also checks exit codes). I believe that the third command is irrelevant because of this.

I agree that the first command is bad in that it includes an implicit behavior, another reason I prefer the second example. I would suggest that, if you boil this down to one command with aliases, that the one command considers --sequential and --parallel mutually exclusive. Having used commands with ordered parameters in the past, it can easily become a PITA, requires additional knowledge, is more error-prone and isn't very intuitive, IMHO.

The second command, however, does brings up a question: what to do with exit codes (if anything)? None of these examples use || in case one (or more? or all?) of the parallel commands fails. This is where I think the decomposition and flexibility in the second example really shows its value. For example, imagine something like this (which isn't great, I just tried to make it more realistic than a b c):

run-series clean initEmail
    && run-parallel --must-succeed build 'sendEmail --subj="building \"${projName}\"" foo@bar.com'
    && run-series --any-must-succeed 'minify -d app/js -r "^.*\\.js"' imgify
        && run-parallel emailDev emailMgrs
        || run-series pkgErr emailDev

Although, since run-series is (so far, as I understand it) redundant, this could really be:

npm run clean && npm run initEmail
    && npm run-all --all-must-succeed build 'sendEmail --subj="building \"${projName}\"" foo@bar.com'
    && npm run minify -- -d app/js -r "^.*\\.js" && npm run imgify
        && npm run-all --any-must-succeed emailDev emailMgrs
        || npm run pkgErr && npm run emailDev

I could see needing run-series in order to bridge the gap between ; and & to allow users to run commands cross-platform in series regardless of exit code.

Lastly, I am very glad you all agreed to combine your efforts. There is way too much fragmentation and duplication of purpose and effort these days.

@paulpflug
Copy link

I think we can agree this is a difficult topic.. we only have 1 line, no syntax highlighting and ' as an indicator for nesting.

With npm run we can get hold on the 1 line and nesting problem. But with the syntax we have a clear tradeoff between verbosity and clarity. I think the best way is to offer both possibilities..

I'm strongly for ordered parameters as &&, || and all other also have a significant order and everything else would be confusing.

So for you example, I think a desireable syntax would be:

run-npm clean initEmail buildAndEmail minify --any emailDev emailMgrs --on-error pkgErr emailDev

with all nested commands hidden behind own npm scripts.

@kievechua
Copy link

Hi all, may I know what's the status of the consolidation of all projects?
Is there any possibility to create a Github organization and put all related repos in there?

roc pushed a commit to roc/hof-example-form that referenced this issue May 31, 2016
…l as the former has been deprecated in favour of the latter

See issue mysticatea/npm-run-all#10

* Removed parallelshell and added npm-run-all
* Added a new watch:app npm script which sets NODE_ENV to development and starts nodemon in current directory
* Altered dev npm script to run npm-run-all with `--parallel` flag, this concurrently runs tasks `watch:app`, `watch:scss`, `watch:js` and `watch:translations`
@mitermayer
Copy link

Which project is the one where you are all merging into ?

@amelon
Copy link

amelon commented Jul 7, 2016

it's npm-run-all.

@kimmobrunfeldt
Copy link

I'm confused as to your Windows comment. Using && works the same for me in Windows as it does in Unix/Linux--it runs the commands in series if the previous command succeeded. Maybe it changed with recent versions of Windows...

Ok thanks for clarifying, I wasn't sure as I haven't used a windows shell for a while.

@lukeramsden
Copy link

Any update on this?

@xaviergonz
Copy link

Slightly different and slightly related, a project I recently made:
makfy

@BobbyBabes
Copy link

@keithamus Has npm-run-all already become the one canonical parallelisation tool that you proposed ?

@keithamus
Copy link
Author

Yes I would say so. Sadly I didn't get any time to work on it 😊 but I'd say it's now the tool I wanted parallelshell to be.

@BobbyBabes
Copy link

That's awesome to hear. Great collaboration.
The sad thing is though that I'm going to use npm-run-all now.

Sadly I didn't get any time to work on it 😊

Well I don't understand that you guys have/find the time to build all these tools and maintain and support it. I must be a lot slower, or just less productive.
Currently rereading your article "How to use npm as a build tool", to rewrite my obnoxious large Gulp and Grunt scripts. Thanks for that too.

@reggi
Copy link

reggi commented Nov 13, 2017

From @pygy https://github.com/pygy/gosub

What does it have over npm-run-all? It passes parameters to subtasks. That's all. It doesn't take any options and can't run tasks in parallel unlike npm-run-all.

@exalted
Copy link

exalted commented Nov 30, 2017

@kimmobrunfeldt commented on Oct 17, 2015:

[…] because concurrently is not tied to npm run scripts, you can also use the tool for any shell command.

Is this goal achieved in this consolidation? As the name of this package suggests, I think, this is still pretty much tied to npm scripts. Am I wrong?

Thanks. 🙏

@stereokai
Copy link

Is the consolidation of all these projects into one megarepo still taking place? Cheers!

@pygy
Copy link

pygy commented Jan 14, 2018

Hi all I had originally missed this thread. I wrote gosub to scratch an itch (running subscripts in a npm/yarn-agnostic fashion), I didn't know that npm-run-all was doing it as well.

I'll probably keep using it for my libs given how simple it is (no options, does exatcly what I want), but I can add a banner at the top of the README pointing to whatever the meta-project ends up being.

@roblav96
Copy link

roblav96 commented Mar 2, 2019

Set exec to a script:

"scripts": {
	"exec": "exec",
	"dev": "del dist; run-p 'exec -- tsc -w' 'exec -- nodemon'",
},

👍

@KrishnaPG
Copy link

How to use this, to start multiple projects? For example, something like

Root
 |-- server/package.json
 |-- client/package.json
 |-- ui/package.json

Need to start the server, client and ui projects all - does this project solve that problem? how to achieve it?

@mightyiam
Copy link

@KrishnaPG, it seems that your question is unrelated to this issue. Non-the-less, I'll try to help you. Try the run-p command. If you have any more questions, please open a new issue and tag me in it.

@trusktr
Copy link

trusktr commented May 5, 2020

I recently stumbled on something similar to the tools listed in the OP, but the one I found automatically took each command and multiplexed it into a configurable layout (like tmux terminal multiplexer).

The layout was specified in package.json of a project. It was really neat, because it would show each command's output separately in their own sub-panels.

But I can not find this package. I should've saved it!

EDIT: Okay, I found this: https://www.npmjs.com/package/multiplerun. That's similar to what I stumbled on before, but that one is specifically for use with iTerm in macOS. The one I had stumbled on was pure Node.js (I think) and would therefore run in any OS, in any terminal.

EDIT: There's also https://www.npmjs.com/package/stmux, but it isn't the one I found before.

@mightyiam
Copy link

@trusktr searching for tmux on npm I found this: https://www.npmjs.com/package/multiview

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests