Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Cross.toml deserialization using serde #670

Merged
merged 11 commits into from
Mar 22, 2022
50 changes: 50 additions & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ rustc_version = "0.4"
toml = "0.5"
which = { version = "4", default_features = false }
shell-escape = "0.1"
serde = { version = "1", features = ["derive"] }
serde_json = "1"

[target.'cfg(not(windows))'.dependencies]
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@ $ cross rustc --target powerpc-unknown-linux-gnu --release -- -C lto
## Configuration

You can place a `Cross.toml` file in the root of your Cargo project or use a
`CROSS_CONFIG` environment variable to tweak `cross`'s behavior:
`CROSS_CONFIG` environment variable to tweak `cross`'s behavior. The format
of `Cross.toml` is documented in [docs/cross_toml.md](docs/cross_toml.md).

### Custom Docker images

Expand Down
32 changes: 32 additions & 0 deletions docs/cross_toml.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
The `cross` configuration in the `Cross.toml` file, can contain the following elements:

# `build`
The `build` key allows you to set global variables, e.g.:

```toml
[build]
xargo = true
```

# `build.env`
With the `build.env` key you can globally set volumes that should be mounted
in the Docker container or environment variables that should be passed through.
For example:

```toml
[build.env]
volumes = ["VOL1_ARG", "VOL2_ARG"]
passthrough = ["IMPORTANT_ENV_VARIABLES"]
```

# `target.TARGET`
The `target` key allows you to specify parameters for specific compilation targets.

```toml
[target.aarch64-unknown-linux-gnu]
volumes = ["VOL1_ARG", "VOL2_ARG"]
passthrough = ["VAR1", "VAR2"]
xargo = false
image = "test-image"
runner = "custom-runner"
```
31 changes: 14 additions & 17 deletions src/config.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{Result, Target, Toml};
use crate::{CrossToml, Result, Target};

use crate::errors::*;
use std::collections::HashMap;
Expand Down Expand Up @@ -101,27 +101,27 @@ fn split_to_cloned_by_ws(string: &str) -> Vec<String> {

#[derive(Debug)]
pub struct Config {
toml: Option<Toml>,
toml: Option<CrossToml>,
env: Environment,
}

impl Config {
pub fn new(toml: Option<Toml>) -> Self {
pub fn new(toml: Option<CrossToml>) -> Self {
Config {
toml,
env: Environment::new(None),
}
}

#[cfg(test)]
fn new_with(toml: Option<Toml>, env: Environment) -> Self {
fn new_with(toml: Option<CrossToml>, env: Environment) -> Self {
Config { toml, env }
}

pub fn xargo(&self, target: &Target) -> Result<Option<bool>> {
let (build_xargo, target_xargo) = self.env.xargo(target)?;
let (toml_build_xargo, toml_target_xargo) = if let Some(ref toml) = self.toml {
toml.xargo(target)?
toml.xargo(target)
} else {
(None, None)
};
Expand All @@ -145,15 +145,17 @@ impl Config {
if let Some(env_value) = env_value {
return Ok(Some(env_value));
}
self.toml.as_ref().map_or(Ok(None), |t| t.image(target))
self.toml.as_ref().map_or(Ok(None), |t| Ok(t.image(target)))
}

pub fn runner(&self, target: &Target) -> Result<Option<String>> {
let env_value = self.env.runner(target);
if let Some(env_value) = env_value {
return Ok(Some(env_value));
}
self.toml.as_ref().map_or(Ok(None), |t| t.runner(target))
self.toml
.as_ref()
.map_or(Ok(None), |t| Ok(t.runner(target)))
}

pub fn env_passthrough(&self, target: &Target) -> Result<Vec<String>> {
Expand All @@ -179,15 +181,15 @@ impl Config {
Ok(collected)
}

fn sum_of_env_toml_values<'a>(
toml_getter: impl FnOnce() -> Option<Result<Vec<&'a str>>>,
fn sum_of_env_toml_values(
toml_getter: impl FnOnce() -> Option<Vec<String>>,
env_values: Option<Vec<String>>,
) -> Result<Vec<String>> {
let mut collect = vec![];
if let Some(mut vars) = env_values {
collect.append(&mut vars);
} else if let Some(toml_values) = toml_getter() {
collect.extend(toml_values?.into_iter().map(|v| v.to_string()));
collect.extend(toml_values.into_iter().map(|v| v.to_string()));
}

Ok(collect)
Expand Down Expand Up @@ -277,13 +279,8 @@ mod tests {
use super::*;
use std::matches;

fn toml(content: &str) -> Result<crate::Toml> {
Ok(crate::Toml {
table: match content.parse().wrap_err("couldn't parse toml")? {
toml::Value::Table(table) => table,
_ => eyre::bail!("couldn't parse toml as TOML table"),
},
})
fn toml(content: &str) -> Result<crate::CrossToml> {
Ok(CrossToml::from_str(content).wrap_err("couldn't parse toml")?)
}

#[test]
Expand Down
Loading