From 1a6caa476ac4adce1ad015a08baf9440bea4dbba Mon Sep 17 00:00:00 2001 From: Jose Quintana <1700322+joseluisq@users.noreply.github.com> Date: Mon, 12 Feb 2024 23:19:15 +0100 Subject: [PATCH] feat: add `all` and `experimental` Cargo feature flags (#313) * feat: `all` and `experimental` cargo feature flags - the `all` will host all available features (`default`) plus the `experimental`. - the `experimental` will only hold unstable features like for example `metrics` (as of writing) * chore: enable the `all` cargo feature for freebsd this feature also fixes #312 --- .cargo/config.toml | 2 +- .cirrus.yml | 8 +++++--- .github/workflows/devel.yml | 6 ++++-- .github/workflows/release.build.manual.yml | 6 +++++- .github/workflows/release.yml | 4 +++- Cargo.toml | 8 ++++++-- docs/content/building-from-source.md | 20 +++++++++++++++++++- src/handler.rs | 8 ++++---- src/server.rs | 8 ++++---- src/settings/cli.rs | 2 +- src/settings/file.rs | 2 +- src/settings/mod.rs | 7 ++++--- src/testing.rs | 2 +- tests/experimental_metrics.rs | 2 +- 14 files changed, 59 insertions(+), 26 deletions(-) diff --git a/.cargo/config.toml b/.cargo/config.toml index a89bcf2..c13d6c3 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -10,7 +10,7 @@ rustflags = ["-C", "target-feature=+crt-static"] [target.i686-pc-windows-msvc] rustflags = ["-C", "link-arg=libvcruntime.lib"] -# Required for RuntimeMetrics as of writing [build] +# Required for experimental features like `metrics` and others. rustflags = ["--cfg", "tokio_unstable"] rustdocflags = ["--cfg", "tokio_unstable"] diff --git a/.cirrus.yml b/.cirrus.yml index 85adc05..438e6b2 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -9,6 +9,7 @@ task: only_if: $CIRRUS_TAG == '' env: RUSTFLAGS: -Dwarnings --cfg tokio_unstable + CARGO_FEATURES: "--features=all" matrix: - name: freebsd-amd64-test env: @@ -32,17 +33,18 @@ task: test_script: - . $HOME/.cargo/env - | - cargo test --all --target="$BINARY_ARCH-unknown-freebsd" + cargo test --all --target="$BINARY_ARCH-unknown-freebsd" $CARGO_FEATURES build_test_script: - . $HOME/.cargo/env - | - cargo rustc --bin static-web-server --verbose --target="$BINARY_ARCH-unknown-freebsd" + cargo build --bin static-web-server -vv --target="$BINARY_ARCH-unknown-freebsd" $CARGO_FEATURES target/$BINARY_ARCH-unknown-freebsd/debug/static-web-server -h task: only_if: $CIRRUS_TAG != '' env: RUSTFLAGS: -Dwarnings --cfg tokio_unstable + CARGO_FEATURES: "--features=all" GITHUB_TOKEN: ENCRYPTED[d1766ef328d83729917d2ffb875d64c35d1c0177edf8f32e66ec464daf5c1b7b145d65fc6c044a73fffe2235d3b38349] matrix: - name: freebsd-amd64-release @@ -66,7 +68,7 @@ task: - rustup show build_script: | . $HOME/.cargo/env - cargo rustc --bin static-web-server --verbose --release --target="$BINARY_ARCH-unknown-freebsd" + cargo build --bin static-web-server -vv --release --target="$BINARY_ARCH-unknown-freebsd" $CARGO_FEATURES archive_script: | staging="static-web-server-$CIRRUS_TAG-$BINARY_ARCH-unknown-freebsd" mkdir -p "$staging/" diff --git a/.github/workflows/devel.yml b/.github/workflows/devel.yml index 816a973..989d67b 100644 --- a/.github/workflows/devel.yml +++ b/.github/workflows/devel.yml @@ -38,6 +38,8 @@ jobs: RUST_BACKTRACE: 1 # Skip tests SKIP_TESTS: "" + # SWS features for Cargo build + CARGO_FEATURES: "--features=all" strategy: matrix: build: @@ -236,12 +238,12 @@ jobs: - name: Run tests shell: bash run: | - ${{ env.CARGO_BIN }} test --verbose ${{ env.TARGET_FLAGS }} ${{ env.SKIP_TESTS }} + ${{ env.CARGO_BIN }} test --verbose ${{ env.CARGO_FEATURES }} ${{ env.TARGET_FLAGS }} ${{ env.SKIP_TESTS }} - name: Run build shell: bash run: | - ${{ env.CARGO_BIN }} rustc --bin static-web-server --verbose ${{ env.TARGET_FLAGS }} + ${{ env.CARGO_BIN }} build --bin static-web-server -vv ${{ env.CARGO_FEATURES }} ${{ env.TARGET_FLAGS }} - name: Run executable shell: bash diff --git a/.github/workflows/release.build.manual.yml b/.github/workflows/release.build.manual.yml index 92916f8..e7e7b4a 100644 --- a/.github/workflows/release.build.manual.yml +++ b/.github/workflows/release.build.manual.yml @@ -20,6 +20,10 @@ jobs: TARGET_DIR: ./target # Emit backtraces on panics. RUST_BACKTRACE: 1 + # Rustc flags needed by the `all` features + RUSTFLAGS: "--cfg tokio_unstable" + # SWS features for Cargo build + CARGO_FEATURES: "--features=all" strategy: matrix: build: @@ -154,7 +158,7 @@ jobs: echo "target dir is: ${{ env.TARGET_DIR }}" - name: Build release binary - run: ${{ env.CARGO_BIN }} rustc --bin static-web-server --verbose --release ${{ env.TARGET_FLAGS }} + run: ${{ env.CARGO_BIN }} build --bin static-web-server -vv --release ${{ env.CARGO_FEATURES }} ${{ env.TARGET_FLAGS }} - name: Prepare Docker envs shell: bash diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 583d22a..4ec61d8 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -46,6 +46,8 @@ jobs: TARGET_DIR: ./target # Emit backtraces on panics. RUST_BACKTRACE: 1 + # SWS features for Cargo build + CARGO_FEATURES: "--features=all" strategy: matrix: build: @@ -214,7 +216,7 @@ jobs: echo "target dir is: ${{ env.TARGET_DIR }}" - name: Build release binary - run: ${{ env.CARGO_BIN }} rustc --bin static-web-server --verbose --release ${{ env.TARGET_FLAGS }} + run: ${{ env.CARGO_BIN }} build --bin static-web-server -vv --release ${{ env.CARGO_FEATURES }} ${{ env.TARGET_FLAGS }} - name: Build archive shell: bash diff --git a/Cargo.toml b/Cargo.toml index 312df1c..ee4e6fb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,6 +37,7 @@ doc = false [features] # All features enabled by default default = ["compression", "http2", "directory-listing", "basic-auth", "fallback-page"] +all = ["default", "experimental"] # HTTP2 http2 = ["tokio-rustls", "rustls-pemfile"] # Compression @@ -51,6 +52,9 @@ directory-listing = ["humansize", "chrono"] basic-auth = ["bcrypt"] # Fallback Page fallback-page = [] +# Experimental features +# --experimental-metrics +experimental = ["tokio-metrics-collector", "prometheus"] [dependencies] aho-corasick = "1.1" @@ -91,8 +95,8 @@ version = "0.5" [target.'cfg(unix)'.dependencies] signal-hook = { version = "0.3", features = ["extended-siginfo"] } signal-hook-tokio = { version = "0.3", features = ["futures-v0_3"], default-features = false } -tokio-metrics-collector = "0.2" -prometheus = "0.13" +tokio-metrics-collector = { version = "0.2", optional = true } +prometheus = { version = "0.13", optional = true } [target.'cfg(windows)'.dependencies] windows-service = "0.6" diff --git a/docs/content/building-from-source.md b/docs/content/building-from-source.md index e6a9016..25fd058 100644 --- a/docs/content/building-from-source.md +++ b/docs/content/building-from-source.md @@ -29,7 +29,9 @@ However, you can disable just the ones you don't need from the lists below. Feature | Description ---------|------ **Default** | -`default` | Activates all features by default. +`default` | Activates the default features by omission. +`all` | Activates all available features including the `experimental` feature. This is the default feature used when building SWS binaries. +`experimental` | Activates all SWS experimental features. Make sure to also provide the required `RUSTFLAGS` if the feature requires so. [**HTTP2/TLS**](./features/http2-tls.md) | `http2` | Activates the HTTP2 and TLS feature. [**Compression**](./features/compression.md) | @@ -52,8 +54,13 @@ For example, if you want to run or build SWS without the default features like ` ```sh # run cargo run --no-default-features -- -h + # or build cargo build --release --no-default-features + +# or including all features (example) +RUSTFLAGS="--cfg tokio_unstable" \ + cargo build -vv --release --features all ``` ## Cross-compiling @@ -75,6 +82,17 @@ Let's say, you want to cross-compile SWS from macOS to Linux. Then follow these Built binaries can be found under the corresponding toolchain directory inside `target/`. +## Testing + +```sh +# run tests for default features +cargo test +# or run tests for all features including experimental ones +RUSTFLAGS="--cfg tokio_unstable" cargo test --features all +# or run specific tests +cargo test --test rewrites +``` + ## Building documentation from source All HTML documentation is located in the `docs/` project's directory and is built using [Material for MkDocs](https://github.com/squidfunk/mkdocs-material). diff --git a/src/handler.rs b/src/handler.rs index 48cd289..0106516 100644 --- a/src/handler.rs +++ b/src/handler.rs @@ -81,7 +81,7 @@ pub struct RequestHandlerOpts { /// Health endpoint feature. pub health: bool, /// Metrics endpoint feature (experimental). - #[cfg(unix)] + #[cfg(all(unix, feature = "experimental"))] pub experimental_metrics: bool, /// Maintenance mode feature. pub maintenance_mode: bool, @@ -125,7 +125,7 @@ impl RequestHandler { let compression_static = self.opts.compression_static; let ignore_hidden_files = self.opts.ignore_hidden_files; let health = self.opts.health; - #[cfg(unix)] + #[cfg(all(unix, feature = "experimental"))] let experimental_metrics = self.opts.experimental_metrics; let index_files: Vec<&str> = self.opts.index_files.iter().map(|s| s.as_str()).collect(); @@ -134,7 +134,7 @@ impl RequestHandler { let health_request = health && uri_path == "/health" && (method.is_get() || method.is_head()); - #[cfg(unix)] + #[cfg(all(unix, feature = "experimental"))] let metrics_request = experimental_metrics && uri_path == "/metrics" && (method.is_get() || method.is_head()); @@ -202,7 +202,7 @@ impl RequestHandler { } // Metrics endpoint check - #[cfg(unix)] + #[cfg(all(unix, feature = "experimental"))] if metrics_request { use prometheus::Encoder; diff --git a/src/server.rs b/src/server.rs index 3e3613c..333c8c9 100644 --- a/src/server.rs +++ b/src/server.rs @@ -293,15 +293,15 @@ impl Server { server_info!("health endpoint: enabled={}", health); // Metrics endpoint option (experimental) - #[cfg(unix)] + #[cfg(all(unix, feature = "experimental"))] let experimental_metrics = general.experimental_metrics; - #[cfg(unix)] + #[cfg(all(unix, feature = "experimental"))] server_info!( "metrics endpoint (experimental): enabled={}", experimental_metrics ); - #[cfg(unix)] + #[cfg(all(unix, feature = "experimental"))] if experimental_metrics { prometheus::default_registry() .register(Box::new( @@ -350,7 +350,7 @@ impl Server { ignore_hidden_files, index_files, health, - #[cfg(unix)] + #[cfg(all(unix, feature = "experimental"))] experimental_metrics, maintenance_mode, maintenance_mode_status, diff --git a/src/settings/cli.rs b/src/settings/cli.rs index 3f24843..60f912e 100644 --- a/src/settings/cli.rs +++ b/src/settings/cli.rs @@ -400,7 +400,7 @@ pub struct General { /// This is especially useful with Kubernetes liveness and readiness probes. pub health: bool, - #[cfg(unix)] + #[cfg(all(unix, feature = "experimental"))] #[arg( long = "experimental-metrics", default_value = "false", diff --git a/src/settings/file.rs b/src/settings/file.rs index 05ae5a7..19e3bf0 100644 --- a/src/settings/file.rs +++ b/src/settings/file.rs @@ -239,7 +239,7 @@ pub struct General { /// Health endpoint feature. pub health: Option, - #[cfg(unix)] + #[cfg(all(unix, feature = "experimental"))] /// Metrics endpoint feature (experimental). pub experimental_metrics: Option, diff --git a/src/settings/mod.rs b/src/settings/mod.rs index b641676..2114c91 100644 --- a/src/settings/mod.rs +++ b/src/settings/mod.rs @@ -149,7 +149,8 @@ impl Settings { let mut ignore_hidden_files = opts.ignore_hidden_files; let mut index_files = opts.index_files; let mut health = opts.health; - #[cfg(unix)] + + #[cfg(all(unix, feature = "experimental"))] let mut experimental_metrics = opts.experimental_metrics; let mut maintenance_mode = opts.maintenance_mode; @@ -296,7 +297,7 @@ impl Settings { if let Some(v) = general.health { health = v } - #[cfg(unix)] + #[cfg(all(unix, feature = "experimental"))] if let Some(v) = general.experimental_metrics { experimental_metrics = v } @@ -553,7 +554,7 @@ impl Settings { ignore_hidden_files, index_files, health, - #[cfg(unix)] + #[cfg(all(unix, feature = "experimental"))] experimental_metrics, maintenance_mode, maintenance_mode_status, diff --git a/src/testing.rs b/src/testing.rs index 75a637e..ef27a7e 100644 --- a/src/testing.rs +++ b/src/testing.rs @@ -52,7 +52,7 @@ pub mod fixtures { ignore_hidden_files: opts.general.ignore_hidden_files, index_files: vec![opts.general.index_files], health: opts.general.health, - #[cfg(unix)] + #[cfg(all(unix, feature = "experimental"))] experimental_metrics: opts.general.experimental_metrics, maintenance_mode: opts.general.maintenance_mode, maintenance_mode_status: opts.general.maintenance_mode_status, diff --git a/tests/experimental_metrics.rs b/tests/experimental_metrics.rs index 597155d..fed395c 100644 --- a/tests/experimental_metrics.rs +++ b/tests/experimental_metrics.rs @@ -3,7 +3,7 @@ #![deny(rust_2018_idioms)] #![deny(dead_code)] -#[cfg(unix)] +#[cfg(all(unix, feature = "experimental"))] pub mod tests { use hyper::Request; use std::net::SocketAddr; -- libgit2 1.7.2