Skip to content

Commit cd51ad8

Browse files
committed
feat: add support to shell expansion
1 parent 6ab20de commit cd51ad8

File tree

6 files changed

+164
-23
lines changed

6 files changed

+164
-23
lines changed

Cargo.lock

+107
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,4 @@ colored = "2.1.0"
1212
serde = { version = "1.0.201", features = ["derive"] }
1313
serde_json = "1.0.117"
1414
atty = "0.2.14"
15+
shellexpand = "3.1.0"

src/cli.rs

+1
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ enum Commands {
5656
},
5757

5858
/// Run the package
59+
#[command(disable_help_flag = true)]
5960
Run {
6061
/// Name of the package to run
6162
name: String,

src/commands.rs

+17-11
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use crate::files::versions::{remove, upsert};
22
use crate::packages;
33
use crate::packages::Package;
44
use crate::runner::run;
5-
use crate::shims::add_shim;
5+
use crate::shims::{add_shim, remove_shim};
66
use colored::*;
77
use std::env;
88
use std::error::Error;
@@ -46,7 +46,7 @@ pub fn list_packages(name: Option<&str>) -> Result<(), Box<dyn Error>> {
4646
}
4747
Ok(())
4848
} else {
49-
Err(Box::from("Could not find any packages installed."))
49+
Err("Could not find any packages installed.".into())
5050
}
5151
}
5252
}
@@ -61,10 +61,13 @@ pub fn add_package(name: String, version: String, set_default: bool) -> Result<(
6161
if set_default {
6262
package.versions.current = version.clone();
6363
}
64-
run_pull_and_add_shim(&name, &version, package)?;
64+
let current = package.versions.current.clone();
65+
do_add_package(&name, &version, package)?;
66+
println!("Added '{}' version '{}'. Current version is '{}'.", name, version, current);
6567
} else {
6668
let package = Package::new(&name, crate::files::versions::Package::new(&version))?;
67-
run_pull_and_add_shim(&name, &version, package)?;
69+
do_add_package(&name, &version, package)?;
70+
println!("Added '{}' version '{}'. Current version is '{}'.", name, version, version);
6871
}
6972
Ok(())
7073
}
@@ -82,7 +85,7 @@ pub fn remove_package(name: String, version: Option<String>) -> Result<(), Box<d
8285
if package.versions.versions.contains(&version) {
8386
package.versions.versions.retain(|v| v != version.as_str());
8487
if package.versions.versions.is_empty() {
85-
remove(&name)?;
88+
do_remove_package(&name)?;
8689
println!("Removed package '{}'.", name);
8790
} else {
8891
upsert(&name, package)?;
@@ -95,7 +98,8 @@ pub fn remove_package(name: String, version: Option<String>) -> Result<(), Box<d
9598
}
9699
}
97100
(Some(_), None) => {
98-
remove(&name)?;
101+
do_remove_package(&name)?;
102+
println!("Removed package '{}'.", name);
99103
Ok(())
100104
}
101105
(None, _) => Err(format!("Package '{}' does not exists.", name).into()),
@@ -130,11 +134,7 @@ pub fn run_package(name: String, subcommand: Vec<String>) -> Result<(), Box<dyn
130134
}
131135
}
132136

133-
fn run_pull_and_add_shim(
134-
name: &String,
135-
version: &String,
136-
package: Package,
137-
) -> Result<(), Box<dyn Error>> {
137+
fn do_add_package(name: &String, version: &String, package: Package) -> Result<(), Box<dyn Error>> {
138138
let mut new_package = package.clone();
139139
new_package.versions.current = version.clone();
140140
if crate::runner::pull(&new_package) {
@@ -145,3 +145,9 @@ fn run_pull_and_add_shim(
145145
Err(format!("Failed to add package '{}' at version '{}'.", name, version).into())
146146
}
147147
}
148+
149+
fn do_remove_package(name: &String) -> Result<(), Box<dyn Error>> {
150+
remove(&name)?;
151+
remove_shim(&name)?;
152+
Ok(())
153+
}

src/packages.rs

+11-3
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,20 @@ impl Package {
4949
}
5050

5151
pub fn print(&self) {
52-
println!("- {}", self.name);
52+
println!("- [{}]", self.name);
53+
println!(" - image: {}", self.index.image);
54+
if let Some(volumes) = &self.index.volumes {
55+
println!(" - volumes:");
56+
for volume in volumes {
57+
println!(" - {}:{}", volume.source, volume.target);
58+
}
59+
}
60+
println!(" - versions:");
5361
for version in &self.versions.versions {
5462
if version == &self.versions.current {
55-
println!(" - {} ✔", version);
63+
println!(" - {} ✔", version);
5664
} else {
57-
println!(" - {}", version);
65+
println!(" - {}", version);
5866
}
5967
}
6068
}

src/runner.rs

+27-9
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use crate::packages::Package;
22
use atty::Stream;
33
use std::io::{self, Read, Write};
4+
use std::path::Path;
45
use std::process::{Command, Stdio};
56

67
fn run_command(command: &str, stdin_buffer: Option<Vec<u8>>) -> bool {
@@ -44,22 +45,39 @@ pub fn run(package: &Package, params: &Vec<String>) -> bool {
4445
io::stdin()
4546
.read_to_end(&mut buffer)
4647
.expect("Failed to read stdin");
47-
buffer.len();
4848
}
4949

50-
let interactive_flag = if interactive { "-i " } else { "" };
51-
let command = format!(
52-
"docker run {}{} {}",
53-
interactive_flag,
54-
package.container_image_url(),
55-
params.join(" ")
56-
);
50+
let mut args = vec!["run".to_string()];
51+
if interactive {
52+
args.push("-i".to_string());
53+
}
54+
55+
// Handling volumes if available
56+
if let Some(volumes) = &package.index.volumes {
57+
for volume in volumes {
58+
let source = shellexpand::full(&volume.source).unwrap();
59+
if Path::new(&source.to_string()).exists() {
60+
args.push("-v".to_string());
61+
args.push(format!("{}:{}", &source, volume.target));
62+
} else {
63+
println!("Volume source '{}' not found. Skipping.", source);
64+
}
65+
}
66+
}
67+
68+
args.push(format!(
69+
"{}:{}",
70+
package.index.image.clone(),
71+
package.versions.current
72+
));
73+
args.extend(params.iter().cloned());
5774

75+
let command = format!("docker {}", args.join(" "));
76+
println!("Running {}", command);
5877
run_command(&command, Some(buffer))
5978
}
6079

6180
pub fn pull(package: &Package) -> bool {
6281
let command = format!("docker pull {}", package.container_image_url());
63-
// Normally, pull does not need stdin interaction
6482
run_command(&command, None)
6583
}

0 commit comments

Comments
 (0)