From 526f05cb201612b3267c86d3fc95aaa4603d6590 Mon Sep 17 00:00:00 2001 From: Brandon Maier Date: Mon, 16 Dec 2024 08:32:25 -0600 Subject: [PATCH] feat: support --manifest-path to project directory Allow `pixi --manifest-path ` to accept a path to a project directory. This makes it easier to use pixi when scripting as the script does not need to know if a project is using pixi.toml or pyproject.toml. Implements: https://github.com/prefix-dev/pixi/issues/2706 --- src/cli/cli_config.rs | 2 +- src/cli/completion.rs | 2 +- src/cli/project/description/mod.rs | 2 +- src/cli/project/environment/mod.rs | 2 +- src/cli/project/platform/mod.rs | 2 +- src/cli/project/version/mod.rs | 2 +- ...__completion__tests__nushell_completion.snap | 2 +- src/project/mod.rs | 17 +++++++++++++++-- 8 files changed, 22 insertions(+), 9 deletions(-) diff --git a/src/cli/cli_config.rs b/src/cli/cli_config.rs index a6fbd84bd8..398f49c65e 100644 --- a/src/cli/cli_config.rs +++ b/src/cli/cli_config.rs @@ -19,7 +19,7 @@ use std::path::PathBuf; /// Project configuration #[derive(Parser, Debug, Default, Clone)] pub struct ProjectConfig { - /// The path to `pixi.toml` or `pyproject.toml` + /// The path to `pixi.toml`, `pyproject.toml`, or the project directory #[arg(long, global = true)] pub manifest_path: Option, } diff --git a/src/cli/completion.rs b/src/cli/completion.rs index 806ed7e5d2..5b6491e5b6 100644 --- a/src/cli/completion.rs +++ b/src/cli/completion.rs @@ -257,7 +257,7 @@ _arguments "${_arguments_options[@]}" \ # Runs task in project export extern "pixi run" [ ...task: string # The pixi task or a task shell command you want to run in the project's environment, which can be an executable in the environment's PATH - --manifest-path: string # The path to `pixi.toml` or `pyproject.toml` + --manifest-path: string # The path to `pixi.toml`, `pyproject.toml`, or the project directory --frozen # Install the environment as defined in the lockfile, doesn't update lockfile if it isn't up-to-date with the manifest file --locked # Check if lockfile is up-to-date before installing the environment, aborts when lockfile isn't up-to-date with the manifest file --environment(-e): string # The environment to run the task in diff --git a/src/cli/project/description/mod.rs b/src/cli/project/description/mod.rs index 11e5dc9668..b0ddaeb410 100644 --- a/src/cli/project/description/mod.rs +++ b/src/cli/project/description/mod.rs @@ -8,7 +8,7 @@ use std::path::PathBuf; /// Commands to manage project description. #[derive(Parser, Debug)] pub struct Args { - /// The path to `pixi.toml` or `pyproject.toml` + /// The path to `pixi.toml`, `pyproject.toml`, or the project directory #[clap(long, global = true)] pub manifest_path: Option, diff --git a/src/cli/project/environment/mod.rs b/src/cli/project/environment/mod.rs index 3d51dd2806..4f94765763 100644 --- a/src/cli/project/environment/mod.rs +++ b/src/cli/project/environment/mod.rs @@ -9,7 +9,7 @@ use std::path::PathBuf; /// Commands to manage project environments. #[derive(Parser, Debug)] pub struct Args { - /// The path to `pixi.toml` or `pyproject.toml` + /// The path to `pixi.toml`, `pyproject.toml`, or the project directory #[clap(long, global = true)] pub manifest_path: Option, diff --git a/src/cli/project/platform/mod.rs b/src/cli/project/platform/mod.rs index 230900bc1b..80f382c82b 100644 --- a/src/cli/project/platform/mod.rs +++ b/src/cli/project/platform/mod.rs @@ -9,7 +9,7 @@ use std::path::PathBuf; /// Commands to manage project platforms. #[derive(Parser, Debug)] pub struct Args { - /// The path to `pixi.toml` or `pyproject.toml` + /// The path to `pixi.toml`, `pyproject.toml`, or the project directory #[clap(long, global = true)] pub manifest_path: Option, diff --git a/src/cli/project/version/mod.rs b/src/cli/project/version/mod.rs index c72f996947..600e382a98 100644 --- a/src/cli/project/version/mod.rs +++ b/src/cli/project/version/mod.rs @@ -10,7 +10,7 @@ use std::path::PathBuf; /// Commands to manage project version. #[derive(Parser, Debug)] pub struct Args { - /// The path to `pixi.toml` or `pyproject.toml` + /// The path to `pixi.toml`, `pyproject.toml`, or the project directory #[clap(long, global = true)] pub manifest_path: Option, diff --git a/src/cli/snapshots/pixi__cli__completion__tests__nushell_completion.snap b/src/cli/snapshots/pixi__cli__completion__tests__nushell_completion.snap index 8117489f62..1fe39f137b 100644 --- a/src/cli/snapshots/pixi__cli__completion__tests__nushell_completion.snap +++ b/src/cli/snapshots/pixi__cli__completion__tests__nushell_completion.snap @@ -14,7 +14,7 @@ expression: result # Runs task in project export extern "pixi run" [ ...task: string@"nu-complete pixi run" # The pixi task or a task shell command you want to run in the project's environment, which can be an executable in the environment's PATH - --manifest-path: string # The path to `pixi.toml` or `pyproject.toml` + --manifest-path: string # The path to `pixi.toml`, `pyproject.toml`, or the project directory --frozen # Install the environment as defined in the lockfile, doesn't update lockfile if it isn't up-to-date with the manifest file --locked # Check if lockfile is up-to-date before installing the environment, aborts when lockfile isn't up-to-date with the manifest file --environment(-e): string@"nu-complete pixi run environment" # The environment to run the task in diff --git a/src/project/mod.rs b/src/project/mod.rs index ad95c5244d..864131ac52 100644 --- a/src/project/mod.rs +++ b/src/project/mod.rs @@ -233,9 +233,22 @@ impl Project { } /// Loads a project from manifest file. - pub fn from_path(manifest_path: &Path) -> miette::Result { + pub fn from_path(manifest_path: impl AsRef) -> miette::Result { + let manifest_path = manifest_path.as_ref(); + let manifest_path = if manifest_path.is_dir() { + find_project_manifest(manifest_path).ok_or_else(|| { + miette::miette!( + "could not find {} or {} at directory {}", + consts::PROJECT_MANIFEST, + consts::PYPROJECT_MANIFEST, + manifest_path.to_string_lossy() + ) + })? + } else { + manifest_path.to_path_buf() + }; let manifest = Manifest::from_path(manifest_path)?; - Ok(Project::from_manifest(manifest)) + Ok(Self::from_manifest(manifest)) } /// Loads a project manifest file or discovers it in the current directory