Skip to content

Commit 2dfbeaa

Browse files
author
Noam Gottlieb
committed
feat: Added dry-run flag to pixi run + docs + test
1 parent b0288d6 commit 2dfbeaa

File tree

3 files changed

+45
-0
lines changed

3 files changed

+45
-0
lines changed

docs/reference/cli.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,7 @@ You cannot run `pixi run source setup.bash` as `source` is not available in the
297297
- `--concurrent-downloads`: The number of concurrent downloads to use when installing packages. Defaults to 50.
298298
- `--concurrent-solves`: The number of concurrent solves to use when installing packages. Defaults to the number of cpu threads.
299299
- `--skip-deps`: Skip the dependencies of the task, which where defined in the `depends-on` field of the task.
300+
- `--dry-run (-n)`: Run the task in dry-run mode (only print the command that would run)
300301

301302
```shell
302303
pixi run python
@@ -310,6 +311,8 @@ pixi run build
310311
pixi run task argument1 argument2
311312
# Skip dependencies of the task
312313
pixi run --skip-deps task
314+
# Run in dry-run mode to see the commands that would be run
315+
pixi run --dry-run task
313316

314317
# If you have multiple environments you can select the right one with the --environment flag.
315318
pixi run --environment cuda python

src/cli/run.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ pub struct Args {
6666
#[arg(long)]
6767
pub skip_deps: bool,
6868

69+
/// Run the task in dry-run mode (only print the command that would run)
70+
#[clap(short = 'n', long)]
71+
pub dry_run: bool,
72+
6973
#[clap(long, action = clap::ArgAction::HelpLong)]
7074
pub help: Option<bool>,
7175

@@ -151,6 +155,18 @@ pub async fn execute(args: Args) -> miette::Result<()> {
151155

152156
tracing::info!("Task graph: {}", task_graph);
153157

158+
// Print dry-run message if dry-run mode is enabled
159+
if args.dry_run {
160+
eprintln!(
161+
"{}{}",
162+
console::Emoji("🌵 ", ""),
163+
console::style("Dry-run mode enabled - no tasks will be executed.")
164+
.yellow()
165+
.bold(),
166+
);
167+
eprintln!();
168+
}
169+
154170
// Traverse the task graph in topological order and execute each individual
155171
// task.
156172
let mut task_idx = 0;
@@ -196,6 +212,12 @@ pub async fn execute(args: Args) -> miette::Result<()> {
196212
);
197213
}
198214

215+
// on dry-run mode, we just print the command and skip the execution
216+
if args.dry_run {
217+
task_idx += 1;
218+
continue;
219+
}
220+
199221
// check task cache
200222
let task_cache = match executable_task
201223
.can_skip(&lock_file.lock_file)

tests/integration_python/test_run_cli.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,3 +352,23 @@ def test_run_help(pixi: Path, tmp_pixi_workspace: Path) -> None:
352352
[pixi, "run", "python", "--help"],
353353
stdout_contains="python",
354354
)
355+
356+
357+
def test_run_dry_run(pixi: Path, tmp_pixi_workspace: Path) -> None:
358+
manifest = tmp_pixi_workspace.joinpath("pixi.toml")
359+
toml = f"""
360+
{EMPTY_BOILERPLATE_PROJECT}
361+
[activation.env]
362+
WET_RUN = "WET-RUN-VAR"
363+
[tasks]
364+
dry-run-task = "echo $WET_RUN"
365+
"""
366+
manifest.write_text(toml)
367+
368+
# Run the task with --dry-run flag
369+
verify_cli_command(
370+
[pixi, "run", "--manifest-path", manifest, "--dry-run", "dry-run-task"],
371+
stderr_contains="Dry-run mode enabled",
372+
stdout_excludes="WET-RUN-VAR",
373+
stderr_excludes="WET-RUN-VAR",
374+
)

0 commit comments

Comments
 (0)