Skip to content

Commit

Permalink
[fud2] Basic testing setup (#1954)
Browse files Browse the repository at this point in the history
* Skeleton for the simplest possible test

* Reusable test scaffolding

* Test config setup

* Control executable name for tests

* Split main/lib/test

Now we have separate files for the main driver build, the actual `main`
function which is very short, and the tests.

* Add missing tests file

* Include through in test description

* A second test!

* Change config option name

We use `exe` everywhere, not `exec`, and I keep forgetting this fact.

* Be friendlier to Insta

By default, snapshot names are based on the call site... so let's try
separating the assertion lines?

* Factor out test function

* Accept snapshots!

* Add CI action to test fud2

* Appease clippy
  • Loading branch information
sampsyo authored Mar 4, 2024
1 parent 138df88 commit ec266a0
Show file tree
Hide file tree
Showing 10 changed files with 704 additions and 478 deletions.
16 changes: 16 additions & 0 deletions .github/workflows/fud2.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
name: fud2 tests

on:
push:
branches: [main]
pull_request:
branches: [main]

jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Rust
uses: actions-rust-lang/setup-rust-toolchain@v1
- run: cargo test -p fud
47 changes: 47 additions & 0 deletions Cargo.lock

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

7 changes: 7 additions & 0 deletions fud2/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@ anyhow.workspace = true
manifest-dir-macros = "0.1"
include_dir = "0.7"

[lib]
name = "fud2"
path = "src/lib.rs"

[[bin]]
name = "fud2"
path = "src/main.rs"

[dev-dependencies]
insta = "1.36.0"
20 changes: 16 additions & 4 deletions fud2/fud-core/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ pub struct GlobalConfig {

/// Enable verbose output.
pub verbose: bool,

/// The path to the build tool executable.
pub exe: String,
}

impl Default for GlobalConfig {
Expand All @@ -23,12 +26,17 @@ impl Default for GlobalConfig {
ninja: "ninja".to_string(),
keep_build_dir: false,
verbose: false,
exe: std::env::current_exe()
.expect("executable path unknown")
.to_str()
.expect("invalid executable name")
.into(),
}
}
}

/// Location of the configuration file
pub(crate) fn config_path(name: &str) -> std::path::PathBuf {
pub fn config_path(name: &str) -> std::path::PathBuf {
// The configuration is usually at `~/.config/driver_name.toml`.
let config_base = env::var("XDG_CONFIG_HOME").unwrap_or_else(|_| {
let home = env::var("HOME").expect("$HOME not set");
Expand All @@ -39,11 +47,15 @@ pub(crate) fn config_path(name: &str) -> std::path::PathBuf {
config_path
}

/// Get raw configuration data with some default options.
pub fn default_config() -> Figment {
Figment::from(Serialized::defaults(GlobalConfig::default()))
}

/// Load configuration data from the standard config file location.
pub(crate) fn load_config(name: &str) -> Figment {
pub fn load_config(name: &str) -> Figment {
let config_path = config_path(name);

// Use our defaults, overridden by the TOML config file.
Figment::from(Serialized::defaults(GlobalConfig::default()))
.merge(Toml::file(config_path))
default_config().merge(Toml::file(config_path))
}
26 changes: 14 additions & 12 deletions fud2/fud-core/src/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,14 @@ pub struct Run<'a> {
impl<'a> Run<'a> {
pub fn new(driver: &'a Driver, plan: Plan) -> Self {
let config_data = config::load_config(&driver.name);
Self::with_config(driver, plan, config_data)
}

pub fn with_config(
driver: &'a Driver,
plan: Plan,
config_data: figment::Figment,
) -> Self {
let global_config: config::GlobalConfig =
config_data.extract().expect("failed to load config");
Self {
Expand Down Expand Up @@ -226,21 +234,15 @@ impl<'a> Run<'a> {
Ok(())
}

fn emit<T: Write + 'static>(&self, out: T) -> EmitResult {
pub fn emit<T: Write + 'a>(&self, out: T) -> EmitResult {
let mut emitter = Emitter::new(
out,
self.config_data.clone(),
self.plan.workdir.clone(),
);

// Emit preamble.
emitter.var(
"build-tool",
std::env::current_exe()
.expect("executable path unknown")
.to_str()
.expect("invalid executable name"),
)?;
emitter.var("build-tool", &self.global_config.exe)?;
emitter.rule("get-rsrc", "$build-tool get-rsrc $out")?;
writeln!(emitter.out)?;

Expand Down Expand Up @@ -278,14 +280,14 @@ impl<'a> Run<'a> {
}
}

pub struct Emitter {
pub out: Box<dyn Write>,
pub struct Emitter<'a> {
pub out: Box<dyn Write + 'a>,
pub config_data: figment::Figment,
pub workdir: Utf8PathBuf,
}

impl Emitter {
fn new<T: Write + 'static>(
impl<'a> Emitter<'a> {
fn new<T: Write + 'a>(
out: T,
config_data: figment::Figment,
workdir: Utf8PathBuf,
Expand Down
Loading

0 comments on commit ec266a0

Please sign in to comment.