diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8063a1d..e469e7e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -37,7 +37,7 @@ jobs: name: Check runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Install toolchain uses: dtolnay/rust-toolchain@nightly with: @@ -46,17 +46,17 @@ jobs: - uses: taiki-e/install-action@v2 with: tool: typos-cli,taplo-cli,hawkeye - - run: cargo +nightly x lint + - run: cargo x lint test: name: Run tests strategy: matrix: os: [ ubuntu-24.04, macos-14, windows-2022 ] - rust-version: [ "stable" ] + rust-version: [ "stable", "nightly" ] runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - uses: Swatinem/rust-cache@v2 - name: Delete rust-toolchain.toml run: rm rust-toolchain.toml diff --git a/Cargo.lock b/Cargo.lock index 6fb6e54..e80912d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -58,6 +58,12 @@ version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" +[[package]] +name = "cfg-if" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + [[package]] name = "clap" version = "4.5.53" @@ -170,14 +176,39 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "examples" +version = "0.0.0" +dependencies = [ + "derive_more", + "exn", +] + [[package]] name = "exn" version = "0.2.1" dependencies = [ - "derive_more", "insta", ] +[[package]] +name = "fastrand" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + +[[package]] +name = "getrandom" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasip2", +] + [[package]] name = "heck" version = "0.5.0" @@ -186,13 +217,14 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "insta" -version = "1.44.3" +version = "1.45.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5c943d4415edd8153251b6f197de5eb1640e56d84e8d9159bea190421c73698" +checksum = "983e3b24350c84ab8a65151f537d67afbbf7153bb9f1110e03e9fa9b07f67a5c" dependencies = [ "console", "once_cell", "similar", + "tempfile", ] [[package]] @@ -243,6 +275,12 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + [[package]] name = "rustc_version" version = "0.4.1" @@ -294,6 +332,19 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "tempfile" +version = "3.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" +dependencies = [ + "fastrand", + "getrandom", + "once_cell", + "rustix", + "windows-sys 0.61.2", +] + [[package]] name = "unicode-ident" version = "1.0.22" @@ -318,6 +369,15 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +[[package]] +name = "wasip2" +version = "1.0.1+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" +dependencies = [ + "wit-bindgen", +] + [[package]] name = "which" version = "8.0.0" @@ -423,6 +483,12 @@ version = "0.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d135d17ab770252ad95e9a872d365cf3090e3be864a34ab46f48555993efc904" +[[package]] +name = "wit-bindgen" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" + [[package]] name = "x" version = "0.0.0" diff --git a/Cargo.toml b/Cargo.toml index 568be35..5b4c41e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,7 @@ # limitations under the License. [workspace] -members = ["exn", "xtask"] +members = ["examples", "exn", "xtask"] resolver = "3" [workspace.package] @@ -23,6 +23,16 @@ license = "Apache-2.0" readme = "README.md" repository = "https://github.com/fast/exn" +[workspace.dependencies] +# Workspace dependencies +exn = { path = "exn" } + +# Crates.io dependencies +clap = { version = "4.5.20", features = ["derive"] } +derive_more = { version = "2.1.0", features = ["full"] } +insta = { version = "1.45.1" } +which = { version = "8.0.0" } + [workspace.lints.rust] unexpected_cfgs = { level = "deny", check-cfg = ['cfg(windows_test)'] } unknown_lints = "deny" diff --git a/examples/Cargo.toml b/examples/Cargo.toml new file mode 100644 index 0000000..58b6ce6 --- /dev/null +++ b/examples/Cargo.toml @@ -0,0 +1,45 @@ +# Copyright 2025 FastLabs Developers +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +[package] +name = "examples" +publish = false + +edition.workspace = true + +[[example]] +name = "anti-pattern" +path = "src/anti-pattern.rs" + +[[example]] +name = "basic" +path = "src/basic.rs" + +[[example]] +name = "custom-layout" +path = "src/custom-layout.rs" + +[[example]] +name = "downcast" +path = "src/downcast.rs" + +[package.metadata.release] +release = false + +[dependencies] +derive_more = { workspace = true } +exn = { workspace = true } + +[lints] +workspace = true diff --git a/exn/examples/anti_pattern.rs b/examples/src/anti-pattern.rs similarity index 93% rename from exn/examples/anti_pattern.rs rename to examples/src/anti-pattern.rs index 05f4ed5..a3529fb 100644 --- a/exn/examples/anti_pattern.rs +++ b/examples/src/anti-pattern.rs @@ -80,8 +80,8 @@ mod http { // Output when running `cargo run --example anti_pattern`. // Notice "failed to send request" appears twice with no new information! // -// Error: fatal error occurred in application, at exn/examples/anti_pattern.rs:35:16 +// Error: fatal error occurred in application, at examples/src/anti-pattern.rs:35:16 // | -// |-> failed to send request, at exn/examples/anti_pattern.rs:49:30 +// |-> failed to send request, at examples/src/anti-pattern.rs:49:30 // | -// |-> failed to send request to server: https://anti-pattern.com, at exn/examples/anti_pattern.rs:67:9 +// |-> failed to send request to server: https://anti-pattern.com, at examples/src/anti-pattern.rs:67:9 diff --git a/exn/examples/basic.rs b/examples/src/basic.rs similarity index 94% rename from exn/examples/basic.rs rename to examples/src/basic.rs index e9b5fee..ce85c53 100644 --- a/exn/examples/basic.rs +++ b/examples/src/basic.rs @@ -71,8 +71,8 @@ mod http { // Output when running `cargo run --example basic`: // -// Error: fatal error occurred in application, at exn/examples/basic.rs:34:16 +// Error: fatal error occurred in application, at examples/src/basic.rs:34:16 // | -// |-> failed to run app, at exn/examples/basic.rs:49:14 +// |-> failed to run app, at examples/src/basic.rs:49:14 // | -// |-> failed to send request to server: https://example.com, at exn/examples/basic.rs:62:9 +// |-> failed to send request to server: https://example.com, at examples/src/basic.rs:62:9 diff --git a/exn/examples/custom_layout.rs b/examples/src/custom-layout.rs similarity index 96% rename from exn/examples/custom_layout.rs rename to examples/src/custom-layout.rs index 5f7154d..36eb54e 100644 --- a/exn/examples/custom_layout.rs +++ b/examples/src/custom-layout.rs @@ -120,5 +120,5 @@ mod http { // Output when running `cargo run --example custom_layout`: // // Error: fatal error occurred in application: -// 0: [exn/examples/custom_layout.rs:81:30] failed to run app -// 1: [exn/examples/custom_layout.rs:101:9] failed to send request to server: https://example.com +// 0: [examples/src/custom-layout.rs:81:30] failed to run app +// 1: [examples/src/custom-layout.rs:101:9] failed to send request to server: https://example.com diff --git a/exn/examples/downcast.rs b/examples/src/downcast.rs similarity index 94% rename from exn/examples/downcast.rs rename to examples/src/downcast.rs index d6f3b01..45d6645 100644 --- a/exn/examples/downcast.rs +++ b/examples/src/downcast.rs @@ -117,8 +117,8 @@ mod http { // Retryable error, attempting retry #3 // // HTTP error with status code: 503 -// Error: fatal error occurred in application, at exn/examples/downcast.rs:52:24 +// Error: fatal error occurred in application, at examples/src/downcast.rs:52:24 // | -// |-> failed to run app, at exn/examples/downcast.rs:80:35 +// |-> failed to run app, at examples/src/downcast.rs:80:35 // | -// |-> HTTP 503: service unavailable, at exn/examples/downcast.rs:93:9 +// |-> HTTP 503: service unavailable, at examples/src/downcast.rs:93:9 diff --git a/exn/Cargo.toml b/exn/Cargo.toml index 4d9a7f2..8380748 100644 --- a/exn/Cargo.toml +++ b/exn/Cargo.toml @@ -31,8 +31,7 @@ rustdoc-args = ["--cfg", "docsrs"] [dependencies] [dev-dependencies] -derive_more = { version = "2.1.0", features = ["full"] } -insta = { version = "1.43.2" } +insta = { workspace = true } [lints] workspace = true diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml index 8217109..6b690a4 100644 --- a/xtask/Cargo.toml +++ b/xtask/Cargo.toml @@ -17,17 +17,13 @@ name = "x" publish = false edition.workspace = true -homepage.workspace = true -license.workspace = true -readme.workspace = true -repository.workspace = true [package.metadata.release] release = false [dependencies] -clap = { version = "4.5.23", features = ["derive"] } -which = { version = "8.0.0" } +clap = { workspace = true } +which = { workspace = true } [lints] workspace = true diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 4e87d7d..1a3110a 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -90,18 +90,16 @@ impl CommandLint { #[cfg(not(windows_test))] fn run_example_tests() { - let examples_dir = PathBuf::from(env!("CARGO_WORKSPACE_DIR")).join("exn/examples"); + let examples_dir = PathBuf::from(env!("CARGO_WORKSPACE_DIR")) + .join("examples") + .join("src"); - assert!( - examples_dir.exists(), - "No examples directory found at {:?}", - examples_dir - ); + let entries = fs::read_dir(&examples_dir).unwrap_or_else(|err| { + panic!("failed to read examples directory at {examples_dir:?}: {err:?}") + }); let mut total = 0; - let mut failed = Vec::new(); - let entries = fs::read_dir(&examples_dir).unwrap(); - + let mut failed = vec![]; for entry in entries { let entry = entry.unwrap(); let path = entry.path(); @@ -120,14 +118,20 @@ fn run_example_tests() { let content = fs::read_to_string(&path).unwrap(); - let commented_stderr = stderr + let actual = stderr .lines() - .map(|line| format!("// {}", line).trim().to_string()) + .map(|line| { + if line.is_empty() { + "//".to_string() + } else { + format!("// {}", line) + } + }) .collect::>() .join("\n"); - if !content.contains(&commented_stderr) { - failed.push((path, stderr.to_string(), commented_stderr)); + if !content.contains(&actual) { + failed.push((path, actual)); } total += 1; @@ -135,10 +139,9 @@ fn run_example_tests() { if !failed.is_empty() { eprintln!("{}/{} example tests failed:", failed.len(), total); - for (path, actual, expected_comment) in failed { + for (path, actual) in failed { eprintln!("\nexample: {}", path.display()); eprintln!("actual stderr:\n{}", actual); - eprintln!("expected comment in file:\n{}", expected_comment); } std::process::exit(1); } else { @@ -207,7 +210,7 @@ fn make_test_cmd(no_capture: bool, default_features: bool, features: &[&str]) -> fn make_format_cmd(fix: bool) -> StdCommand { let mut cmd = find_command("cargo"); - cmd.args(["fmt", "--all"]); + cmd.args(["+nightly", "fmt", "--all"]); if !fix { cmd.arg("--check"); } @@ -217,6 +220,7 @@ fn make_format_cmd(fix: bool) -> StdCommand { fn make_clippy_cmd(fix: bool) -> StdCommand { let mut cmd = find_command("cargo"); cmd.args([ + "+nightly", "clippy", "--tests", "--all-features",