diff --git a/.gitignore b/.gitignore index c9613dfcc..66f8abf70 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,6 @@ node_modules # Built docs /earthly/docs/site /earthly/docs/local + +# Local Build Artefacts +target/ \ No newline at end of file diff --git a/earthly/rust/Earthfile b/earthly/rust/Earthfile index 41ed39390..429034dff 100644 --- a/earthly/rust/Earthfile +++ b/earthly/rust/Earthfile @@ -2,57 +2,90 @@ VERSION 0.7 # cspell: words rustup rustc automake autotools xutils miri nextest kani +# cspell: words TARGETPLATFORM TARGETOS TARGETARCH TARGETVARIANT +# cspell: words USERPLATFORM USEROS USERARCH USERVARIANT +# cspell: words ripgrep colordiff rustfmt stdcfgs toolset toolsets readelf # Base Rustup build container. -rustup: - # Base it on Debian bookworm-slim - FROM debian:bookworm-slim +rust-base: + ARG TARGETPLATFORM + ARG TARGETOS + ARG TARGETARCH + ARG TARGETVARIANT + ARG USERPLATFORM + ARG USEROS + ARG USERARCH + ARG USERVARIANT + + + # This is our base Host toolset, and rustup. + # The ACTUAL version of rust that will be used, and available targets + # is controlled by a `rust-toolchain.toml` file when the RUST_SETUP UDC is run. + # HOWEVER, It is enforced that the rust version in `rust-toolchain.toml` MUST match this version. + FROM rust:1.73-alpine3.18 + + RUN echo "TARGETPLATFORM = $TARGETPLATFORM"; \ + echo "TARGETOS = $TARGETOS"; \ + echo "TARGETARCH = $TARGETARCH"; \ + echo "TARGETVARIANT = $TARGETVARIANT"; \ + echo "USERPLATFORM = $USERPLATFORM"; \ + echo "USEROS = $USEROS"; \ + echo "USERARCH = $USERARCH"; \ + echo "USERVARIANT = $USERVARIANT"; - WORKDIR /root - - # Set necessary env vars from this setup. - ENV RUSTUP_HOME=/usr/local/rustup - ENV CARGO_HOME=/usr/local/cargo - ENV CARGO_HOME_BIN=$CARGO_HOME/bin - ENV PATH=$CARGO_HOME_BIN:$PATH - # Ensure correct directory permissions on the install locations. - RUN mkdir -p $RUSTUP_HOME && \ - mkdir -p $CARGO_HOME_BIN && \ - chmod -R a+w $RUSTUP_HOME $CARGO_HOME + WORKDIR /root # Install necessary packages # Expand this list as needed, rather than adding more tools in later containers. - RUN apt-get update && \ - apt-get install --no-install-recommends -y \ - ca-certificates \ - curl \ - file \ - build-essential \ - autoconf \ - automake \ - autotools-dev \ - libtool \ - xutils-dev \ + RUN apk add --no-cache \ + musl-dev \ mold \ - python3 \ - python3-pip \ - musl-tools \ - clang && \ - rm -rf /var/lib/apt/lists/* + clang \ + ripgrep \ + bash \ + colordiff \ + graphviz - # Install OpenSSL here but ONLY if we can't avoid using it. + # Make sure we have the clippy linter. + RUN rustup component add clippy - # Install rustup. - RUN curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain none -y -v + # Install a nightly toolchain which matches. + RUN rustup toolchain install nightly --component miri --component rust-src --component rustfmt --component clippy # Install the default cargo config. - COPY config.toml $CARGO_HOME/config.toml + COPY stdcfgs/cargo_config.toml $CARGO_HOME/config.toml + + # Install rust based tooling + # Install tools we use commonly with `cargo`. + # Note, we disable static compiles for tools, specifically, as its not required. + # These tools are not artifacts and we do not use them in production. + RUN cargo install cargo-nextest --version=0.9.59 && \ + cargo install cargo-machete --version=0.6.0 && \ + cargo install refinery_cli --version=0.8.11 && \ + cargo install cargo-deny --version=0.14.3 && \ + cargo install cargo-modules --version=0.10.2 + + # Universal build scripts we will always need and are not target dependent. + COPY --dir scripts /scripts + + # Standardized Rust configs. + # Build will refuse to proceed if the projects rust configs do not match these. + # This is to enforce consistent compiler and tool configuration on local setup and CI builds. + COPY --dir stdcfgs /stdcfgs + +# Builds all the rust-base targets for each supported DOCKER architecture. +# Currently only used for multi-platform cross build testing. +# This will ONLY work if you have `qemu` properly setup on linux and `rosetta` for +# docker enabled on Mac. +# Again, this is just a test target, and not for general use. +rust-base-all-hosts: + BUILD --platform=linux/amd64 --platform=linux/arm64 +rust-base # Common Rust setup # Parameters: # * toolchain : The `rust-toolchain` toml file. -RUST_SETUP: +SETUP: COMMAND ARG toolchain=./rust-toolchain.toml @@ -62,35 +95,153 @@ RUST_SETUP: # Copy our toolchain dependency. COPY $toolchain ./rust-toolchain.toml - ENV default_rust_channel=$(grep -oP 'channel\s*=\s*"\K[^"]+' rust-toolchain.toml) + ENV default_rust_channel=$(rg -oP 'channel\s*=\s*"\K[^"]+' rust-toolchain.toml) + + # Check that `default_rust_channel` and $RUST_VERSION from the rust-base container are exactly the same. + # This ensures CI Rust version and local rust version are properly aligned and prevents version skew. + RUN /scripts/verify_toolchain.sh $default_rust_channel $RUST_VERSION # Install pinned Rustup from `rust-toolchain.toml` # Plus nightly latest so we can use it for docs, lints, etc. RUN rustup default $default_rust_channel && \ rustup show && \ - rustup toolchain install nightly --component miri --component rust-src && \ cargo --version && \ cargo +nightly --version - # Install tools we use commonly with `cargo`. - RUN cargo install cargo-nextest --locked && \ - cargo install refinery_cli --locked && \ - cargo install cargo-machete --locked -# Test rust build container -check: - FROM +rustup +CP_SRC: + # Copy the build src using this. + COMMAND + # This can be one directory like `"src/*"` or multiple src separated by `","`: + # eg, "example/Cargo.toml, example/Cargo.lock, example/src" + ARG src="" - DO +RUST_SETUP --toolchain=example/rust-toolchain.toml + # ONLY copy whats needed to build. Not everything. + # Note: rust-toolchain.toml was already copied when rust was setup. + # Minimizing whats copied reduces needless cache misses. + FOR --sep=", " file IN $src + COPY --dir $file . + END - # Check all the expected tooling is installed and works for both the stable and nightly versions. - RUN rustc --version && \ - rustc +nightly --version && \ - cargo --version && \ - cargo +nightly --version && \ - cargo clippy --version && \ - cargo +nightly clippy --version && \ - cargo nextest --version && \ - cargo machete --version \ - refinery --version && \ - mold --version + RUN ls -al + + +# Steps we do during the `check` CI phase for all Rust programs +CHECK: + COMMAND + + # This is set up so that ALL checks are run and it will fail if any fail. + # This improves visibility into all issues that need to be corrected for `check` + # to pass without needing to iterate excessively. + RUN /scripts/std_checks.sh + +# Check if the build executable, isn't a busted mess. +SMOKE_TEST: + COMMAND + ARG TARGETPLATFORM + ARG bin + + RUN ldd target/$TARGETARCH/release/$bin + RUN readelf -p .comment target/$TARGETARCH/release/$bin + RUN strip -v target/$TARGETARCH/release/$bin + + # ALL executables MUST have `--help` as an option. + RUN target/$TARGETARCH/release/$bin --help + + +# Set up our target toolchains, and copy our files. +builder: + FROM +rust-base + + DO +SETUP --toolchain=example/rust-toolchain.toml + + DO +CP_SRC --src="example/*" + +# Test rust build container - Use best architecture host tools. +check-hosted: + FROM +builder + + DO +CHECK + +# Test which runs check with all supported host tooling. Needs qemu or rosetta to run. +# Only used to validate tooling is working across host toolsets. +check-all-hosts: + BUILD --platform=linux/amd64 --platform=linux/arm64 +check-hosted + +build-hosted: + ARG TARGETPLATFORM + + # Build the service + FROM +builder + + RUN /scripts/std_build.sh + + DO +SMOKE_TEST --bin=hello_world + + SAVE ARTIFACT target/$TARGETARCH/doc doc + SAVE ARTIFACT target/$TARGETARCH/release/hello_world hello_world + +# Test which runs check with all supported host tooling. Needs qemu or rosetta to run. +# Only used to validate tooling is working across host toolsets. +build-all-hosts: + BUILD --platform=linux/amd64 --platform=linux/arm64 +build-hosted + +## ----------------------------------------------------------------------------- +## +## Standard CI targets. +## +## These targets are discovered and executed automatically by CI. + +# Run check using the most efficient host tooling +# CI Automated Entry point. +check: + FROM busybox + # This is necessary to pick the correct architecture build to suit the native machine. + # It primarily ensures that Darwin/Arm builds work as expected without needing x86 emulation. + # All target implementation of this should follow this pattern. + ARG USERARCH + + IF [ "$USERARCH" == "arm64" ] + BUILD --platform=linux/arm64 +check-hosted + ELSE + BUILD --platform=linux/amd64 +check-hosted + END + +# Run build using the most efficient host tooling +# CI Automated Entry point. +build: + FROM busybox + # This is necessary to pick the correct architecture build to suit the native machine. + # It primarily ensures that Darwin/Arm builds work as expected without needing x86 emulation. + # All target implementation of this should follow this pattern. + ARG USERARCH + + IF [ "$USERARCH" == "arm64" ] + BUILD --platform=linux/arm64 +build-hosted + ELSE + BUILD --platform=linux/amd64 +build-hosted + END + + +# This step will build any packages we would intend to publish or integration test. +package: + FROM scratch + +# Run integration tests on all packages built during the `package` step. +integrate: + FROM scratch + +# Publish packages if all integration tests have passed. +# (Failure to pass tests will prevent packages being published.) +publish: + FROM scratch + +## ----------------------------------------------------------------------------- + +# This step simulates the full CI run for local purposes only. +local-ci-run: + BUILD +check + BUILD +build + BUILD +package + BUILD +integrate + BUILD +publish \ No newline at end of file diff --git a/earthly/rust/config.toml b/earthly/rust/config.toml deleted file mode 100644 index 6d6820327..000000000 --- a/earthly/rust/config.toml +++ /dev/null @@ -1,52 +0,0 @@ -# Use MOLD linker where possible. -# cspell: words rustflags armv gnueabihf msvc nextest - -# Should be the default to have fully static rust programs. -[target.x86_64-unknown-linux-musl] -linker = "clang" -rustflags = [ - "-C", "link-arg=-fuse-ld=/usr/bin/mold", - "-C", "target-feature=+crt-static" -] - -[target.x86_64-unknown-linux-gnu] -linker = "clang" -rustflags = [ - "-C", "link-arg=-fuse-ld=/usr/bin/mold", - # "-C", "target-feature=+crt-static" - proc-macro doesn't work with it. `https://github.com/rust-lang/rust/issues/78210` -] - -[target.aarch64-unknown-linux-gnu] -linker = "clang" -rustflags = [ - "-C", "link-arg=-fuse-ld=/usr/bin/mold", - # "-C", "target-feature=+crt-static" - proc-macro doesn't work with it. `https://github.com/rust-lang/rust/issues/78210` -] - -[target.aarch64-unknown-linux-musl] -linker = "clang" -rustflags = [ - "-C", "link-arg=-fuse-ld=/usr/bin/mold", - "-C", "target-feature=+crt-static" -] - -[target.armv7-unknown-linux-gnueabihf] -linker = "clang" -rustflags = [ - "-C", "link-arg=-fuse-ld=/usr/bin/mold", - "-C", "target-feature=+crt-static" -] - -[target.x86_64-pc-windows-gnu] -linker = "clang" -rustflags = [ - "-C", "link-arg=-fuse-ld=/usr/bin/mold", - "-C", "target-feature=+crt-static" -] - -[target.x86_64-pc-windows-msvc] -linker = "clang" -rustflags = [ - "-C", "link-arg=-fuse-ld=/usr/bin/mold", - "-C", "target-feature=+crt-static" -] diff --git a/earthly/rust/example/.cargo/config.toml b/earthly/rust/example/.cargo/config.toml new file mode 100644 index 000000000..e8463c6a5 --- /dev/null +++ b/earthly/rust/example/.cargo/config.toml @@ -0,0 +1,129 @@ +# Use MOLD linker where possible, but ONLY in CI applicable targets. +# cspell: words rustflags armv gnueabihf msvc nextest idents rustdocflags +# cspell: words rustdoc lintfix lintrestrict testfast testdocs codegen testci +# cspell: words fmtchk fmtfix + +# Configure how Docker container targets build. + +# If you want to customize these targets for a local build, then customize them in you: +# $CARGO_HOME/config.toml +# NOT in the project itself. +# These targets are ONLY the targets used by CI and inside docker builds. + +# DO NOT remove `"-C", "target-feature=+crt-static"` from the rustflags for these targets. + +# Should be the default to have fully static rust programs in CI +[target.x86_64-unknown-linux-musl] +linker = "clang" +rustflags = [ + "-C", "link-arg=-fuse-ld=/usr/bin/mold", + "-C", "target-feature=-crt-static" +] + +# Should be the default to have fully static rust programs in CI +[target.aarch64-unknown-linux-musl] +linker = "clang" +rustflags = [ + "-C", "link-arg=-fuse-ld=/usr/bin/mold", + "-C", "target-feature=-crt-static" +] + + +[build] + +rustflags = [ + "-D", + "warnings", + "-D", + "missing_docs", + "-D", + "let_underscore_drop", + "-D", + "non_ascii_idents", + "-D", + "single_use_lifetimes", + "-D", + "trivial_casts", + "-D", + "trivial_numeric_casts", +] + +rustdocflags = [ + "-D", + "warnings", + "-D", + "missing_docs", + "-D", + "rustdoc::broken_intra_doc_links", + "-D", + "rustdoc::invalid_codeblock_attributes", + "-D", + "rustdoc::invalid_html_tags", + "-D", + "rustdoc::invalid_rust_codeblocks", + "-D", + "rustdoc::bare_urls", + "-D", + "rustdoc::unescaped_backticks", +] + +[profile.dev] +opt-level = 1 +debug = true +debug-assertions = true +overflow-checks = true +lto = false +panic = 'unwind' +incremental = true +codegen-units = 256 + +[profile.release] +opt-level = 3 +debug = false +debug-assertions = false +overflow-checks = false +lto = "thin" +panic = 'unwind' +incremental = false +codegen-units = 16 + +[profile.test] +opt-level = 3 +debug = true +lto = false +debug-assertions = true +incremental = true +codegen-units = 256 + +[profile.bench] +opt-level = 3 +debug = false +debug-assertions = false +overflow-checks = false +lto = "thin" +incremental = false +codegen-units = 16 + + +[alias] +lint = "clippy -- -D warnings -D clippy::pedantic -D clippy::unwrap_used -D clippy::expect_used -D clippy::exit -D clippy::get_unwrap -D clippy::index_refutable_slice -D clippy::indexing_slicing -D clippy::match_on_vec_items -D clippy::match_wild_err_arm -D clippy::missing_panics_doc -D clippy::panic -D clippy::string_slice -D clippy::unchecked_duration_subtraction -D clippy::unreachable -D clippy::missing_docs_in_private_items" +lintfix = "clippy -- -D warnings -D clippy::pedantic -D clippy::unwrap_used -D clippy::expect_used -D clippy::exit -D clippy::get_unwrap -D clippy::index_refutable_slice -D clippy::indexing_slicing -D clippy::match_on_vec_items -D clippy::match_wild_err_arm -D clippy::missing_panics_doc -D clippy::panic -D clippy::string_slice -D clippy::unchecked_duration_subtraction -D clippy::unreachable" +lintrestrict = "clippy -- -D warnings -D clippy::pedantic -D clippy::restriction -D clippy::missing_docs_in_private_items" +lint-vscode = "clippy --workspace --message-format=json-diagnostic-rendered-ansi --all-targets -- -D warnings -D clippy::pedantic -D clippy::unwrap_used -D clippy::expect_used -D clippy::exit -D clippy::get_unwrap -D clippy::index_refutable_slice -D clippy::indexing_slicing -D clippy::match_on_vec_items -D clippy::match_wild_err_arm -D clippy::missing_panics_doc -D clippy::panic -D clippy::string_slice -D clippy::unchecked_duration_subtraction -D clippy::unreachable -D clippy::missing_docs_in_private_items" + +docs = "doc --workspace -r --all-features --no-deps --bins --document-private-items --examples --locked" +# nightly docs build broken... when they are'nt we can enable these docs... --unit-graph --timings=html,json -Z unstable-options" +testfast = "nextest run --release --workspace --locked" +testci = "nextest run --release --workspace --locked -P ci" +testdocs = "test --doc --release --workspace --locked" + +# Rust formatting, MUST be run with +nightly +fmtchk = "fmt -- --check -v --color=always" +fmtfix = "fmt -- -v" + +[term] +quiet = false # whether cargo output is quiet +verbose = true # whether cargo provides verbose output +color = 'always' # whether cargo colorizes output use `CARGO_TERM_COLOR="off"` to disable. +progress.when = 'auto' # whether cargo shows progress bar +progress.width = 80 # width of progress bar diff --git a/earthly/rust/example/.config/nextest.toml b/earthly/rust/example/.config/nextest.toml new file mode 100644 index 000000000..ebc7d7390 --- /dev/null +++ b/earthly/rust/example/.config/nextest.toml @@ -0,0 +1,49 @@ +# cspell: words nextest scrollability testcase +[store] +# The directory under the workspace root at which nextest-related files are +# written. Profile-specific storage is currently written to dir/. +# dir = "target/nextest" + +[profile.default] +# Print out output for failing tests as soon as they fail, and also at the end +# of the run (for easy scrollability). +failure-output = "immediate-final" + +# Do not cancel the test run on the first failure. +fail-fast = true + +status-level = "all" +final-status-level = "all" + +[profile.ci] +# Print out output for failing tests as soon as they fail, and also at the end +# of the run (for easy scrollability). +failure-output = "immediate-final" +# Do not cancel the test run on the first failure. +fail-fast = false + +status-level = "all" +final-status-level = "all" + + +[profile.ci.junit] +# Output a JUnit report into the given file inside 'store.dir/'. +# If unspecified, JUnit is not written out. + +path = "junit.xml" + +# The name of the top-level "report" element in JUnit report. If aggregating +# reports across different test runs, it may be useful to provide separate names +# for each report. +report-name = "cat-gateway" + +# Whether standard output and standard error for passing tests should be stored in the JUnit report. +# Output is stored in the and elements of the element. +store-success-output = true + +# Whether standard output and standard error for failing tests should be stored in the JUnit report. +# Output is stored in the and elements of the element. +# +# Note that if a description can be extracted from the output, it is always stored in the +# element. +store-failure-output = true diff --git a/earthly/rust/example/Cargo.lock b/earthly/rust/example/Cargo.lock new file mode 100644 index 000000000..61dfd6fe2 --- /dev/null +++ b/earthly/rust/example/Cargo.lock @@ -0,0 +1,739 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "aho-corasick" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +dependencies = [ + "memchr", +] + +[[package]] +name = "anes" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" + +[[package]] +name = "anstream" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" + +[[package]] +name = "anstyle-parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "317b9a89c1868f5ea6ff1d9539a69f45dffc21ce321ac1fd1160dfa48c8e2140" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628" +dependencies = [ + "anstyle", + "windows-sys", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "bitflags" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" + +[[package]] +name = "bumpalo" +version = "3.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" + +[[package]] +name = "cast" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "ciborium" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "effd91f6c78e5a4ace8a5d3c0b6bfaec9e2baaef55f3efc00e45fb2e477ee926" +dependencies = [ + "ciborium-io", + "ciborium-ll", + "serde", +] + +[[package]] +name = "ciborium-io" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdf919175532b369853f5d5e20b26b43112613fd6fe7aee757e35f7a44642656" + +[[package]] +name = "ciborium-ll" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "defaa24ecc093c77630e6c15e17c51f5e187bf35ee514f4e2d67baaa96dae22b" +dependencies = [ + "ciborium-io", + "half", +] + +[[package]] +name = "clap" +version = "4.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac495e00dcec98c83465d5ad66c5c4fabd652fd6686e7c6269b117e729a6f17b" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c77ed9a32a62e6ca27175d00d29d05ca32e396ea1eb5fb01d8256b669cec7663" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" + +[[package]] +name = "colorchoice" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" + +[[package]] +name = "criterion" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2b12d017a929603d80db1831cd3a24082f8137ce19c69e6447f54f5fc8d692f" +dependencies = [ + "anes", + "cast", + "ciborium", + "clap", + "criterion-plot", + "is-terminal", + "itertools", + "num-traits", + "once_cell", + "oorandom", + "plotters", + "rayon", + "regex", + "serde", + "serde_derive", + "serde_json", + "tinytemplate", + "walkdir", +] + +[[package]] +name = "criterion-plot" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1" +dependencies = [ + "cast", + "itertools", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" +dependencies = [ + "cfg-if", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" +dependencies = [ + "autocfg", + "cfg-if", + "crossbeam-utils", + "memoffset", + "scopeguard", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "either" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" + +[[package]] +name = "errno" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "half" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "hello_world" +version = "0.1.0" +dependencies = [ + "clap", + "criterion", +] + +[[package]] +name = "hermit-abi" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" + +[[package]] +name = "is-terminal" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" +dependencies = [ + "hermit-abi", + "rustix", + "windows-sys", +] + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" + +[[package]] +name = "js-sys" +version = "0.3.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "libc" +version = "0.2.149" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" + +[[package]] +name = "linux-raw-sys" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" + +[[package]] +name = "log" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" + +[[package]] +name = "memchr" +version = "2.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" + +[[package]] +name = "memoffset" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num-traits" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" + +[[package]] +name = "oorandom" +version = "11.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" + +[[package]] +name = "plotters" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2c224ba00d7cadd4d5c660deaf2098e5e80e07846537c51f9cfa4be50c1fd45" +dependencies = [ + "num-traits", + "plotters-backend", + "plotters-svg", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "plotters-backend" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e76628b4d3a7581389a35d5b6e2139607ad7c75b17aed325f210aa91f4a9609" + +[[package]] +name = "plotters-svg" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38f6d39893cca0701371e3c27294f09797214b86f1fb951b89ade8ec04e2abab" +dependencies = [ + "plotters-backend", +] + +[[package]] +name = "proc-macro2" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rayon" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "regex" +version = "1.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" + +[[package]] +name = "rustix" +version = "0.38.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys", +] + +[[package]] +name = "ryu" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "serde" +version = "1.0.190" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91d3c334ca1ee894a2c6f6ad698fe8c435b76d504b13d436f0685d648d6d96f7" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.190" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67c5609f394e5c2bd7fc51efda478004ea80ef42fee983d5c67a65e34f32c0e3" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "syn" +version = "2.0.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tinytemplate" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" +dependencies = [ + "serde", + "serde_json", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "utf8parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" + +[[package]] +name = "walkdir" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "wasm-bindgen" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" + +[[package]] +name = "web-sys" +version = "0.3.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" diff --git a/earthly/rust/example/Cargo.toml b/earthly/rust/example/Cargo.toml new file mode 100644 index 000000000..de0ecb52d --- /dev/null +++ b/earthly/rust/example/Cargo.toml @@ -0,0 +1,27 @@ +[package] +name = "hello_world" +version = "0.1.0" +edition = "2021" +license = "MIT OR Apache-2.0" + +[dependencies] +clap = {version= "4.4.7", features = ["derive" ] } + +[dev-dependencies] +criterion = { version = "0.5.1", features = ["html_reports"] } + +[lib] +name = "hello_world_lib" +path = "src/lib.rs" + +[[bin]] +name = "hello_world" +path = "src/main.rs" + +[[test]] +name = "integration_test" +harness = false + +[[bench]] +name = "benchmark" +harness = false diff --git a/earthly/rust/example/README.md b/earthly/rust/example/README.md new file mode 100644 index 000000000..81a6e9a14 --- /dev/null +++ b/earthly/rust/example/README.md @@ -0,0 +1,4 @@ +# Example Rust Project + +This is an simple but hopefully full featured example rust project. +It is used to test both our Catalyst-CI Rust building infrastructure and serve as a template for its use. diff --git a/earthly/rust/example/benches/benchmark.rs b/earthly/rust/example/benches/benchmark.rs new file mode 100644 index 000000000..9268cfb6b --- /dev/null +++ b/earthly/rust/example/benches/benchmark.rs @@ -0,0 +1,17 @@ +//! Simple benchmark example +use criterion::{black_box, criterion_group, criterion_main, Criterion}; + +fn fibonacci(n: u64) -> u64 { + match n { + 0 => 1, + 1 => 1, + n => fibonacci(n - 1) + fibonacci(n - 2), + } +} + +fn criterion_benchmark(c: &mut Criterion) { + c.bench_function("fib 20", |b| b.iter(|| fibonacci(black_box(20)))); +} + +criterion_group!(benches, criterion_benchmark); +criterion_main!(benches); diff --git a/earthly/rust/example/clippy.toml b/earthly/rust/example/clippy.toml new file mode 100644 index 000000000..154626ef4 --- /dev/null +++ b/earthly/rust/example/clippy.toml @@ -0,0 +1 @@ +allow-unwrap-in-tests = true diff --git a/earthly/rust/example/deny.toml b/earthly/rust/example/deny.toml new file mode 100644 index 000000000..b11e9e887 --- /dev/null +++ b/earthly/rust/example/deny.toml @@ -0,0 +1,274 @@ +# This template contains all of the possible sections and their default values + +# cspell: words rustc RUSTSEC dotgraphs reqwest rustls pemfile webpki + +# Note that all fields that take a lint level have these possible values: +# * deny - An error will be produced and the check will fail +# * warn - A warning will be produced, but the check will not fail +# * allow - No warning or error will be produced, though in some cases a note +# will be + +# The values provided in this template are the default values that will be used +# when any section or field is not specified in your own configuration + +# Root options + +# If 1 or more target triples (and optionally, target_features) are specified, +# only the specified targets will be checked when running `cargo deny check`. +# This means, if a particular package is only ever used as a target specific +# dependency, such as, for example, the `nix` crate only being used via the +# `target_family = "unix"` configuration, that only having windows targets in +# this list would mean the nix crate, as well as any of its exclusive +# dependencies not shared by any other crates, would be ignored, as the target +# list here is effectively saying which targets you are building for. +targets = [ + # The triple can be any string, but only the target triples built in to + # rustc (as of 1.40) can be checked against actual config expressions + #{ triple = "x86_64-unknown-linux-musl" }, + # You can also specify which target_features you promise are enabled for a + # particular target. target_features are currently not validated against + # the actual valid features supported by the target architecture. + #{ triple = "wasm32-unknown-unknown", features = ["atomics"] }, +] +# When creating the dependency graph used as the source of truth when checks are +# executed, this field can be used to prune crates from the graph, removing them +# from the view of cargo-deny. This is an extremely heavy hammer, as if a crate +# is pruned from the graph, all of its dependencies will also be pruned unless +# they are connected to another crate in the graph that hasn't been pruned, +# so it should be used with care. The identifiers are [Package ID Specifications] +# (https://doc.rust-lang.org/cargo/reference/pkgid-spec.html) +#exclude = [] +# If true, metadata will be collected with `--all-features`. Note that this can't +# be toggled off if true, if you want to conditionally enable `--all-features` it +# is recommended to pass `--all-features` on the cmd line instead +all-features = false +# If true, metadata will be collected with `--no-default-features`. The same +# caveat with `all-features` applies +no-default-features = false +# If set, these feature will be enabled when collecting metadata. If `--features` +# is specified on the cmd line they will take precedence over this option. +#features = [] +# When outputting inclusion graphs in diagnostics that include features, this +# option can be used to specify the depth at which feature edges will be added. +# This option is included since the graphs can be quite large and the addition +# of features from the crate(s) to all of the graph roots can be far too verbose. +# This option can be overridden via `--feature-depth` on the cmd line +feature-depth = 1 + +# This section is considered when running `cargo deny check advisories` +# More documentation for the advisories section can be found here: +# https://embarkstudios.github.io/cargo-deny/checks/advisories/cfg.html +[advisories] +# The path where the advisory database is cloned/fetched into +db-path = "~/.cargo/advisory-db" +# The url(s) of the advisory databases to use +db-urls = ["https://github.com/rustsec/advisory-db"] +# The lint level for security vulnerabilities +vulnerability = "deny" +# The lint level for unmaintained crates +unmaintained = "warn" +# The lint level for crates that have been yanked from their source registry +yanked = "warn" +# The lint level for crates with security notices. +notice = "warn" +# A list of advisory IDs to ignore. Note that ignored advisories will still +# output a note when they are encountered. +ignore = [ + #"RUSTSEC-0000-0000", +] +# Threshold for security vulnerabilities, any vulnerability with a CVSS score +# lower than the range specified will be ignored. Note that ignored advisories +# will still output a note when they are encountered. +# * None - CVSS Score 0.0 +# * Low - CVSS Score 0.1 - 3.9 +# * Medium - CVSS Score 4.0 - 6.9 +# * High - CVSS Score 7.0 - 8.9 +# * Critical - CVSS Score 9.0 - 10.0 +#severity-threshold = + +# If this is true, then cargo deny will use the git executable to fetch advisory database. +# If this is false, then it uses a built-in git library. +# Setting this to true can be helpful if you have special authentication requirements that cargo-deny does not support. +# See Git Authentication for more information about setting up git authentication. +#git-fetch-with-cli = true + +# This section is considered when running `cargo deny check licenses` +# More documentation for the licenses section can be found here: +# https://embarkstudios.github.io/cargo-deny/checks/licenses/cfg.html +[licenses] +# The lint level for crates which do not have a detectable license +unlicensed = "deny" +# List of explicitly allowed licenses +# See https://spdx.org/licenses/ for list of possible licenses +# [possible values: any SPDX 3.11 short identifier (+ optional exception)]. +allow = [ + "MIT", + "Apache-2.0", + "Unicode-DFS-2016", + "BSD-3-Clause" +] +# List of explicitly disallowed licenses +# See https://spdx.org/licenses/ for list of possible licenses +# [possible values: any SPDX 3.11 short identifier (+ optional exception)]. +deny = [ + #"Nokia", +] +# Lint level for licenses considered copyleft +copyleft = "deny" + +# Blanket approval or denial for OSI-approved or FSF Free/Libre licenses +# * both - The license will be approved if it is both OSI-approved *AND* FSF +# * either - The license will be approved if it is either OSI-approved *OR* FSF +# * osi - The license will be approved if it is OSI approved +# * fsf - The license will be approved if it is FSF Free +# * osi-only - The license will be approved if it is OSI-approved *AND NOT* FSF +# * fsf-only - The license will be approved if it is FSF *AND NOT* OSI-approved +# * neither - This predicate is ignored and the default lint level is used +allow-osi-fsf-free = "neither" +# Lint level used when no other predicates are matched +# 1. License isn't in the allow or deny lists +# 2. License isn't copyleft +# 3. License isn't OSI/FSF, or allow-osi-fsf-free = "neither" +default = "deny" +# The confidence threshold for detecting a license from license text. +# The higher the value, the more closely the license text must be to the +# canonical license text of a valid SPDX license file. +# [possible values: any between 0.0 and 1.0]. +confidence-threshold = 0.8 +# Allow 1 or more licenses on a per-crate basis, so that particular licenses +# aren't accepted for every possible crate as with the normal allow list +exceptions = [ + # Each entry is the crate and version constraint, and its specific allow + # list + #{ allow = ["Zlib"], name = "adler32", version = "*" }, +] + +# Some crates don't have (easily) machine readable licensing information, +# adding a clarification entry for it allows you to manually specify the +# licensing information +#[[licenses.clarify]] +# The name of the crate the clarification applies to +#name = "ring" +# The optional version constraint for the crate +#version = "*" +# The SPDX expression for the license requirements of the crate +#expression = "MIT AND ISC AND OpenSSL" +# One or more files in the crate's source used as the "source of truth" for +# the license expression. If the contents match, the clarification will be used +# when running the license check, otherwise the clarification will be ignored +# and the crate will be checked normally, which may produce warnings or errors +# depending on the rest of your configuration +#license-files = [ + # Each entry is a crate relative path, and the (opaque) hash of its contents + #{ path = "LICENSE", hash = 0xbd0eed23 } +#] + +[licenses.private] +# If true, ignores workspace crates that aren't published, or are only +# published to private registries. +# To see how to mark a crate as unpublished (to the official registry), +# visit https://doc.rust-lang.org/cargo/reference/manifest.html#the-publish-field. +ignore = false +# One or more private registries that you might publish crates to, if a crate +# is only published to private registries, and ignore is true, the crate will +# not have its license(s) checked +registries = [ + #"https://sekretz.com/registry +] + +# This section is considered when running `cargo deny check bans`. +# More documentation about the 'bans' section can be found here: +# https://embarkstudios.github.io/cargo-deny/checks/bans/cfg.html +[bans] +# Lint level for when multiple versions of the same crate are detected +multiple-versions = "warn" +# Lint level for when a crate version requirement is `*` +wildcards = "deny" +# The graph highlighting used when creating dotgraphs for crates +# with multiple versions +# * lowest-version - The path to the lowest versioned duplicate is highlighted +# * simplest-path - The path to the version with the fewest edges is highlighted +# * all - Both lowest-version and simplest-path are used +highlight = "all" +# The default lint level for `default` features for crates that are members of +# the workspace that is being checked. This can be overridden by allowing/denying +# `default` on a crate-by-crate basis if desired. +workspace-default-features = "allow" +# The default lint level for `default` features for external crates that are not +# members of the workspace. This can be overridden by allowing/denying `default` +# on a crate-by-crate basis if desired. +external-default-features = "allow" +# List of crates that are allowed. Use with care! +allow = [ + #{ name = "ansi_term", version = "=0.11.0" }, +] +# List of crates to deny +deny = [ + # Each entry the name of a crate and a version range. If version is + # not specified, all versions will be matched. + #{ name = "ansi_term", version = "=0.11.0" }, + # + # Wrapper crates can optionally be specified to allow the crate when it + # is a direct dependency of the otherwise banned crate + #{ name = "ansi_term", version = "=0.11.0", wrappers = [] }, + { name = "openssl" }, +] + +# List of features to allow/deny +# Each entry the name of a crate and a version range. If version is +# not specified, all versions will be matched. +#[[bans.features]] +#name = "reqwest" +# Features to not allow +#deny = ["json"] +# Features to allow +#allow = [ +# "rustls", +# "__rustls", +# "__tls", +# "hyper-rustls", +# "rustls", +# "rustls-pemfile", +# "rustls-tls-webpki-roots", +# "tokio-rustls", +# "webpki-roots", +#] +# If true, the allowed features must exactly match the enabled feature set. If +# this is set there is no point setting `deny` +#exact = true + +# Certain crates/versions that will be skipped when doing duplicate detection. +skip = [ + #{ name = "ansi_term", version = "=0.11.0" }, +] +# Similarly to `skip` allows you to skip certain crates during duplicate +# detection. Unlike skip, it also includes the entire tree of transitive +# dependencies starting at the specified crate, up to a certain depth, which is +# by default infinite. +skip-tree = [ + #{ name = "ansi_term", version = "=0.11.0", depth = 20 }, +] + +# This section is considered when running `cargo deny check sources`. +# More documentation about the 'sources' section can be found here: +# https://embarkstudios.github.io/cargo-deny/checks/sources/cfg.html +[sources] +# Lint level for what to happen when a crate from a crate registry that is not +# in the allow list is encountered +unknown-registry = "deny" +# Lint level for what to happen when a crate from a git repository that is not +# in the allow list is encountered +unknown-git = "deny" +# List of URLs for allowed crate registries. Defaults to the crates.io index +# if not specified. If it is specified but empty, no registries are allowed. +allow-registry = ["https://github.com/rust-lang/crates.io-index"] +# List of URLs for allowed Git repositories +allow-git = [] + +[sources.allow-org] +# 1 or more github.com organizations to allow git sources for +#github = [""] +# 1 or more gitlab.com organizations to allow git sources for +#gitlab = [""] +# 1 or more bitbucket.org organizations to allow git sources for +#bitbucket = [""] diff --git a/earthly/rust/example/rust-toolchain.toml b/earthly/rust/example/rust-toolchain.toml index c17e06b4c..dca770e1b 100644 --- a/earthly/rust/example/rust-toolchain.toml +++ b/earthly/rust/example/rust-toolchain.toml @@ -2,3 +2,4 @@ channel = "1.73.0" profile = "default" components = [ ] +targets = ["x86_64-unknown-linux-musl", "aarch64-unknown-linux-musl", "aarch64-apple-darwin"] \ No newline at end of file diff --git a/earthly/rust/example/rustfmt.toml b/earthly/rust/example/rustfmt.toml new file mode 100644 index 000000000..b0f20832c --- /dev/null +++ b/earthly/rust/example/rustfmt.toml @@ -0,0 +1,68 @@ +# Enable unstable features: +# * imports_indent +# * imports_layout +# * imports_granularity +# * group_imports +# * reorder_impl_items +# * trailing_comma +# * where_single_line +# * wrap_comments +# * comment_width +# * blank_lines_upper_bound +# * condense_wildcard_suffixes +# * force_multiline_blocks +# * format_code_in_doc_comments +# * format_generated_files +# * hex_literal_case +# * inline_attribute_width +# * normalize_comments +# * normalize_doc_attributes +# * overflow_delimited_expr +unstable_features = true + +# Compatibility: +edition = "2021" + +# Tabs & spaces - Defaults, listed for clarity +tab_spaces = 4 +hard_tabs = false + +# Commas. +trailing_comma = "Vertical" +match_block_trailing_comma = true + +# General width constraints. +max_width = 100 + +# Comments: +normalize_comments = true +normalize_doc_attributes = true +wrap_comments = true +comment_width = 90 # small excess is okay but prefer 80 +format_code_in_doc_comments = true +format_generated_files = false + +# Imports. +imports_indent = "Block" +imports_layout = "Mixed" +group_imports = "StdExternalCrate" +reorder_imports = true +imports_granularity = "Crate" + +# Arguments: +use_small_heuristics = "Default" +fn_params_layout = "Compressed" +overflow_delimited_expr = true +where_single_line = true + +# Misc: +inline_attribute_width = 0 +blank_lines_upper_bound = 1 +reorder_impl_items = true +use_field_init_shorthand = true +force_multiline_blocks = true +condense_wildcard_suffixes = true +hex_literal_case = "Upper" + +# Ignored files: +ignore = [] diff --git a/earthly/rust/example/src/lib.rs b/earthly/rust/example/src/lib.rs new file mode 100644 index 000000000..57b53cf6f --- /dev/null +++ b/earthly/rust/example/src/lib.rs @@ -0,0 +1,34 @@ +//! Our simple library crate. + +/// Format our hello message nicely. +#[must_use] +pub fn fmt_hello(name: &str, count: u8) -> String { + format!("Hello #{count:>3} {name}!") +} + +/// Excessive unit tests for this function. +#[cfg(test)] +mod tests { + use super::*; + + #[test] + /// Prove we can say hello to Dave on a 3 count. + fn test_hello_dave_3() { + let msg = fmt_hello("Dave", 3); + assert_eq!(msg, "Hello # 3 Dave!"); + } + + #[test] + /// Prove we can say hello to Sally on a 67 count. + fn test_hello_sally_67() { + let msg = fmt_hello("Sally", 67); + assert_eq!(msg, "Hello # 67 Sally!"); + } + + #[test] + /// Prove we can say hello to World on a 123 count. + fn test_hello_world_123() { + let msg = fmt_hello("World", 123); + assert_eq!(msg, "Hello #123 World!"); + } +} diff --git a/earthly/rust/example/src/main.rs b/earthly/rust/example/src/main.rs new file mode 100644 index 000000000..4f4a4bf22 --- /dev/null +++ b/earthly/rust/example/src/main.rs @@ -0,0 +1,27 @@ +//! Simple program to greet a person. +//! Used as a test of the Rust CI/CD pipeline. + +use clap::Parser; +use hello_world_lib::fmt_hello; + +/// Simple program to greet a person +#[derive(Parser, Debug)] +#[command(author, version, about, long_about = None)] +struct Args { + /// Name of the person to greet + #[arg(short, long)] + name: String, + + /// Number of times to greet + #[arg(short, long, default_value_t = 1)] + count: u8, +} + +/// The main entrypoint of this program. +fn main() { + let args = Args::parse(); + + for cnt in 0..args.count { + println!("{}", fmt_hello(&args.name, cnt)); + } +} diff --git a/earthly/rust/example/tests/integration_test.rs b/earthly/rust/example/tests/integration_test.rs new file mode 100644 index 000000000..9a5311499 --- /dev/null +++ b/earthly/rust/example/tests/integration_test.rs @@ -0,0 +1,11 @@ +//! Simple integration tests + +#[test] +/// Prove we can say hello to Dave on a 99 count. +fn test_hello_dave_99() { + let msg = fmt_hello("Dave", 99); + assert_eq!(msg, "Hello # 99 Dave!"); +} + +/// Dummy main needed because we are integration testing a binary package. +fn main() {} diff --git a/earthly/rust/scripts/README.md b/earthly/rust/scripts/README.md new file mode 100644 index 000000000..df629cafc --- /dev/null +++ b/earthly/rust/scripts/README.md @@ -0,0 +1,6 @@ +# Standard stage processing scripts + +These script files are used during the CI phases to simplify the Earthfiles and +to improve maintainability. + +They need to be `bash` scripts, and they need to execute on an `alpine` os base. diff --git a/earthly/rust/scripts/colors.sh b/earthly/rust/scripts/colors.sh new file mode 100644 index 000000000..3d1cbd2be --- /dev/null +++ b/earthly/rust/scripts/colors.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +# shellcheck disable=SC2034 # This file is intended to bo sourced. + +BLACK='\033[0;30m' +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[0;33m' +BLUE='\033[0;34m' +MAGENTA='\033[0;35m' +CYAN='\033[0;36m' +WHITE='\033[0;37m' +NC='\033[0m' # No Color + + +status() { + local rc="$1" + local message="$2" + shift 2 + + # Check if the command returned a bad status + if "$@"; then + # Append green OK to the message + echo -e "${CYAN}${message} : ${GREEN}[OK]${NC}" + else + # Append red ERROR to the message + echo -e "${CYAN}${message} : ${RED}[ERROR]${NC}" + rc=1 + fi + + # Return the current status + return "$rc" +} diff --git a/earthly/rust/scripts/std_build.sh b/earthly/rust/scripts/std_build.sh new file mode 100755 index 000000000..c74164b3e --- /dev/null +++ b/earthly/rust/scripts/std_build.sh @@ -0,0 +1,55 @@ +#!/usr/bin/env bash + +# cspell: words testci testdocs + +# This script is run inside the `check` stage for rust projects to perform all +# high level non-compilation checks. +# These are the Standard checks which ALL rust targets must pass before they +# will be scheduled to be `build`. +# Individual targets can add extra `check` steps, but these checks must always +# pass. + +source "$(dirname "$0")/colors.sh" + + +# This is set up so that ALL build steps are run and it will fail if any fail. +# This improves visibility into all issues that need to be corrected for `build` +# to pass without needing to iterate excessively. + +rc=0 + +## Build the code +status $rc "Building all code in the workspace" \ + cargo build --release --workspace --locked; rc=$? + +## Check the code passes all clippy lint checks. +status $rc "Checking all Clippy Lints in the workspace" \ + cargo lint; rc=$? + +## Check we can generate all the documentation +status $rc "Checking Documentation can be generated OK" \ + cargo docs; rc=$? + +## Check if all Self contained tests pass (Test that need no external resources). +status $rc "Checking Self contained Unit tests all pass" \ + cargo testci; rc=$? + +## Check if all documentation tests pass. +status $rc "Checking Documentation tests all pass" \ + cargo testdocs; rc=$? + +## Check if any benchmarks defined run (We don;t validate the results.) +status $rc "Checking Benchmarks all run to completion" \ + cargo bench --all-targets; rc=$? + +## Generate Module Trees for documentation purposes. +# cargo modules generate tree --orphans --types --traits --fns --tests --all-features --lib +# cargo modules generate tree --orphans --types --traits --fns --tests --all-features --bin + +## Generate Module Graphs for documentation purposes. +# cargo modules generate graph --all-features --types --traits --fns --modules --uses --externs --acyclic --lib +# cargo modules generate graph --all-features --types --traits --fns --modules --uses --externs --acyclic --bin + + +# Return an error if any of this fails. +exit $rc \ No newline at end of file diff --git a/earthly/rust/scripts/std_checks.sh b/earthly/rust/scripts/std_checks.sh new file mode 100755 index 000000000..8138dde73 --- /dev/null +++ b/earthly/rust/scripts/std_checks.sh @@ -0,0 +1,52 @@ +#!/usr/bin/env bash + +# cspell: words localfile vendorfile colordiff Naur fmtchk fmtfix rustfmt stdcfgs +# cspell: words nextest + +# This script is run inside the `check` stage for rust projects to perform all +# high level non-compilation checks. +# These are the Standard checks which ALL rust targets must pass before they +# will be scheduled to be `build`. +# Individual targets can add extra `check` steps, but these checks must always +# pass. + +source "$(dirname "$0")/colors.sh" + +# Checks if two files that should exist DO, and are equal. +# used to enforce consistency between local config files and the expected config locked in CI. +check_vendored_files() { + local rc=$1 + local localfile=$2 + local vendorfile=$3 + + status "$rc" "Checking if Local File '$localfile' == Vendored File '$vendorfile'" \ + colordiff -Naur "$localfile" "$vendorfile" + return $? +} + +# This is set up so that ALL checks are run and it will fail if any fail. +# This improves visibility into all issues that need to be corrected for `check` +# to pass without needing to iterate excessively. + +# Check if the rust src is properly formatted. +# Note, we run this first so we can print help how to fix. +status 0 "Checking Rust Code Format" cargo +nightly fmtchk; rc=$? +if [ $rc -ne 0 ]; then + echo -e " ${YELLOW}You can locally fix format errors by running: \`cargo +nightly fmtfix\`${NC}" +fi + +## Check if .cargo.config.toml has been modified. +check_vendored_files $rc .cargo/config.toml "$CARGO_HOME"/config.toml; rc=$? +check_vendored_files $rc rustfmt.toml /stdcfgs/rustfmt.toml; rc=$? +check_vendored_files $rc .config/nextest.toml /stdcfgs/nextest.toml; rc=$? +check_vendored_files $rc clippy.toml /stdcfgs/clippy.toml; rc=$? +check_vendored_files $rc deny.toml /stdcfgs/deny.toml; rc=$? + +# Check if we have unused dependencies declared in our Cargo.toml files. +status $rc "Checking for Unused Dependencies" cargo machete; rc=$? + +# Check if we have any supply chain issues with dependencies. +status $rc "Checking for Supply Chain Issues" cargo deny check; rc=$? + +# Return an error if any of this fails. +exit $rc \ No newline at end of file diff --git a/earthly/rust/scripts/verify_toolchain.sh b/earthly/rust/scripts/verify_toolchain.sh new file mode 100755 index 000000000..5de53599f --- /dev/null +++ b/earthly/rust/scripts/verify_toolchain.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +source "$(dirname "$0")/colors.sh" + +default_rust_channel=$1 +RUST_VERSION=$2 + +if [ "$default_rust_channel" != "$RUST_VERSION" ]; then + echo -e "${YELLOW}Your Rust Toolchain is set to Version : ${RED}$default_rust_channel${NC}" + echo -e "${YELLOW}This Builder requires it to be : ${GREEN}$RUST_VERSION${NC}" + echo -e "${RED}Either use the correct Earthly Rust Builder version from CI, or correct './rust-toolchain.toml' to match.${NC}" + exit 1; +fi diff --git a/earthly/rust/stdcfgs/README.md b/earthly/rust/stdcfgs/README.md new file mode 100644 index 000000000..f80360071 --- /dev/null +++ b/earthly/rust/stdcfgs/README.md @@ -0,0 +1,51 @@ +# Rust Standardized Configuration + + + +We define RUST Global Cargo Configurations here. +It is applied globally to all Rust Code built by Project Catalyst. + +There are many tools in the rust ecosystem, and there is not a single config file which controls them. +This directory contains our standardized configuration for these tools to ensure consistent use. +These files must be consistent with the Rust configs being used to build code in CI. +They are also important to be consistent on a local developers machine to ensure consistent environments. + +All configs exists here so that they can be used locally during development, as well as during CI builds. + +They will be checked during CI to ensure they have not been altered from the enforced standard. +The enforced standard can be referenced here: [Catalyst-CI Global Cargo Config](todo) + +If a file needs to be updated, please update it in the standard location first, have the PR +approved, and then update the equivalent file in the project repo to match it. + +Differences between these files and the enforced standards will prevent CI from accepting your PR. + +## `cargo_config.toml` + +This is the standard `.cargo/config.toml` file. + +Each Project Catalyst Repo that has Rust code must include this file in: + +```path +/.cargo/config.toml +``` + +## `clippy.toml` + +Clippy configuration options. +Goes in the Rust workspace root folder. + +## `nextest.toml` + +Configures the `nextest` test runner. +Goes in `/.config/nextest.toml` + +## `deny.toml` + +Configuration for cargo deny to enforce software supply chain control. +This file goes in `/deny.toml` + +## `rustfmt.toml` + +Configuration for `rustfmt`. +Goes in `/rustfmt.toml` diff --git a/earthly/rust/stdcfgs/cargo_config.toml b/earthly/rust/stdcfgs/cargo_config.toml new file mode 100644 index 000000000..e8463c6a5 --- /dev/null +++ b/earthly/rust/stdcfgs/cargo_config.toml @@ -0,0 +1,129 @@ +# Use MOLD linker where possible, but ONLY in CI applicable targets. +# cspell: words rustflags armv gnueabihf msvc nextest idents rustdocflags +# cspell: words rustdoc lintfix lintrestrict testfast testdocs codegen testci +# cspell: words fmtchk fmtfix + +# Configure how Docker container targets build. + +# If you want to customize these targets for a local build, then customize them in you: +# $CARGO_HOME/config.toml +# NOT in the project itself. +# These targets are ONLY the targets used by CI and inside docker builds. + +# DO NOT remove `"-C", "target-feature=+crt-static"` from the rustflags for these targets. + +# Should be the default to have fully static rust programs in CI +[target.x86_64-unknown-linux-musl] +linker = "clang" +rustflags = [ + "-C", "link-arg=-fuse-ld=/usr/bin/mold", + "-C", "target-feature=-crt-static" +] + +# Should be the default to have fully static rust programs in CI +[target.aarch64-unknown-linux-musl] +linker = "clang" +rustflags = [ + "-C", "link-arg=-fuse-ld=/usr/bin/mold", + "-C", "target-feature=-crt-static" +] + + +[build] + +rustflags = [ + "-D", + "warnings", + "-D", + "missing_docs", + "-D", + "let_underscore_drop", + "-D", + "non_ascii_idents", + "-D", + "single_use_lifetimes", + "-D", + "trivial_casts", + "-D", + "trivial_numeric_casts", +] + +rustdocflags = [ + "-D", + "warnings", + "-D", + "missing_docs", + "-D", + "rustdoc::broken_intra_doc_links", + "-D", + "rustdoc::invalid_codeblock_attributes", + "-D", + "rustdoc::invalid_html_tags", + "-D", + "rustdoc::invalid_rust_codeblocks", + "-D", + "rustdoc::bare_urls", + "-D", + "rustdoc::unescaped_backticks", +] + +[profile.dev] +opt-level = 1 +debug = true +debug-assertions = true +overflow-checks = true +lto = false +panic = 'unwind' +incremental = true +codegen-units = 256 + +[profile.release] +opt-level = 3 +debug = false +debug-assertions = false +overflow-checks = false +lto = "thin" +panic = 'unwind' +incremental = false +codegen-units = 16 + +[profile.test] +opt-level = 3 +debug = true +lto = false +debug-assertions = true +incremental = true +codegen-units = 256 + +[profile.bench] +opt-level = 3 +debug = false +debug-assertions = false +overflow-checks = false +lto = "thin" +incremental = false +codegen-units = 16 + + +[alias] +lint = "clippy -- -D warnings -D clippy::pedantic -D clippy::unwrap_used -D clippy::expect_used -D clippy::exit -D clippy::get_unwrap -D clippy::index_refutable_slice -D clippy::indexing_slicing -D clippy::match_on_vec_items -D clippy::match_wild_err_arm -D clippy::missing_panics_doc -D clippy::panic -D clippy::string_slice -D clippy::unchecked_duration_subtraction -D clippy::unreachable -D clippy::missing_docs_in_private_items" +lintfix = "clippy -- -D warnings -D clippy::pedantic -D clippy::unwrap_used -D clippy::expect_used -D clippy::exit -D clippy::get_unwrap -D clippy::index_refutable_slice -D clippy::indexing_slicing -D clippy::match_on_vec_items -D clippy::match_wild_err_arm -D clippy::missing_panics_doc -D clippy::panic -D clippy::string_slice -D clippy::unchecked_duration_subtraction -D clippy::unreachable" +lintrestrict = "clippy -- -D warnings -D clippy::pedantic -D clippy::restriction -D clippy::missing_docs_in_private_items" +lint-vscode = "clippy --workspace --message-format=json-diagnostic-rendered-ansi --all-targets -- -D warnings -D clippy::pedantic -D clippy::unwrap_used -D clippy::expect_used -D clippy::exit -D clippy::get_unwrap -D clippy::index_refutable_slice -D clippy::indexing_slicing -D clippy::match_on_vec_items -D clippy::match_wild_err_arm -D clippy::missing_panics_doc -D clippy::panic -D clippy::string_slice -D clippy::unchecked_duration_subtraction -D clippy::unreachable -D clippy::missing_docs_in_private_items" + +docs = "doc --workspace -r --all-features --no-deps --bins --document-private-items --examples --locked" +# nightly docs build broken... when they are'nt we can enable these docs... --unit-graph --timings=html,json -Z unstable-options" +testfast = "nextest run --release --workspace --locked" +testci = "nextest run --release --workspace --locked -P ci" +testdocs = "test --doc --release --workspace --locked" + +# Rust formatting, MUST be run with +nightly +fmtchk = "fmt -- --check -v --color=always" +fmtfix = "fmt -- -v" + +[term] +quiet = false # whether cargo output is quiet +verbose = true # whether cargo provides verbose output +color = 'always' # whether cargo colorizes output use `CARGO_TERM_COLOR="off"` to disable. +progress.when = 'auto' # whether cargo shows progress bar +progress.width = 80 # width of progress bar diff --git a/earthly/rust/stdcfgs/clippy.toml b/earthly/rust/stdcfgs/clippy.toml new file mode 100644 index 000000000..154626ef4 --- /dev/null +++ b/earthly/rust/stdcfgs/clippy.toml @@ -0,0 +1 @@ +allow-unwrap-in-tests = true diff --git a/earthly/rust/stdcfgs/deny.toml b/earthly/rust/stdcfgs/deny.toml new file mode 100644 index 000000000..b11e9e887 --- /dev/null +++ b/earthly/rust/stdcfgs/deny.toml @@ -0,0 +1,274 @@ +# This template contains all of the possible sections and their default values + +# cspell: words rustc RUSTSEC dotgraphs reqwest rustls pemfile webpki + +# Note that all fields that take a lint level have these possible values: +# * deny - An error will be produced and the check will fail +# * warn - A warning will be produced, but the check will not fail +# * allow - No warning or error will be produced, though in some cases a note +# will be + +# The values provided in this template are the default values that will be used +# when any section or field is not specified in your own configuration + +# Root options + +# If 1 or more target triples (and optionally, target_features) are specified, +# only the specified targets will be checked when running `cargo deny check`. +# This means, if a particular package is only ever used as a target specific +# dependency, such as, for example, the `nix` crate only being used via the +# `target_family = "unix"` configuration, that only having windows targets in +# this list would mean the nix crate, as well as any of its exclusive +# dependencies not shared by any other crates, would be ignored, as the target +# list here is effectively saying which targets you are building for. +targets = [ + # The triple can be any string, but only the target triples built in to + # rustc (as of 1.40) can be checked against actual config expressions + #{ triple = "x86_64-unknown-linux-musl" }, + # You can also specify which target_features you promise are enabled for a + # particular target. target_features are currently not validated against + # the actual valid features supported by the target architecture. + #{ triple = "wasm32-unknown-unknown", features = ["atomics"] }, +] +# When creating the dependency graph used as the source of truth when checks are +# executed, this field can be used to prune crates from the graph, removing them +# from the view of cargo-deny. This is an extremely heavy hammer, as if a crate +# is pruned from the graph, all of its dependencies will also be pruned unless +# they are connected to another crate in the graph that hasn't been pruned, +# so it should be used with care. The identifiers are [Package ID Specifications] +# (https://doc.rust-lang.org/cargo/reference/pkgid-spec.html) +#exclude = [] +# If true, metadata will be collected with `--all-features`. Note that this can't +# be toggled off if true, if you want to conditionally enable `--all-features` it +# is recommended to pass `--all-features` on the cmd line instead +all-features = false +# If true, metadata will be collected with `--no-default-features`. The same +# caveat with `all-features` applies +no-default-features = false +# If set, these feature will be enabled when collecting metadata. If `--features` +# is specified on the cmd line they will take precedence over this option. +#features = [] +# When outputting inclusion graphs in diagnostics that include features, this +# option can be used to specify the depth at which feature edges will be added. +# This option is included since the graphs can be quite large and the addition +# of features from the crate(s) to all of the graph roots can be far too verbose. +# This option can be overridden via `--feature-depth` on the cmd line +feature-depth = 1 + +# This section is considered when running `cargo deny check advisories` +# More documentation for the advisories section can be found here: +# https://embarkstudios.github.io/cargo-deny/checks/advisories/cfg.html +[advisories] +# The path where the advisory database is cloned/fetched into +db-path = "~/.cargo/advisory-db" +# The url(s) of the advisory databases to use +db-urls = ["https://github.com/rustsec/advisory-db"] +# The lint level for security vulnerabilities +vulnerability = "deny" +# The lint level for unmaintained crates +unmaintained = "warn" +# The lint level for crates that have been yanked from their source registry +yanked = "warn" +# The lint level for crates with security notices. +notice = "warn" +# A list of advisory IDs to ignore. Note that ignored advisories will still +# output a note when they are encountered. +ignore = [ + #"RUSTSEC-0000-0000", +] +# Threshold for security vulnerabilities, any vulnerability with a CVSS score +# lower than the range specified will be ignored. Note that ignored advisories +# will still output a note when they are encountered. +# * None - CVSS Score 0.0 +# * Low - CVSS Score 0.1 - 3.9 +# * Medium - CVSS Score 4.0 - 6.9 +# * High - CVSS Score 7.0 - 8.9 +# * Critical - CVSS Score 9.0 - 10.0 +#severity-threshold = + +# If this is true, then cargo deny will use the git executable to fetch advisory database. +# If this is false, then it uses a built-in git library. +# Setting this to true can be helpful if you have special authentication requirements that cargo-deny does not support. +# See Git Authentication for more information about setting up git authentication. +#git-fetch-with-cli = true + +# This section is considered when running `cargo deny check licenses` +# More documentation for the licenses section can be found here: +# https://embarkstudios.github.io/cargo-deny/checks/licenses/cfg.html +[licenses] +# The lint level for crates which do not have a detectable license +unlicensed = "deny" +# List of explicitly allowed licenses +# See https://spdx.org/licenses/ for list of possible licenses +# [possible values: any SPDX 3.11 short identifier (+ optional exception)]. +allow = [ + "MIT", + "Apache-2.0", + "Unicode-DFS-2016", + "BSD-3-Clause" +] +# List of explicitly disallowed licenses +# See https://spdx.org/licenses/ for list of possible licenses +# [possible values: any SPDX 3.11 short identifier (+ optional exception)]. +deny = [ + #"Nokia", +] +# Lint level for licenses considered copyleft +copyleft = "deny" + +# Blanket approval or denial for OSI-approved or FSF Free/Libre licenses +# * both - The license will be approved if it is both OSI-approved *AND* FSF +# * either - The license will be approved if it is either OSI-approved *OR* FSF +# * osi - The license will be approved if it is OSI approved +# * fsf - The license will be approved if it is FSF Free +# * osi-only - The license will be approved if it is OSI-approved *AND NOT* FSF +# * fsf-only - The license will be approved if it is FSF *AND NOT* OSI-approved +# * neither - This predicate is ignored and the default lint level is used +allow-osi-fsf-free = "neither" +# Lint level used when no other predicates are matched +# 1. License isn't in the allow or deny lists +# 2. License isn't copyleft +# 3. License isn't OSI/FSF, or allow-osi-fsf-free = "neither" +default = "deny" +# The confidence threshold for detecting a license from license text. +# The higher the value, the more closely the license text must be to the +# canonical license text of a valid SPDX license file. +# [possible values: any between 0.0 and 1.0]. +confidence-threshold = 0.8 +# Allow 1 or more licenses on a per-crate basis, so that particular licenses +# aren't accepted for every possible crate as with the normal allow list +exceptions = [ + # Each entry is the crate and version constraint, and its specific allow + # list + #{ allow = ["Zlib"], name = "adler32", version = "*" }, +] + +# Some crates don't have (easily) machine readable licensing information, +# adding a clarification entry for it allows you to manually specify the +# licensing information +#[[licenses.clarify]] +# The name of the crate the clarification applies to +#name = "ring" +# The optional version constraint for the crate +#version = "*" +# The SPDX expression for the license requirements of the crate +#expression = "MIT AND ISC AND OpenSSL" +# One or more files in the crate's source used as the "source of truth" for +# the license expression. If the contents match, the clarification will be used +# when running the license check, otherwise the clarification will be ignored +# and the crate will be checked normally, which may produce warnings or errors +# depending on the rest of your configuration +#license-files = [ + # Each entry is a crate relative path, and the (opaque) hash of its contents + #{ path = "LICENSE", hash = 0xbd0eed23 } +#] + +[licenses.private] +# If true, ignores workspace crates that aren't published, or are only +# published to private registries. +# To see how to mark a crate as unpublished (to the official registry), +# visit https://doc.rust-lang.org/cargo/reference/manifest.html#the-publish-field. +ignore = false +# One or more private registries that you might publish crates to, if a crate +# is only published to private registries, and ignore is true, the crate will +# not have its license(s) checked +registries = [ + #"https://sekretz.com/registry +] + +# This section is considered when running `cargo deny check bans`. +# More documentation about the 'bans' section can be found here: +# https://embarkstudios.github.io/cargo-deny/checks/bans/cfg.html +[bans] +# Lint level for when multiple versions of the same crate are detected +multiple-versions = "warn" +# Lint level for when a crate version requirement is `*` +wildcards = "deny" +# The graph highlighting used when creating dotgraphs for crates +# with multiple versions +# * lowest-version - The path to the lowest versioned duplicate is highlighted +# * simplest-path - The path to the version with the fewest edges is highlighted +# * all - Both lowest-version and simplest-path are used +highlight = "all" +# The default lint level for `default` features for crates that are members of +# the workspace that is being checked. This can be overridden by allowing/denying +# `default` on a crate-by-crate basis if desired. +workspace-default-features = "allow" +# The default lint level for `default` features for external crates that are not +# members of the workspace. This can be overridden by allowing/denying `default` +# on a crate-by-crate basis if desired. +external-default-features = "allow" +# List of crates that are allowed. Use with care! +allow = [ + #{ name = "ansi_term", version = "=0.11.0" }, +] +# List of crates to deny +deny = [ + # Each entry the name of a crate and a version range. If version is + # not specified, all versions will be matched. + #{ name = "ansi_term", version = "=0.11.0" }, + # + # Wrapper crates can optionally be specified to allow the crate when it + # is a direct dependency of the otherwise banned crate + #{ name = "ansi_term", version = "=0.11.0", wrappers = [] }, + { name = "openssl" }, +] + +# List of features to allow/deny +# Each entry the name of a crate and a version range. If version is +# not specified, all versions will be matched. +#[[bans.features]] +#name = "reqwest" +# Features to not allow +#deny = ["json"] +# Features to allow +#allow = [ +# "rustls", +# "__rustls", +# "__tls", +# "hyper-rustls", +# "rustls", +# "rustls-pemfile", +# "rustls-tls-webpki-roots", +# "tokio-rustls", +# "webpki-roots", +#] +# If true, the allowed features must exactly match the enabled feature set. If +# this is set there is no point setting `deny` +#exact = true + +# Certain crates/versions that will be skipped when doing duplicate detection. +skip = [ + #{ name = "ansi_term", version = "=0.11.0" }, +] +# Similarly to `skip` allows you to skip certain crates during duplicate +# detection. Unlike skip, it also includes the entire tree of transitive +# dependencies starting at the specified crate, up to a certain depth, which is +# by default infinite. +skip-tree = [ + #{ name = "ansi_term", version = "=0.11.0", depth = 20 }, +] + +# This section is considered when running `cargo deny check sources`. +# More documentation about the 'sources' section can be found here: +# https://embarkstudios.github.io/cargo-deny/checks/sources/cfg.html +[sources] +# Lint level for what to happen when a crate from a crate registry that is not +# in the allow list is encountered +unknown-registry = "deny" +# Lint level for what to happen when a crate from a git repository that is not +# in the allow list is encountered +unknown-git = "deny" +# List of URLs for allowed crate registries. Defaults to the crates.io index +# if not specified. If it is specified but empty, no registries are allowed. +allow-registry = ["https://github.com/rust-lang/crates.io-index"] +# List of URLs for allowed Git repositories +allow-git = [] + +[sources.allow-org] +# 1 or more github.com organizations to allow git sources for +#github = [""] +# 1 or more gitlab.com organizations to allow git sources for +#gitlab = [""] +# 1 or more bitbucket.org organizations to allow git sources for +#bitbucket = [""] diff --git a/earthly/rust/stdcfgs/nextest.toml b/earthly/rust/stdcfgs/nextest.toml new file mode 100644 index 000000000..ebc7d7390 --- /dev/null +++ b/earthly/rust/stdcfgs/nextest.toml @@ -0,0 +1,49 @@ +# cspell: words nextest scrollability testcase +[store] +# The directory under the workspace root at which nextest-related files are +# written. Profile-specific storage is currently written to dir/. +# dir = "target/nextest" + +[profile.default] +# Print out output for failing tests as soon as they fail, and also at the end +# of the run (for easy scrollability). +failure-output = "immediate-final" + +# Do not cancel the test run on the first failure. +fail-fast = true + +status-level = "all" +final-status-level = "all" + +[profile.ci] +# Print out output for failing tests as soon as they fail, and also at the end +# of the run (for easy scrollability). +failure-output = "immediate-final" +# Do not cancel the test run on the first failure. +fail-fast = false + +status-level = "all" +final-status-level = "all" + + +[profile.ci.junit] +# Output a JUnit report into the given file inside 'store.dir/'. +# If unspecified, JUnit is not written out. + +path = "junit.xml" + +# The name of the top-level "report" element in JUnit report. If aggregating +# reports across different test runs, it may be useful to provide separate names +# for each report. +report-name = "cat-gateway" + +# Whether standard output and standard error for passing tests should be stored in the JUnit report. +# Output is stored in the and elements of the element. +store-success-output = true + +# Whether standard output and standard error for failing tests should be stored in the JUnit report. +# Output is stored in the and elements of the element. +# +# Note that if a description can be extracted from the output, it is always stored in the +# element. +store-failure-output = true diff --git a/earthly/rust/stdcfgs/rustfmt.toml b/earthly/rust/stdcfgs/rustfmt.toml new file mode 100644 index 000000000..b0f20832c --- /dev/null +++ b/earthly/rust/stdcfgs/rustfmt.toml @@ -0,0 +1,68 @@ +# Enable unstable features: +# * imports_indent +# * imports_layout +# * imports_granularity +# * group_imports +# * reorder_impl_items +# * trailing_comma +# * where_single_line +# * wrap_comments +# * comment_width +# * blank_lines_upper_bound +# * condense_wildcard_suffixes +# * force_multiline_blocks +# * format_code_in_doc_comments +# * format_generated_files +# * hex_literal_case +# * inline_attribute_width +# * normalize_comments +# * normalize_doc_attributes +# * overflow_delimited_expr +unstable_features = true + +# Compatibility: +edition = "2021" + +# Tabs & spaces - Defaults, listed for clarity +tab_spaces = 4 +hard_tabs = false + +# Commas. +trailing_comma = "Vertical" +match_block_trailing_comma = true + +# General width constraints. +max_width = 100 + +# Comments: +normalize_comments = true +normalize_doc_attributes = true +wrap_comments = true +comment_width = 90 # small excess is okay but prefer 80 +format_code_in_doc_comments = true +format_generated_files = false + +# Imports. +imports_indent = "Block" +imports_layout = "Mixed" +group_imports = "StdExternalCrate" +reorder_imports = true +imports_granularity = "Crate" + +# Arguments: +use_small_heuristics = "Default" +fn_params_layout = "Compressed" +overflow_delimited_expr = true +where_single_line = true + +# Misc: +inline_attribute_width = 0 +blank_lines_upper_bound = 1 +reorder_impl_items = true +use_field_init_shorthand = true +force_multiline_blocks = true +condense_wildcard_suffixes = true +hex_literal_case = "Upper" + +# Ignored files: +ignore = []