Exec Command

Execute an arbitrary command in each package.

bash
melos exec
# e.g. melos exec -- pub global run tuneup check

The command is executed in a shell. On Windows the shell is cmd.exe and on all other platforms it is sh.

If multiple commands are being executed and no further commands should be executed after a command has failed, connect the commands with &&:

shell
melos exec -- "melos bootstrap && melos run build"

It is important to pass multiple commands as a single string to melos exec, otherwise the shell will pass only the first command to melos exec.

dart test and flutter test exit with the exit code 79 when no tests ran, for example when no tests in a package match the requested --tags. Melos treats this exit code as a success, so that packages without matching tests do not fail the command or trigger --fail-fast:

shell
melos exec --fail-fast -- "flutter test --tags integration"

concurrency (-c)

Defines the max concurrency value of how many packages will execute the command in at any one time. Defaults to 5.

bash
# Set a 1 concurrency
melos exec -c 1  -- "dart analyze ."

--fail-fast

Whether exec should fail fast and not execute the script in further packages if the script fails in an individual package. Defaults to false.

bash
# Fail fast
melos exec --fail-fast -- "dart analyze ."

--group-logs

When executing a command in multiple packages concurrently, the output of the packages is streamed as it is produced, which means the logs of the different packages are interleaved and hard to follow.

With --group-logs, the output of each package is buffered instead and printed once every package has finished, grouped per package and in the order the output was produced. Packages in which the command failed are printed last, so failures are at the end of the log where they are easy to spot. Defaults to false.

The flag only has an effect when the command runs in more than one package with a concurrency greater than 1. When the command runs in a single package or with --concurrency 1, the output cannot interleave in the first place, so --group-logs is a no-op and the output is streamed as usual.

bash
# Print the output grouped per package, once all packages have finished
melos exec --group-logs -- "dart analyze ."

--sources

Globs, relative to the root of each package, that match the files the result of the command depends on. Melos stores a checksum of the matching files in every package in which the command succeeds, and skips the package the next time the same command runs if none of the files changed. The option can be specified multiple times.

bash
# Only generate code in the packages in which the Dart files or the pubspec
# changed since the last successful run
melos exec --order-dependents --sources "lib/**.dart" --sources "pubspec.yaml" -- "dart run build_runner build"

A glob that matches a directory, such as lib, also matches all of the files inside of it. A glob can also match files outside of the package, for example ../../pubspec.lock for the lock file of the workspace in a package that is located in packages/<name>. Melos prints a warning for a glob that does not match a file in any package, since that usually is a mistake.

The checksum of a package also covers the matching files of all of its dependencies in the workspace, because the result of a command such as code generation can depend on them. A change in a package therefore makes the command run again in every package that depends on it. Packages that are excluded from the workspace with ignore are not taken into account.

A package in which the command fails is not considered up to date, so the command runs in it again the next time. The packages that depend on it are not affected by that, as long as its files did not change.

The checksums are stored in .dart_tool/melos/fingerprints inside of each package, separately for every combination of command and sources. melos clean removes them.

Commands that do not change the sources, such as running tests or the analyzer, do not need to be ordered and keep running in all packages concurrently.

--run-unchanged

Run the command in every package, even in the packages in which the files matching --sources did not change. The checksums of the packages in which the command succeeds are still updated.

bash
melos exec --run-unchanged --sources "lib/**.dart" -- "dart run build_runner build"

--ignore-sources

Ignore --sources, so that the command runs in every package without calculating or storing checksums. This is useful where the checksums are never reused, for example on a continuous integration server that starts from a fresh checkout, since it avoids reading all of the source files.

bash
melos exec --ignore-sources --sources "lib/**.dart" -- "dart test"

In contrast to --run-unchanged, no checksums are stored. The stored checksums of the packages that the command runs in are removed, so the command also runs in them the next time that the sources are taken into account.

The sources can be ignored for the whole workspace with command/exec/ignoreSources or the MELOS_IGNORE_SOURCES environment variable. Use --no-ignore-sources to take them into account regardless.