Skip to content

Commit

Permalink
--wip--
Browse files Browse the repository at this point in the history
  • Loading branch information
schmidma committed Dec 17, 2024
1 parent 480bc7e commit 8486f75
Show file tree
Hide file tree
Showing 8 changed files with 814 additions and 485 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ build_script_helpers = { path = "crates/build_script_helpers" }
byteorder = "1.4.3"
calibration = { path = "crates/calibration" }
chrono = "0.4.23"
clap = { version = "4.2.4", features = ["derive"] }
clap = { version = "4.2.4", features = ["derive", "env"] }
clap_complete = "4.2.1"
code_generation = { path = "crates/code_generation" }
color-eyre = "0.6.2"
Expand Down
217 changes: 56 additions & 161 deletions crates/repository/src/cargo.rs
Original file line number Diff line number Diff line change
@@ -1,153 +1,70 @@
use std::path::Path;
use std::{path::Path, process::Command, str::FromStr};

use color_eyre::{
eyre::{bail, Context, ContextCompat},
Result,
};
use log::info;
use tokio::process::Command;

use crate::data_home::get_data_home;

#[derive(Debug, Clone, Copy)]
pub enum Executor {
Native,
Installed,
Docker,
}

pub struct Environment {
pub executor: Executor,
pub version: String,
impl FromStr for Executor {
type Err = color_eyre::Report;

fn from_str(s: &str) -> Result<Self> {
match s {
"installed" => Ok(Self::Installed),
"docker" => Ok(Self::Docker),
_ => bail!("invalid executor: {s}"),
}
}
}

pub enum Cargo {
pub enum Environment {
Native,
Sdk { environment: Environment },
Sdk { executor: Executor, version: String },
}

impl Cargo {
pub fn native() -> Self {
Cargo::Native
}

pub fn sdk(environment: Environment) -> Self {
Cargo::Sdk { environment }
}

pub fn command<'a>(
self,
sub_command: &'a str,
repository_root: &'a Path,
) -> Result<CargoCommand<'a>> {
Ok(CargoCommand {
cargo: self,
sub_command,
repository_root,
manifest_path: None,
profile: None,
workspace: false,
all_features: false,
all_targets: false,
features: None,
passthrough_arguments: None,
})
}
pub enum Host {
Local,
Remote,
}

pub struct CargoCommand<'a> {
cargo: Cargo,
sub_command: &'a str,
repository_root: &'a Path,
manifest_path: Option<&'a Path>,
profile: Option<&'a str>,
workspace: bool,
all_features: bool,
all_targets: bool,
features: Option<&'a [String]>,
passthrough_arguments: Option<&'a [String]>,
pub struct Cargo {
host: Host,
environment: Environment,
}

impl<'a> CargoCommand<'a> {
pub fn manifest_path(&mut self, manifest_path: &'a Path) -> Result<()> {
if !manifest_path.is_relative() {
bail!("manifest path must be relative to repository root")
impl Cargo {
pub fn local(environment: Environment) -> Self {
Self {
host: Host::Local,
environment,
}
self.manifest_path = Some(manifest_path);
Ok(())
}

pub fn profile(&mut self, profile: &'a str) {
self.profile = Some(profile);
}

pub fn workspace(&mut self) {
self.workspace = true;
}

pub fn all_features(&mut self) {
self.all_features = true;
}

pub fn all_targets(&mut self) {
self.all_targets = true;
}

pub fn features(&mut self, features: &'a [String]) {
self.features = Some(features);
}

pub fn passthrough_arguments(&mut self, passthrough_arguments: &'a [String]) {
self.passthrough_arguments = Some(passthrough_arguments);
pub fn remote(environment: Environment) -> Self {
Self {
host: Host::Remote,
environment,
}
}

pub fn shell_command(self) -> Result<String> {
let mut cargo_arguments = String::new();
pub fn command(self, repository_root: impl AsRef<Path>) -> Result<Command> {
let repository_root = repository_root.as_ref();

if let Some(manifest_path) = self.manifest_path {
cargo_arguments.push_str(&format!(
"--manifest-path {path}",
path = manifest_path
.to_str()
.wrap_err("failed to convert manifest path to string")?
));
}
if let Some(profile) = self.profile {
cargo_arguments.push_str(&format!(" --profile {profile}"));
}
if self.workspace {
cargo_arguments.push_str(" --workspace");
}
if self.all_features {
cargo_arguments.push_str(" --all-features");
}
if self.all_targets {
cargo_arguments.push_str(" --all-targets");
}
if let Some(features) = self.features {
cargo_arguments.push_str(" --features ");
cargo_arguments.push_str(&features.join(","));
}
if let Some(passthrough_arguments) = self.passthrough_arguments {
cargo_arguments.push_str(" -- ");
cargo_arguments.push_str(&passthrough_arguments.join(" "));
}

let shell_command = match self.cargo {
Cargo::Native => {
format!(
"cd {repository_root} && cargo {command} {cargo_arguments}",
repository_root = self
.repository_root
.to_str()
.wrap_err("failed to convert repository root to string")?,
command = self.sub_command,
)
}
Cargo::Sdk {
environment:
Environment {
executor: Executor::Native,
version,
},
// TODO: implement remote
let command = match self.environment {
Environment::Native => Command::new("cargo"),
Environment::Sdk {
executor: Executor::Installed,
version,
} => {
let data_home = get_data_home().wrap_err("failed to get data home")?;
let environment_file = &data_home.join(format!(
Expand All @@ -156,63 +73,41 @@ impl<'a> CargoCommand<'a> {
let sdk_environment_setup = environment_file
.to_str()
.wrap_err("failed to convert sdk environment setup path to string")?;
let cargo_command = format!(
"cargo {command} {cargo_arguments}",
command = self.sub_command,
);
format!(
"cd {repository_root} && . {sdk_environment_setup} && {cargo_command}",
repository_root = self
.repository_root
.to_str()
.wrap_err("failed to convert repository root to string")?,
)
let mut command = Command::new("bash");
command
.arg("-c")
.arg(format!(". {sdk_environment_setup} && cargo $@"));
command
}
Cargo::Sdk {
environment:
Environment {
executor: Executor::Docker,
version,
},
Environment::Sdk {
executor: Executor::Docker,
version,
} => {
let data_home = get_data_home().wrap_err("failed to get data home")?;
let cargo_home = data_home.join("container-cargo-home/");
let mut command = Command::new("bash");
command.arg("-c");
command.arg(
format!("\
mkdir -p {cargo_home} &&
docker run \
--volume={repository_root}:/hulk:z \
--volume={cargo_home}:/naosdk/sysroots/corei7-64-aldebaran-linux/home/cargo:Z \
--volume={cargo_home}:/naosdk/sysroots/corei7-64-aldebaran-linux/home/cargo:z \
--rm \
--interactive \
--tty ghcr.io/hulks/naosdk:{version} \
/bin/bash -c \"\
cd /hulk && \
. /naosdk/environment-setup-corei7-64-aldebaran-linux && \
cargo {command} {cargo_arguments}\
cargo $@\
\"
",
repository_root=self.repository_root.to_str().wrap_err("failed to convert repository root to string")?,
repository_root=repository_root.to_str().wrap_err("failed to convert repository root to string")?,
cargo_home=cargo_home.to_str().wrap_err("failed to convert cargo home to string")?,
command=self.sub_command,
)
));
command
}
};
Ok(shell_command)
}
}

pub async fn run_shell(command: &str) -> Result<()> {
info!("Executing command: `{command}`");

let status = Command::new("sh")
.arg("-c")
.arg(command)
.status()
.await
.wrap_err("failed to execute cargo command")?;

if !status.success() {
bail!("cargo command exited with {status}");
Ok(command)
}
Ok(())
}
Loading

0 comments on commit 8486f75

Please sign in to comment.