Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ reqwest-middleware = "0.4"
reqwest-retry = "0.7.0"
rlimit = "0.10.2"
rstest = "0.25.0"
same-file = "1.0.6"
self-replace = "1.5.0"
serde = "1.0.218"
serde-untagged = "0.1.6"
Expand Down Expand Up @@ -327,6 +328,7 @@ reqwest = { workspace = true, features = [
] }
reqwest-middleware = { workspace = true }
rlimit = { workspace = true }
same-file = { workspace = true }
self-replace = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
Expand Down
20 changes: 19 additions & 1 deletion src/cli/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,15 @@ use std::{
use clap::{Parser, ValueEnum};
use miette::{Context, IntoDiagnostic};
use minijinja::{Environment, context};
use pixi_config::{Config, get_default_author};
use pixi_config::{Config, get_default_author, pixi_home};
use pixi_consts::consts;
use pixi_manifest::{
DependencyOverwriteBehavior, FeatureName, SpecType, pyproject::PyProjectManifest,
};
use pixi_spec::PixiSpec;
use pixi_utils::conda_environment_file::CondaEnvFile;
use rattler_conda_types::{NamedChannelOrUrl, Platform};
use same_file::is_same_file;
use tokio::fs::OpenOptions;
use url::Url;
use uv_normalize::PackageName;
Expand Down Expand Up @@ -255,6 +256,14 @@ pixi.lock merge=binary gitlab-language=yaml gitlab-generated=true
}
}

fn is_init_dir_equal_to_pixi_home_parent(init_dir: &Path) -> bool {
pixi_home()
.as_ref()
.and_then(|home_dir| home_dir.parent())
.and_then(|parent| is_same_file(parent, init_dir).ok())
.unwrap_or(false)
}

pub async fn execute(args: Args) -> miette::Result<()> {
let env = Environment::new();
// Fail silently if the directory already exists or cannot be created.
Expand All @@ -267,6 +276,15 @@ pub async fn execute(args: Args) -> miette::Result<()> {
let gitattributes_path = dir.join(".gitattributes");
let config = Config::load_global();

if is_init_dir_equal_to_pixi_home_parent(&dir) {
miette::bail!(
"You cannot create a workspace in the parent of the pixi home directory.\n\
Please see https://pixi.sh/pixi/v{}/reference/environment_variables/ \
for more information about the pixi home directory.",
consts::PIXI_VERSION
);
}

// Deprecation warning for the `pyproject` option
if args.pyproject_toml {
eprintln!(
Expand Down
12 changes: 12 additions & 0 deletions tests/integration_python/test_main_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,18 @@ def test_pixi_init_non_existing_dir(pixi: Path, tmp_pixi_workspace: Path) -> Non
assert "[workspace]" in manifest_content


def test_pixi_init_pixi_home_parent(pixi: Path, tmp_pixi_workspace: Path) -> None:
pixi_home = tmp_pixi_workspace / ".pixi"
pixi_home.mkdir(exist_ok=True)

verify_cli_command(
[pixi, "init", pixi_home.parent],
ExitCode.FAILURE,
stderr_contains="You cannot create a workspace in the parent of the pixi home directory",
env={"PIXI_HOME": str(pixi_home)},
)


@pytest.mark.slow
def test_pixi_init_pyproject(pixi: Path, tmp_pixi_workspace: Path) -> None:
manifest_path = tmp_pixi_workspace / "pyproject.toml"
Expand Down