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 a3db57f
Show file tree
Hide file tree
Showing 13 changed files with 1,169 additions and 455 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

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

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
218 changes: 48 additions & 170 deletions crates/repository/src/cargo.rs
Original file line number Diff line number Diff line change
@@ -1,218 +1,96 @@
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;

pub enum Executor {
Native,
Docker,
}

pub struct Environment {
pub executor: Executor,
pub version: String,
#[derive(Debug, Clone)]
pub enum Sdk {
Installed { version: String },
Docker { image: String },
}

pub enum Cargo {
pub enum Environment {
Native,
Sdk { environment: Environment },
Sdk(Sdk),
}

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

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(" "));
}
pub fn command(self, repository_root: impl AsRef<Path>) -> Result<Command> {
let repository_root = repository_root.as_ref();

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(Sdk::Installed { version }) => {
let data_home = get_data_home().wrap_err("failed to get data home")?;
let environment_file = &data_home.join(format!(
"sdk/{version}/environment-setup-corei7-64-aldebaran-linux"
));
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 $@"))
.arg("cargo");
command
}
Cargo::Sdk {
environment:
Environment {
executor: Executor::Docker,
version,
},
} => {
Environment::Sdk(Sdk::Docker { image }) => {
let data_home = get_data_home().wrap_err("failed to get data home")?;
let cargo_home = data_home.join("container-cargo-home/");
// TODO: This has to cd into the current pwd first
let mut command = Command::new("bash");
command.arg("-c");
command.arg(
format!("\
mkdir -p {cargo_home} &&
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} \
--tty {image} \
/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,
)
)).arg("cargo");
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 a3db57f

Please sign in to comment.