Skip to content

Commit 174bf23

Browse files
committed
some improvements
* fixes wrong handling of `cross-util +toolchain` * removes a trailing dbg! * makes `cross-utils volumes create --toolchain` actually parse a toolchain this may be a bit surprising as with `+custom` only the channel will be picked
1 parent 47df5c7 commit 174bf23

File tree

6 files changed

+86
-51
lines changed

6 files changed

+86
-51
lines changed

src/bin/commands/containers.rs

Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
use std::io;
22

33
use clap::{Args, Subcommand};
4+
use cross::docker::ImagePlatform;
5+
use cross::rustc::{QualifiedToolchain, Toolchain};
46
use cross::shell::{MessageInfo, Stream};
57
use cross::{docker, CommandExt, TargetTriple};
6-
use cross::{
7-
docker::ImagePlatform,
8-
rustc::{QualifiedToolchain, Toolchain},
9-
};
108

119
#[derive(Args, Debug)]
1210
pub struct ListVolumes {
@@ -105,7 +103,7 @@ pub struct CreateVolume {
105103
pub engine: Option<String>,
106104
/// Toolchain to create a volume for
107105
#[clap(long, default_value = TargetTriple::DEFAULT.triple(), )]
108-
pub toolchain: TargetTriple,
106+
pub toolchain: String,
109107
}
110108

111109
impl CreateVolume {
@@ -141,7 +139,7 @@ pub struct RemoveVolume {
141139
pub engine: Option<String>,
142140
/// Toolchain to remove the volume for
143141
#[clap(long, default_value = TargetTriple::DEFAULT.triple(), )]
144-
pub toolchain: TargetTriple,
142+
pub toolchain: String,
145143
}
146144

147145
impl RemoveVolume {
@@ -321,11 +319,12 @@ fn get_cross_volumes(
321319
engine: &docker::Engine,
322320
msg_info: &mut MessageInfo,
323321
) -> cross::Result<Vec<String>> {
322+
use cross::docker::remote::VOLUME_PREFIX;
324323
let stdout = docker::subcommand(engine, "volume")
325324
.arg("list")
326325
.args(&["--format", "{{.Name}}"])
327326
// handles simple regex: ^ for start of line.
328-
.args(&["--filter", "name=^cross-"])
327+
.args(&["--filter", &format!("name=^{VOLUME_PREFIX}")])
329328
.run_and_get_stdout(msg_info)?;
330329

331330
let mut volumes: Vec<String> = stdout.lines().map(|s| s.to_string()).collect();
@@ -392,17 +391,13 @@ pub fn create_persistent_volume(
392391
channel: Option<&Toolchain>,
393392
msg_info: &mut MessageInfo,
394393
) -> cross::Result<()> {
395-
let config = cross::config::Config::new(None);
396-
let toolchain_host: cross::Target = toolchain.into();
397-
let mut toolchain = QualifiedToolchain::default(&config, msg_info)?;
398-
toolchain.replace_host(&ImagePlatform::from_target(
399-
toolchain_host.target().clone(),
400-
)?);
394+
let mut toolchain = toolchain_or_target(&toolchain, msg_info)?;
401395
if let Some(channel) = channel {
402-
toolchain = toolchain.with_picked(&config, channel.clone(), msg_info)?;
396+
toolchain.channel = channel.channel.clone();
403397
};
404398
let (dirs, metadata) = docker::get_package_info(engine, toolchain.clone(), msg_info)?;
405-
let container = docker::remote::unique_container_identifier(&toolchain_host, &metadata, &dirs)?;
399+
let container =
400+
docker::remote::unique_container_identifier(&toolchain.host().target, &metadata, &dirs)?;
406401
let volume = dirs.toolchain.unique_toolchain_identifier()?;
407402

408403
if docker::remote::volume_exists(engine, &volume, msg_info)? {
@@ -483,14 +478,11 @@ pub fn remove_persistent_volume(
483478
channel: Option<&Toolchain>,
484479
msg_info: &mut MessageInfo,
485480
) -> cross::Result<()> {
486-
let config = cross::config::Config::new(None);
487-
let target_host: cross::Target = toolchain.into();
488-
let mut toolchain = QualifiedToolchain::default(&config, msg_info)?;
489-
toolchain.replace_host(&ImagePlatform::from_target(target_host.target().clone())?);
481+
let mut toolchain = toolchain_or_target(&toolchain, msg_info)?;
490482
if let Some(channel) = channel {
491-
toolchain = toolchain.with_picked(&config, channel.clone(), msg_info)?;
483+
toolchain.channel = channel.channel.clone();
492484
};
493-
let (dirs, _) = docker::get_package_info(engine, toolchain.clone(), msg_info)?;
485+
let (dirs, _) = docker::get_package_info(engine, toolchain, msg_info)?;
494486
let volume = dirs.toolchain.unique_toolchain_identifier()?;
495487

496488
if !docker::remote::volume_exists(engine, &volume, msg_info)? {
@@ -506,11 +498,12 @@ fn get_cross_containers(
506498
engine: &docker::Engine,
507499
msg_info: &mut MessageInfo,
508500
) -> cross::Result<Vec<String>> {
501+
use cross::docker::remote::VOLUME_PREFIX;
509502
let stdout = docker::subcommand(engine, "ps")
510503
.arg("-a")
511504
.args(&["--format", "{{.Names}}: {{.State}}"])
512505
// handles simple regex: ^ for start of line.
513-
.args(&["--filter", "name=^cross-"])
506+
.args(&["--filter", &format!("name=^{VOLUME_PREFIX}")])
514507
.run_and_get_stdout(msg_info)?;
515508

516509
let mut containers: Vec<String> = stdout.lines().map(|s| s.to_string()).collect();
@@ -576,3 +569,20 @@ pub fn remove_all_containers(
576569

577570
Ok(())
578571
}
572+
573+
fn toolchain_or_target(
574+
s: &str,
575+
msg_info: &mut MessageInfo,
576+
) -> Result<QualifiedToolchain, color_eyre::Report> {
577+
let config = cross::config::Config::new(None);
578+
let mut toolchain = QualifiedToolchain::default(&config, msg_info)?;
579+
let target_list = cross::rustc::target_list(msg_info)?;
580+
if target_list.contains(s) {
581+
toolchain.replace_host(&ImagePlatform::from_target(s.into())?);
582+
} else {
583+
let picked: Toolchain = s.parse()?;
584+
toolchain = toolchain.with_picked(picked)?;
585+
}
586+
587+
Ok(toolchain)
588+
}

src/bin/commands/images.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,7 @@ pub fn remove_target_images(
377377
let target_list = msg_info.as_quiet(cross::rustc::target_list)?;
378378
let mut images = vec![];
379379
for image in cross_images {
380-
let target = dbg!(get_image_target(engine, &image, &target_list, msg_info)?);
380+
let target = get_image_target(engine, &image, &target_list, msg_info)?;
381381
if targets.contains(&target) {
382382
images.push(image);
383383
}

src/bin/cross-util.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,9 @@ enum Commands {
3838
Clean(commands::Clean),
3939
}
4040

41-
fn is_toolchain(toolchain: &str) -> cross::Result<String> {
41+
fn is_toolchain(toolchain: &str) -> cross::Result<Toolchain> {
4242
if toolchain.starts_with('+') {
43-
Ok(toolchain.chars().skip(1).collect())
43+
Ok(toolchain.chars().skip(1).collect::<String>().parse()?)
4444
} else {
4545
let _ = <CliHidden as CommandFactory>::command().get_matches();
4646
unreachable!();

src/docker/remote.rs

Lines changed: 48 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,13 @@ use crate::extensions::CommandExt;
1616
use crate::file::{self, PathExt, ToUtf8};
1717
use crate::rustc::{self, QualifiedToolchain, VersionMetaExt};
1818
use crate::shell::{ColorChoice, MessageInfo, Stream, Verbosity};
19-
use crate::temp;
20-
use crate::{Target, TargetTriple};
19+
use crate::TargetTriple;
20+
use crate::{temp, OutputExt};
2121

2222
// the mount directory for the data volume.
2323
pub const MOUNT_PREFIX: &str = "/cross";
24+
// the prefix used when naming volumes
25+
pub const VOLUME_PREFIX: &str = "cross-";
2426
// default timeout to stop a container (in seconds)
2527
pub const DEFAULT_TIMEOUT: u32 = 2;
2628
// instant kill in case of a non-graceful exit
@@ -94,16 +96,6 @@ enum VolumeId {
9496
Discard,
9597
}
9698

97-
impl VolumeId {
98-
fn create(engine: &Engine, toolchain: &str, msg_info: &mut MessageInfo) -> Result<Self> {
99-
if volume_exists(engine, toolchain, msg_info)? {
100-
Ok(Self::Keep(toolchain.to_owned()))
101-
} else {
102-
Ok(Self::Discard)
103-
}
104-
}
105-
}
106-
10799
// prevent further commands from running if we handled
108100
// a signal earlier, and the volume is exited.
109101
// this isn't required, but avoids unnecessary
@@ -754,6 +746,32 @@ pub fn volume_exists(engine: &Engine, volume: &str, msg_info: &mut MessageInfo)
754746
.map(|output| output.status.success())
755747
}
756748

749+
pub fn existing_volumes(
750+
engine: &Engine,
751+
toolchain: &QualifiedToolchain,
752+
msg_info: &mut MessageInfo,
753+
) -> Result<Vec<String>> {
754+
let list = run_and_get_output(
755+
engine,
756+
&[
757+
"volume",
758+
"list",
759+
"--format",
760+
"{{.Name}}",
761+
"--filter",
762+
&format!("name=^{VOLUME_PREFIX}{}", toolchain),
763+
],
764+
msg_info,
765+
)?
766+
.stdout()?;
767+
768+
if list.is_empty() {
769+
Ok(vec![])
770+
} else {
771+
Ok(list.split('\n').map(ToOwned::to_owned).collect())
772+
}
773+
}
774+
757775
pub fn container_stop(
758776
engine: &Engine,
759777
container: &str,
@@ -818,14 +836,14 @@ impl QualifiedToolchain {
818836
.to_utf8()?;
819837
let toolchain_hash = path_hash(self.get_sysroot())?;
820838
Ok(format!(
821-
"cross-{toolchain_name}-{toolchain_hash}-{commit_hash}"
839+
"{VOLUME_PREFIX}{toolchain_name}-{toolchain_hash}-{commit_hash}"
822840
))
823841
}
824842
}
825843

826844
// unique identifier for a given project
827845
pub fn unique_container_identifier(
828-
target: &Target,
846+
triple: &TargetTriple,
829847
metadata: &CargoMetadata,
830848
dirs: &Directories,
831849
) -> Result<String> {
@@ -847,7 +865,6 @@ pub fn unique_container_identifier(
847865
});
848866

849867
let name = &package.name;
850-
let triple = target.triple();
851868
let toolchain_id = dirs.toolchain.unique_toolchain_identifier()?;
852869
let project_hash = path_hash(&package.manifest_path)?;
853870
Ok(format!("{toolchain_id}-{triple}-{name}-{project_hash}"))
@@ -892,8 +909,22 @@ pub(crate) fn run(
892909
// note that since we use `docker run --rm`, it's very
893910
// unlikely the container state existed before.
894911
let toolchain_id = dirs.toolchain.unique_toolchain_identifier()?;
895-
let container = unique_container_identifier(target, &paths.metadata, dirs)?;
896-
let volume = VolumeId::create(engine, &toolchain_id, msg_info)?;
912+
let container = unique_container_identifier(target.target(), &paths.metadata, dirs)?;
913+
let volume = {
914+
let existing = existing_volumes(engine, &dirs.toolchain, msg_info)?;
915+
if existing.iter().any(|v| v == &toolchain_id) {
916+
VolumeId::Keep(toolchain_id)
917+
} else {
918+
let partial = format!("{VOLUME_PREFIX}{}", dirs.toolchain);
919+
if existing.iter().any(|v| v.starts_with(&partial)) {
920+
msg_info.warn(format_args!(
921+
"a persistent volume does not exists for `{0}`, but there is a volume for a different version.\n > Create a new volume with `cross-util volumes create --toolchain {0}`",
922+
dirs.toolchain
923+
))?;
924+
}
925+
VolumeId::Discard
926+
}
927+
};
897928
let state = container_state(engine, &container, msg_info)?;
898929
if !state.is_stopped() {
899930
msg_info.warn(format_args!("container {container} was running."))?;

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -556,7 +556,7 @@ r#"Overriding the toolchain in cross is only possible in CLI by specifying a cha
556556
To override the toolchain mounted in the image, set `target.{}.image.toolchain = "{picked_host}"`"#, target).header("Note:".bright_cyan()));
557557
}
558558

559-
default_toolchain.with_picked(&config, picked_toolchain, msg_info)?
559+
default_toolchain.with_picked(picked_toolchain)?
560560
} else {
561561
default_toolchain
562562
};

src/rustc.rs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -205,13 +205,7 @@ impl QualifiedToolchain {
205205
}
206206

207207
/// Merge a "picked" toolchain, overriding set fields.
208-
pub fn with_picked(
209-
self,
210-
config: &crate::config::Config,
211-
picked: Toolchain,
212-
msg_info: &mut MessageInfo,
213-
) -> Result<Self> {
214-
let toolchain = Self::default(config, msg_info)?;
208+
pub fn with_picked(self, picked: Toolchain) -> Result<Self> {
215209
let date = picked.date.or(self.date);
216210
let host = picked
217211
.host
@@ -222,7 +216,7 @@ impl QualifiedToolchain {
222216
&channel,
223217
&date,
224218
&host,
225-
&toolchain.sysroot,
219+
&self.sysroot,
226220
))
227221
}
228222

0 commit comments

Comments
 (0)