diff --git a/src/main.rs b/src/main.rs index 2dcb5d4..ab8ec85 100644 --- a/src/main.rs +++ b/src/main.rs @@ -46,7 +46,7 @@ enum Commands { #[arg(long)] // TODO: Read from environment variable? auth_file: Option, - /// The path to 'pixi.toml' or 'pyproject.toml' + /// The path to `pixi.toml`, `pyproject.toml`, or the project directory #[arg(default_value = cwd().join("pixi.toml").into_os_string())] manifest_path: PathBuf, diff --git a/src/pack.rs b/src/pack.rs index 31433e6..9e3ac2d 100644 --- a/src/pack.rs +++ b/src/pack.rs @@ -44,21 +44,36 @@ pub struct PackOptions { pub create_executable: bool, } -/// Pack a pixi environment. -pub async fn pack(options: PackOptions) -> Result<()> { - let lockfile_path = options - .manifest_path - .parent() - .ok_or(anyhow!("could not get parent directory"))? - .join("pixi.lock"); +fn load_lockfile(manifest_path: &Path) -> Result { + if !manifest_path.exists() { + anyhow::bail!( + "manifest path does not exist at {}", + manifest_path.display() + ); + } + + let manifest_path = if !manifest_path.is_dir() { + manifest_path + .parent() + .ok_or(anyhow!("could not get parent directory"))? + } else { + manifest_path + }; - let lockfile = LockFile::from_path(&lockfile_path).map_err(|e| { + let lockfile_path = manifest_path.join("pixi.lock"); + + LockFile::from_path(&lockfile_path).map_err(|e| { anyhow!( "could not read lockfile at {}: {}", lockfile_path.display(), e ) - })?; + }) +} + +/// Pack a pixi environment. +pub async fn pack(options: PackOptions) -> Result<()> { + let lockfile = load_lockfile(&options.manifest_path)?; let client = reqwest_client_from_auth_storage(options.auth_file) .map_err(|e| anyhow!("could not create reqwest client from auth storage: {e}"))?; diff --git a/tests/integration_test.rs b/tests/integration_test.rs index 54f9010..17f8ea8 100644 --- a/tests/integration_test.rs +++ b/tests/integration_test.rs @@ -557,3 +557,15 @@ async fn test_run_packed_executable(options: Options, required_fs_objects: Vec<& // Keep the temporary directory alive until the end of the test drop(temp_dir); } + +#[rstest] +#[tokio::test] +async fn test_manifest_path_dir(#[with(PathBuf::from("examples/simple-python"))] options: Options) { + let pack_options = options.pack_options; + let unpack_options = options.unpack_options; + let pack_file = unpack_options.pack_file.clone(); + + let pack_result = pixi_pack::pack(pack_options).await; + assert!(pack_result.is_ok(), "{:?}", pack_result); + assert!(pack_file.is_file()); +}