From a190761e42f87f97df723f4acf166713f815a035 Mon Sep 17 00:00:00 2001 From: Bruce Mitchener Date: Wed, 13 Nov 2024 14:42:52 +0700 Subject: [PATCH] Use Linebender CI This also sets up the copyright headers on all files. The MSRV is now set to 1.65. A minimum of 1.60 was needed for `log` and 1.62 for using `x86_64-unknown-none` for the `no_std` CI. `usvg` claims to have an MSRV of 1.65 (although a later version is actually tested). Fix up the .gitignore while we're updating it. --- .github/copyright.sh | 24 +++ .github/workflows/ci.yml | 288 +++++++++++++++++++++++++++++++++ .github/workflows/main.yml | 21 --- .gitignore | 5 +- Cargo.lock | 42 +++++ Cargo.toml | 1 + examples/parse.rs | 3 + examples/select.rs | 3 + src/lib.rs | 3 + src/selector.rs | 3 + src/stream.rs | 3 + tests/declaration_tokenizer.rs | 3 + tests/select.rs | 3 + tests/selector_tokenizer.rs | 3 + tests/specificity.rs | 3 + tests/stylesheet.rs | 3 + tests/warnings.rs | 3 + 17 files changed, 389 insertions(+), 25 deletions(-) create mode 100755 .github/copyright.sh create mode 100644 .github/workflows/ci.yml delete mode 100644 .github/workflows/main.yml create mode 100644 Cargo.lock diff --git a/.github/copyright.sh b/.github/copyright.sh new file mode 100755 index 0000000..0822491 --- /dev/null +++ b/.github/copyright.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +# If there are new files with headers that can't match the conditions here, +# then the files can be ignored by an additional glob argument via the -g flag. +# For example: +# -g "!src/special_file.rs" +# -g "!src/special_directory" + +# Check all the standard Rust source files +output=$(rg "^// Copyright (19|20)[\d]{2} (.+ and )?the SimpleCSS Authors( and .+)?$\n^// SPDX-License-Identifier: Apache-2\.0 OR MIT$\n\n" --files-without-match --multiline -g "*.rs" -g "!vello_shaders/{shader,src/cpu}" .) + +if [ -n "$output" ]; then + echo -e "The following files lack the correct copyright header:\n" + echo $output + echo -e "\n\nPlease add the following header:\n" + echo "// Copyright $(date +%Y) the SimpleCSS Authors" + echo "// SPDX-License-Identifier: Apache-2.0 OR MIT" + echo -e "\n... rest of the file ...\n" + exit 1 +fi + +echo "All files have correct copyright headers." +exit 0 + diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..66d11aa --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,288 @@ +env: + # We aim to always test with the latest stable Rust toolchain, however we pin to a specific + # version like 1.70. Note that we only specify MAJOR.MINOR and not PATCH so that bugfixes still + # come automatically. If the version specified here is no longer the latest stable version, + # then please feel free to submit a PR that adjusts it along with the potential clippy fixes. + RUST_STABLE_VER: "1.82" # In quotes because otherwise (e.g.) 1.70 would be interpreted as 1.7 + # The purpose of checking with the minimum supported Rust toolchain is to detect its staleness. + # If the compilation fails, then the version specified here needs to be bumped up to reality. + # Be sure to also update the rust-version property in the workspace Cargo.toml file, + # plus all the README.md files of the affected packages. + RUST_MIN_VER: "1.65" + # List of packages that will be checked with the minimum supported Rust version. + # This should be limited to packages that are intended for publishing. + RUST_MIN_VER_PKGS: "-p simplecss" + # List of features that depend on the standard library and will be excluded from no_std checks. + FEATURES_DEPENDING_ON_STD: "std,default" + + +# Rationale +# +# We don't run clippy with --all-targets because then even --lib and --bins are compiled with +# dev dependencies enabled, which does not match how they would be compiled by users. +# A dev dependency might enable a feature that we need for a regular dependency, +# and checking with --all-targets would not find our feature requirements lacking. +# This problem still applies to cargo resolver version 2. +# Thus we split all the targets into two steps, one with --lib --bins +# and another with --tests --benches --examples. +# Also, we can't give --lib --bins explicitly because then cargo will error on binary-only packages. +# Luckily the default behavior of cargo with no explicit targets is the same but without the error. +# +# We use cargo-hack for a similar reason. Cargo's --workspace will do feature unification across +# the whole workspace. While cargo-hack will instead check each workspace package separately. +# +# Using cargo-hack also allows us to more easily test the feature matrix of our packages. +# We use --each-feature & --optional-deps which will run a separate check for every feature. +# +# We use cargo-nextest, which has a faster concurrency model for running tests. +# However cargo-nextest does not support running doc tests, so we also have a cargo test --doc step. +# For more information see https://github.com/nextest-rs/nextest/issues/16 +# +# The MSRV jobs run only cargo check because different clippy versions can disagree on goals and +# running tests introduces dev dependencies which may require a higher MSRV than the bare package. +# +# For no_std checks we target x86_64-unknown-none, because this target doesn't support std +# and as such will error out if our dependency tree accidentally tries to use std. +# https://doc.rust-lang.org/stable/rustc/platform-support/x86_64-unknown-none.html +# +# We don't save caches in the merge-group cases, because those caches will never be re-used (apart +# from the very rare cases where there are multiple PRs in the merge queue). +# This is because GitHub doesn't share caches between merge queues and the main branch. + +name: CI + +on: + pull_request: + merge_group: + # We run on push, even though the commit is the same as when we ran in merge_group. + # This allows the cache to be primed. + # See https://github.com/orgs/community/discussions/66430 + push: + branches: + - main + +jobs: + fmt: + name: formatting + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: install stable toolchain + uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ env.RUST_STABLE_VER }} + components: rustfmt + + - name: cargo fmt + run: cargo fmt --all --check + + - name: install ripgrep + run: | + sudo apt update + sudo apt install ripgrep + + - name: check copyright headers + run: bash .github/copyright.sh + + clippy-stable: + name: cargo clippy + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [windows-latest, macos-latest, ubuntu-latest] + steps: + - uses: actions/checkout@v4 + + - name: install stable toolchain + uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ env.RUST_STABLE_VER }} + targets: x86_64-unknown-none + components: clippy + + - name: install cargo-hack + uses: taiki-e/install-action@v2 + with: + tool: cargo-hack + + - name: restore cache + uses: Swatinem/rust-cache@v2 + with: + save-if: ${{ github.event_name != 'merge_group' }} + + - name: cargo clippy (no_std) + run: cargo hack clippy --workspace --locked --optional-deps --each-feature --ignore-unknown-features --features libm --exclude-features ${{ env.FEATURES_DEPENDING_ON_STD }} --target x86_64-unknown-none -- -D warnings + + - name: cargo clippy + run: cargo hack clippy --workspace --locked --optional-deps --each-feature --ignore-unknown-features --features std -- -D warnings + + - name: cargo clippy (auxiliary) + run: cargo hack clippy --workspace --locked --optional-deps --each-feature --ignore-unknown-features --features std --tests --benches --examples -- -D warnings + + clippy-stable-wasm: + name: cargo clippy (wasm32) + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: install stable toolchain + uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ env.RUST_STABLE_VER }} + targets: wasm32-unknown-unknown + components: clippy + + - name: install cargo-hack + uses: taiki-e/install-action@v2 + with: + tool: cargo-hack + + - name: restore cache + uses: Swatinem/rust-cache@v2 + with: + save-if: ${{ github.event_name != 'merge_group' }} + + - name: cargo clippy + run: cargo hack clippy --workspace --locked --target wasm32-unknown-unknown --optional-deps --each-feature --ignore-unknown-features --features std -- -D warnings + + - name: cargo clippy (auxiliary) + run: cargo hack clippy --workspace --locked --target wasm32-unknown-unknown --optional-deps --each-feature --ignore-unknown-features --features std --tests --benches --examples -- -D warnings + + test-stable: + name: cargo test + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [windows-latest, macos-latest, ubuntu-latest] + steps: + - uses: actions/checkout@v4 + + - name: install stable toolchain + uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ env.RUST_STABLE_VER }} + + - name: install cargo-nextest + uses: taiki-e/install-action@v2 + with: + tool: cargo-nextest + + - name: restore cache + uses: Swatinem/rust-cache@v2 + with: + save-if: ${{ github.event_name != 'merge_group' }} + + - name: cargo nextest + run: cargo nextest run --workspace --locked --all-features --no-fail-fast + + - name: cargo test --doc + run: cargo test --doc --workspace --locked --all-features --no-fail-fast + + test-stable-wasm: + name: cargo test (wasm32) + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: install stable toolchain + uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ env.RUST_STABLE_VER }} + targets: wasm32-unknown-unknown + + - name: restore cache + uses: Swatinem/rust-cache@v2 + with: + save-if: ${{ github.event_name != 'merge_group' }} + + # TODO: Find a way to make tests work. Until then the tests are merely compiled. + - name: cargo test compile + run: cargo test --workspace --locked --target wasm32-unknown-unknown --all-features --no-run + + check-msrv: + name: cargo check (msrv) + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [windows-latest, macos-latest, ubuntu-latest] + steps: + - uses: actions/checkout@v4 + + - name: install msrv toolchain + uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ env.RUST_MIN_VER }} + targets: x86_64-unknown-none + + - name: install cargo-hack + uses: taiki-e/install-action@v2 + with: + tool: cargo-hack + + - name: restore cache + uses: Swatinem/rust-cache@v2 + with: + save-if: ${{ github.event_name != 'merge_group' }} + + - name: cargo check (no_std) + run: cargo hack check ${{ env.RUST_MIN_VER_PKGS }} --locked --optional-deps --each-feature --ignore-unknown-features --features libm --exclude-features ${{ env.FEATURES_DEPENDING_ON_STD }} --target x86_64-unknown-none + + - name: cargo check + run: cargo hack check ${{ env.RUST_MIN_VER_PKGS }} --locked --optional-deps --each-feature --ignore-unknown-features --features std + + check-msrv-wasm: + name: cargo check (msrv) (wasm32) + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: install msrv toolchain + uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ env.RUST_MIN_VER }} + targets: wasm32-unknown-unknown + + - name: install cargo-hack + uses: taiki-e/install-action@v2 + with: + tool: cargo-hack + + - name: restore cache + uses: Swatinem/rust-cache@v2 + with: + save-if: ${{ github.event_name != 'merge_group' }} + + - name: cargo check + run: cargo hack check ${{ env.RUST_MIN_VER_PKGS }} --locked --target wasm32-unknown-unknown --optional-deps --each-feature --ignore-unknown-features --features std + + doc: + name: cargo doc + # NOTE: We don't have any platform specific docs in this workspace, so we only run on Ubuntu. + # If we get per-platform docs (win/macos/linux/wasm32/..) then doc jobs should match that. + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: install nightly toolchain + uses: dtolnay/rust-toolchain@nightly + + - name: restore cache + uses: Swatinem/rust-cache@v2 + with: + save-if: ${{ github.event_name != 'merge_group' }} + + # We test documentation using nightly to match docs.rs. + - name: cargo doc + run: cargo doc --workspace --locked --all-features --no-deps --document-private-items + env: + RUSTDOCFLAGS: '--cfg docsrs -D warnings' + + # If this fails, consider changing your text or adding something to .typos.toml. + typos: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: check typos + uses: crate-ci/typos@v1.27.0 diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml deleted file mode 100644 index 0af0007..0000000 --- a/.github/workflows/main.yml +++ /dev/null @@ -1,21 +0,0 @@ -name: simplecss - -on: [push, pull_request] - -env: - CARGO_TERM_COLOR: always - -jobs: - build: - runs-on: ubuntu-latest - strategy: - matrix: - rust: - - 1.37.0 - - stable - steps: - - name: Checkout - uses: actions/checkout@v2 - - - name: Test - run: cargo test diff --git a/.gitignore b/.gitignore index 3b874ca..ea8c4bf 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1 @@ -target -Cargo.lock -.idea -*.iml +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..c874d1a --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,42 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "env_logger" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aafcde04e90a5226a6443b7aabdb016ba2f8307c847d524724bd9b346dd1a2d3" +dependencies = [ + "log", +] + +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" + +[[package]] +name = "roxmltree" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0852407257c1b696a0c66b9db3ffe7769c2744a2fa725c8050e6f3e5a823c02b" +dependencies = [ + "xmlparser", +] + +[[package]] +name = "simplecss" +version = "0.2.1" +dependencies = [ + "env_logger", + "log", + "roxmltree", +] + +[[package]] +name = "xmlparser" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8110496c5bcc0d966b0b2da38d5a791aa139eeb0b80e7840a7463c2b806921eb" diff --git a/Cargo.toml b/Cargo.toml index fd5454c..504956f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,7 @@ keywords = ["css", "parser", "selector"] categories = ["parser-implementations"] edition = "2021" exclude = ["testing-tools/**"] +rust-version = "1.65" [features] default = ["std"] diff --git a/examples/parse.rs b/examples/parse.rs index ca02f9d..794be4a 100644 --- a/examples/parse.rs +++ b/examples/parse.rs @@ -1,3 +1,6 @@ +// Copyright 2019 the SimpleCSS Authors +// SPDX-License-Identifier: Apache-2.0 OR MIT + use std::io::{Read, Write}; fn main() { diff --git a/examples/select.rs b/examples/select.rs index c125d17..a9ce360 100644 --- a/examples/select.rs +++ b/examples/select.rs @@ -1,3 +1,6 @@ +// Copyright 2019 the SimpleCSS Authors +// SPDX-License-Identifier: Apache-2.0 OR MIT + struct XmlNode<'a, 'input: 'a>(roxmltree::Node<'a, 'input>); impl<'a, 'input: 'a> XmlNode<'a, 'input> { diff --git a/src/lib.rs b/src/lib.rs index 4171681..31d0a3e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,6 @@ +// Copyright 2016 the SimpleCSS Authors +// SPDX-License-Identifier: Apache-2.0 OR MIT + /*! A simple [CSS 2.1](https://www.w3.org/TR/CSS21/) parser and selector. diff --git a/src/selector.rs b/src/selector.rs index c6575b6..d64b4d5 100644 --- a/src/selector.rs +++ b/src/selector.rs @@ -1,3 +1,6 @@ +// Copyright 2019 the SimpleCSS Authors +// SPDX-License-Identifier: Apache-2.0 OR MIT + use alloc::{vec, vec::Vec}; use core::fmt; diff --git a/src/stream.rs b/src/stream.rs index 006afcd..ce49901 100644 --- a/src/stream.rs +++ b/src/stream.rs @@ -1,3 +1,6 @@ +// Copyright 2016 the SimpleCSS Authors +// SPDX-License-Identifier: Apache-2.0 OR MIT + use core::str; use crate::{Error, TextPos}; diff --git a/tests/declaration_tokenizer.rs b/tests/declaration_tokenizer.rs index ce2cd0d..1fda7b2 100644 --- a/tests/declaration_tokenizer.rs +++ b/tests/declaration_tokenizer.rs @@ -1,3 +1,6 @@ +// Copyright 2019 the SimpleCSS Authors +// SPDX-License-Identifier: Apache-2.0 OR MIT + use simplecss::*; macro_rules! tokenize { diff --git a/tests/select.rs b/tests/select.rs index 6fe1b8d..18366e3 100644 --- a/tests/select.rs +++ b/tests/select.rs @@ -1,3 +1,6 @@ +// Copyright 2019 the SimpleCSS Authors +// SPDX-License-Identifier: Apache-2.0 OR MIT + use simplecss::*; struct XmlNode<'a, 'input: 'a>(roxmltree::Node<'a, 'input>); diff --git a/tests/selector_tokenizer.rs b/tests/selector_tokenizer.rs index 0f9a0e0..0e85534 100644 --- a/tests/selector_tokenizer.rs +++ b/tests/selector_tokenizer.rs @@ -1,3 +1,6 @@ +// Copyright 2019 the SimpleCSS Authors +// SPDX-License-Identifier: Apache-2.0 OR MIT + use simplecss::*; macro_rules! tokenize { diff --git a/tests/specificity.rs b/tests/specificity.rs index 8bb2808..92736f9 100644 --- a/tests/specificity.rs +++ b/tests/specificity.rs @@ -1,3 +1,6 @@ +// Copyright 2019 the SimpleCSS Authors +// SPDX-License-Identifier: Apache-2.0 OR MIT + use simplecss::*; #[test] diff --git a/tests/stylesheet.rs b/tests/stylesheet.rs index 27d0591..808387f 100644 --- a/tests/stylesheet.rs +++ b/tests/stylesheet.rs @@ -1,3 +1,6 @@ +// Copyright 2019 the SimpleCSS Authors +// SPDX-License-Identifier: Apache-2.0 OR MIT + use simplecss::*; #[test] diff --git a/tests/warnings.rs b/tests/warnings.rs index 7e33140..97ed609 100644 --- a/tests/warnings.rs +++ b/tests/warnings.rs @@ -1,3 +1,6 @@ +// Copyright 2019 the SimpleCSS Authors +// SPDX-License-Identifier: Apache-2.0 OR MIT + fn run_process(input: &str) -> String { use std::io::Write; use std::process::Stdio;