---
title: Exec Command
description: Learn more about the `exec` command in Melos.
---

# Exec Command

<Info>Supports all [Melos filtering](/filters) flags.</Info>

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 ."
```

<Info>
  Since the output is only printed once all packages have finished, nothing is
  printed while the command is running.
</Info>

## --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`](/configuration/overview#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`](/commands/clean) removes them.

<Info>
  The checksum of the files in the package itself is calculated after the
  command has finished, so that files generated by the command, which also
  match the sources, do not make the package look changed the next time.
  Changes that are made to these files while the command is running are
  therefore not noticed.
</Info>

<Warning>
  A command that generates files that match the sources, such as code
  generation, should be combined with `--order-dependents`, or
  [`orderDependents`](/configuration/scripts#orderdependents) in a script, so
  that it finishes in the dependencies of a package before it starts in the
  package. Otherwise a package can be run or skipped based on files that the
  command is still generating in a dependency. Melos detects this, prints a
  warning and runs the command in the package the next time.
</Warning>

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.

<Warning>
  Only the files that match the sources are taken into account. Melos does not
  notice a changed environment variable, a new version of a tool or a changed
  file outside of the sources. Use
  [`--run-unchanged`](#--run-unchanged) in these cases.
</Warning>

## --run-unchanged

Run the command in every package, even in the packages in which the files
matching [`--sources`](#--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`](#--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`](#--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`](/configuration/overview#ignoresources) or the
[`MELOS_IGNORE_SOURCES`](/environment-variables#melos_ignore_sources)
environment variable. Use `--no-ignore-sources` to take them into account
regardless.
