Skip to content

Commit

Permalink
misc: initial move of trampoline crate
Browse files Browse the repository at this point in the history
  • Loading branch information
nichmor committed Oct 18, 2024
1 parent 6b6c276 commit 10f976c
Show file tree
Hide file tree
Showing 4 changed files with 147 additions and 6 deletions.
31 changes: 25 additions & 6 deletions Cargo.lock

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

28 changes: 28 additions & 0 deletions crates/pixi_trampoline/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
[package]
authors.workspace = true
edition.workspace = true
homepage.workspace = true
license.workspace = true
name = "pixi_trampoline"
readme.workspace = true
repository.workspace = true
version = "0.1.0"

[profile.release]
# Enable Link Time Optimization.
lto = true
# Reduce number of codegen units to increase optimizations.
codegen-units = 1
# Optimize for size.
opt-level = "z"
# Abort on panic.
panic = "abort"
# Automatically strip symbols from the binary.
debug = false
strip = true


[dependencies]
ctrlc = "3.4"
serde = { version = "1.0.210", features = ["derive"] }
serde_json = "1.0.128"
17 changes: 17 additions & 0 deletions crates/pixi_trampoline/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# A small trampoline binary that allow to run executables installed by pixi global install.


This is the configuration used by trampoline to set the env variables, and run the executable.

```js
{
// Full path to the executable
"exe": "/Users/wolfv/.pixi/envs/conda-smithy/bin/conda-smithy",
// One or more path segments to prepend to the PATH environment variable
"path": "/Users/wolfv/.pixi/envs/conda-smithy/bin",
// One or more environment variables to set
"env": {
"CONDA_PREFIX": "/Users/wolfv/.pixi/envs/conda-smithy"
}
}
```
77 changes: 77 additions & 0 deletions crates/pixi_trampoline/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
use serde::Deserialize;
use std::collections::HashMap;
use std::env;
use std::fs::File;
use std::os::unix::process::CommandExt;
use std::path::{Path, PathBuf};
use std::process::{Command, Stdio};

#[derive(Deserialize, Debug)]
struct Metadata {
exe: String,
path: String,
env: HashMap<String, String>,
}

fn read_metadata(current_exe: &Path) -> Metadata {
// the metadata file is next to the current executable, under the name of exe + ".json"
let metadata_path = current_exe.with_extension("json");
let metadata_file = File::open(metadata_path).unwrap();
let metadata: Metadata = serde_json::from_reader(metadata_file).unwrap();
metadata
}

fn prepend_path(extra_path: &str) -> String {
let path = env::var("PATH").unwrap();
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()
}

fn main() -> () {

Check failure on line 32 in crates/pixi_trampoline/src/main.rs

View workflow job for this annotation

GitHub Actions / Cargo Lint

unneeded unit return type
// 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");

// ignore any ctrl-c signals
ctrlc::set_handler(move || {}).expect("Error setting Ctrl-C handler");

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);

// Set the PATH environment variable
cmd.env("PATH", new_path);

// Set any additional environment variables
for (key, value) in metadata.env.iter() {
cmd.env(key, value);
}

// Add any additional arguments
cmd.args(&args[1..]);

// Configure stdin, stdout, and stderr to use the current process's streams
cmd.stdin(Stdio::inherit())
.stdout(Stdio::inherit())
.stderr(Stdio::inherit());

// Spawn the child process
#[cfg(target_family = "unix")]
cmd.exec();

#[cfg(target_os = "windows")]
{
let mut child = cmd.spawn()?;

// Wait for the child process to complete
let status = child.wait()?;

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

0 comments on commit 10f976c

Please sign in to comment.