Skip to content

Commit

Permalink
Merge branch 'main' into test/follow-up
Browse files Browse the repository at this point in the history
  • Loading branch information
Hofer-Julian authored Nov 6, 2024
2 parents cbb0198 + 4b4a075 commit 64d2e54
Show file tree
Hide file tree
Showing 17 changed files with 220 additions and 23 deletions.
2 changes: 2 additions & 0 deletions crates/pixi_trampoline/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,7 @@ strip = true

[dependencies]
ctrlc = "3.4"
miette = "7.2.0"
pixi_utils = { path = "../pixi_utils" }
serde = { version = "1.0.210", features = ["derive"] }
serde_json = "1.0.128"
48 changes: 30 additions & 18 deletions crates/pixi_trampoline/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ use serde::Deserialize;
use std::collections::HashMap;
use std::env;
use std::fs::File;
use pixi_utils::executable_from_path;
#[cfg(target_family = "unix")]
use std::os::unix::process::CommandExt;
use std::path::{Path, PathBuf};
use std::process::{Command, Stdio};
use miette::{IntoDiagnostic, Context};


// trampoline configuration folder name
Expand All @@ -18,39 +20,40 @@ struct Metadata {
env: HashMap<String, String>,
}

fn read_metadata(current_exe: &Path) -> Metadata {
fn read_metadata(current_exe: &Path) -> miette::Result<Metadata> {
// the metadata file is next to the current executable parent folder,
// under trampoline_configuration/current_exe_name.json
let exe_parent = current_exe.parent().expect("should have a parent");
let exe_name = current_exe.file_stem().expect("should have a file name");
let metadata_path = exe_parent.join(TRAMPOLINE_CONFIGURATION).join(format!("{}{}", exe_name.to_string_lossy(), ".json"));
let metadata_file = File::open(metadata_path).unwrap();
let metadata: Metadata = serde_json::from_reader(metadata_file).unwrap();
metadata
if let Some(exe_parent) = current_exe.parent(){
let metadata_path = exe_parent.join(TRAMPOLINE_CONFIGURATION).join(format!("{}{}", executable_from_path(current_exe), ".json"));
let metadata_file = File::open(&metadata_path).into_diagnostic().wrap_err(format!("Couldn't open {:?}", metadata_path))?;
let metadata: Metadata = serde_json::from_reader(metadata_file).into_diagnostic()?;
return Ok(metadata);
}
miette::bail!("Couldn't get the parent folder of the current executable: {:?}", current_exe);
}

fn prepend_path(extra_path: &str) -> String {
let path = env::var("PATH").unwrap();
fn prepend_path(extra_path: &str) -> miette::Result<String> {
let path = env::var("PATH").into_diagnostic().wrap_err("Couldn't get 'PATH'")?;
let mut split_path = env::split_paths(&path).collect::<Vec<_>>();
split_path.insert(0, PathBuf::from(extra_path));
let new_path = env::join_paths(split_path).unwrap();
new_path.to_string_lossy().into_owned()
let new_path = env::join_paths(&split_path).into_diagnostic().wrap_err(format!("Couldn't join PATH's: {:?}", &split_path))?;
Ok(new_path.to_string_lossy().into_owned())
}

fn main() -> () {
fn trampoline() -> miette::Result<()> {
// Get command-line arguments (excluding the program name)
let args: Vec<String> = env::args().collect();
let current_exe = env::current_exe().expect("Failed to get current executable path");
let current_exe = env::current_exe().into_diagnostic().wrap_err("Couldn't get the `env::current_exe`")?;

// ignore any ctrl-c signals
ctrlc::set_handler(move || {}).expect("Error setting Ctrl-C handler");
ctrlc::set_handler(move || {}).into_diagnostic().wrap_err("Couldn't set the ctrl-c handler")?;

let metadata = read_metadata(&current_exe);
let metadata = read_metadata(&current_exe)?;

// Create a new Command for the specified executable
let mut cmd = Command::new(metadata.exe);

let new_path = prepend_path(&metadata.path);
let new_path = prepend_path(&metadata.path)?;

// Set the PATH environment variable
cmd.env("PATH", new_path);
Expand All @@ -74,12 +77,21 @@ fn main() -> () {

#[cfg(target_os = "windows")]
{
let mut child = cmd.spawn().expect("process spawn should succeed");
let mut child = cmd.spawn().into_diagnostic().wrap_err("Couldn't spawn the child process")?;

// Wait for the child process to complete
let status = child.wait().expect("failed to wait on child");
let status = child.wait().into_diagnostic().wrap_err("Couldn't wait for the child process")?;

// Exit with the same status code as the child process
std::process::exit(status.code().unwrap_or(1));
}
Ok(())
}

// Entry point for the trampoline
fn main() {
if let Err(err) = trampoline() {
eprintln!("{:?}", err);
std::process::exit(1);
}
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
153 changes: 153 additions & 0 deletions pixi.lock

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

6 changes: 5 additions & 1 deletion pixi.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ run-all-examples = { cmd = "python tests/scripts/run-all-examples.py --pixi-exec
] }
test-all-fast = { depends-on = ["test-fast", "test-integration-fast"] }
test-all-slow = { depends-on = ["test-slow", "test-integration-slow"] }
test-export = "python tests/scripts/test-export.sh"
test-fast = "cargo nextest run --workspace"
test-slow = """cargo nextest run --workspace --retries 2 --features slow_integration_tests
--status-level skip --failure-output immediate-final --no-fail-fast --final-status-level slow"""
Expand Down Expand Up @@ -140,6 +139,10 @@ python-build = ">=1.2.2,<2"
[feature.pypi-gen.tasks]
pypi-gen-indexes = "python tests/data/pypi-indexes/generate-indexes.py"

[feature.micromamba]
dependencies = { micromamba = "*" }
tasks = { test-export = "bash tests/scripts/test-export.sh" }

[environments]
default = { features = [
"build",
Expand All @@ -159,3 +162,4 @@ schema = { features = [
"schema",
"pytest",
], no-default-feature = true, solve-group = "default" }
test-export = { features = ["micromamba"], no-default-feature = true }
2 changes: 1 addition & 1 deletion src/cli/project/export/conda_environment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ mod tests {
#[test]
fn test_export_conda_env_yaml() {
let path = Path::new(env!("CARGO_MANIFEST_DIR"))
.join("src/cli/project/export/test-data/testenv/pixi.toml");
.join("tests/data/mock-projects/test-project-export/pixi.toml");
let project = Project::from_path(&path).unwrap();
let args = Args {
output_path: None,
Expand Down
2 changes: 1 addition & 1 deletion src/cli/project/export/conda_explicit_spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ mod tests {
#[test]
fn test_render_conda_explicit_spec() {
let path = Path::new(env!("CARGO_MANIFEST_DIR"))
.join("src/cli/project/export/test-data/testenv/pixi.lock");
.join("tests/data/mock-projects/test-project-export/pixi.lock");
let lockfile = LockFile::from_path(&path).unwrap();

let output_dir = tempdir().unwrap();
Expand Down
23 changes: 23 additions & 0 deletions tests/integration_python/global/test_trampoline.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,3 +135,26 @@ def test_trampoline_migrate_previous_script(
dummy_trampoline_json = tmp_path / "bin" / "trampoline_configuration" / "dummy-trampoline.json"

assert dummy_trampoline_json.is_file()


def test_trampoline_dot_in_exe(pixi: Path, tmp_path: Path, trampoline_channel_1: str) -> None:
env = {"PIXI_HOME": str(tmp_path)}

# Expose binary with a dot in the name
verify_cli_command(
[
pixi,
"global",
"install",
"--channel",
trampoline_channel_1,
"dummy-trampoline",
"--expose",
"exe.test=dummy-trampoline",
],
env=env,
)

exe_test = tmp_path / "bin" / exec_extension("exe.test")
# The binary execute should succeed
verify_cli_command([exe_test], stdout_contains="Success:")
7 changes: 5 additions & 2 deletions tests/scripts/test-export.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,18 @@ set -e
set -x
echo "Running test_export.sh"

echo "Activating 'export-test' env"
eval "$(pixi shell-hook)"
unset PIXI_IN_SHELL
echo "Exporting the export test environment"
cd src/cli/project/export/test-data/testenv
cd tests/data/mock-projects/test-project-export
pixi project export conda-environment | tee test-env.yml
echo "Creating the export test environment with micromamba"
micromamba create -y -f test-env.yml -n export-test
micromamba env list
micromamba env remove -y -n export-test
rm test-env.yml
cd ../../../../../..
cd ../../../..

# Setuptools error with env_test_package
# echo "Exporting an environment.yml with pip extras"
Expand Down

0 comments on commit 64d2e54

Please sign in to comment.