diff --git a/.github/workflows/audit.yml b/.github/workflows/audit.yml index 3f7ba19..a47d1c3 100644 --- a/.github/workflows/audit.yml +++ b/.github/workflows/audit.yml @@ -70,3 +70,46 @@ jobs: run: | cargo +${{ steps.rust-install.outputs.name }} clippy -- -D warnings cargo +${{ steps.rust-install.outputs.name }} clippy --all-features -- -D warnings + + nightly_compat_node: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + submodules: true + + - name: Install rust + id: rust-install + uses: dtolnay/rust-toolchain@nightly + + - name: Update deps + run: | + cargo +${{ steps.rust-install.outputs.name }} update + + - name: Install rust + id: rust-install + uses: dtolnay/rust-toolchain@stable + + - name: Setup Node + uses: actions/setup-node@v4 + with: + cache: npm + node-version: nightly + + - name: Update Dependencies + run: npm update + + - name: Install Dependencies + run: npm install + + - name: Build + run: npm run build + # nodejs support is experimental; don't fail the build for it + continue-on-error: true + + - name: Test + run: npm test + # nodejs support is experimental; don't fail the build for it + continue-on-error: true diff --git a/.github/workflows/qa.yml b/.github/workflows/qa.yml index 205fd7f..d479f11 100644 --- a/.github/workflows/qa.yml +++ b/.github/workflows/qa.yml @@ -58,7 +58,7 @@ jobs: uses: mfinelli/setup-shfmt@master - name: Run shfmt - run: shfmt -d bin/* test/run + run: shfmt -d bin/* - name: Setup Node uses: actions/setup-node@v4 @@ -142,13 +142,9 @@ jobs: with: toolchain: ${{ matrix.rust-toolchain }} - - name: Build - run: | - cargo +${{ steps.rust-install.outputs.name }} build - - name: Run Testsuite - working-directory: "test" - run: ./run + run: | + cargo +${{ steps.rust-install.outputs.name }} test build-test-node: runs-on: ubuntu-latest diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0c2b407..c9c0513 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,3 +1,5 @@ +# Overview + * If you have found a discrepancy in documented and observed behaviour, that is a bug. Feel free to [report it as an issue](https://github.com/mpalmer/action-validator/issues), providing @@ -8,3 +10,116 @@ request](https://github.com/mpalmer/action-validator/pulls). * At all times, abide by the Code of Conduct (CODE_OF_CONDUCT.md). + +--- + +# Environment Setup + +## Install Rust +Firstly, you'll need a Rust toolchain to make any changes to the core functionality of this project. We recommend [using `rustup`](https://www.rust-lang.org/tools/install), because that's what the Rust core team recommend. + +To confirm that rust is installed, run the `cargo` command. If you don't receive the help docs output, you may need to add rust to your shell rc file. + +## Git Submodule Setup +This repository uses [git submodules](https://git-scm.com/book/en/v2/Git-Tools-Submodules). Specifically for the use of [schemastore](https://github.com/SchemaStore/schemastore). + +To setup the git submodule after cloning this repo to your local, you'll want to run the following commands: +1. `git submodule init` +2. `git submodule update` + +It should look similar to the output below. + +```bash +❯ git submodule init +Submodule 'src/schemastore' (https://github.com/SchemaStore/schemastore) registered for path 'src +/schemastore' +❯ git submodule update +Cloning into '/Users/someuser/action-validator/src/schemastore'... +Submodule path 'src/schemastore': checked out 'd3e6ab7727380b214acbab05570fb09a3e5d2dfc' +``` + +At this point, you should be all set to `cargo run`! + +## Node/WASM Setup +If you plan to work on the WASM/Node bindings, you'll also need to install Node. We recommend using [NVM](https://github.com/nvm-sh/nvm) to install the Node version listed in `.nvmrc`. + +Once Node is installed, run `npm install` at the root of the repository. + +You should now be all set to run `npm build`, to build the Node/WASM bindings. Once built, run `npx action-validator` to run the CLI via the Node/WASM bindings. + +# Running the Validator Locally + +## `cargo run [FILE] -- [OPTIONS]` +`cargo run` will create a _debug_ executable and run the project. If this is your first time running the command, cargo will compile the development binary with `cargo build`. This will install all of the dependencies and create the debug binary `action-validator` in the `/target/debug/` directory. `cargo run` will then invoke this binary after creation. + +One caveat if you're running with `cargo run`: if you want to supply the program with options, you need to use the `--` operator between `cargo run` and your provided options. This let's cargo know which flags are meant for cargo, and which are meant for the executable. + +## `cargo build` && `./target/debug/action-validator [OPTIONS]` +As discussed in the prior section, `cargo build` install dependencies (if they're not cached) and build the development binary. This binary can then be invoked directly by running `./target/debug/action-validator`. This does **not** require the use of the `--` operator in between the binary and any provided options. + +## Try It Yourself! + +Run the command `cargo run -- --help`. You should see an output similar to the following. +```bash +❯ cargo run -- --help + Finished dev [unoptimized + debuginfo] target(s) in 0.05s + Running `target/debug/action-validator --help` +A validator for GitHub Action and Workflow YAML files + +Usage: action-validator [OPTIONS] [path_to_action_yaml]... + +Arguments: + [path_to_action_yaml]... Input file + +Options: + -v, --verbose Be more verbose + -h, --help Print help information + -V, --version Print version information +``` + +# Writing Tests + +All tests live in the `tests` directory. Currently, this project implements snapshot testing, +but that's not to say you couldn't write unit or integration tests with the current structure. +To run the tests, simply run `cargo test` from the root directory. If you want to test a specific +feature, you can add the `-F {feature}` flag (e.g. `cargo test -F remote-checks`). + +## Unit/Integration Tests +As of this writing, there are no unit or integration tests. If you are looking to write some, please +follow the directions in [this guide](https://doc.rust-lang.org/book/ch11-01-writing-tests.html). + +## Snapshot Tests +A snapshot test is performed when we execute the cli and capture `stdout`, `stderr`, and/or an exit code. +When the tests are run, the results of the test must exactly match those of the previous run. For this project, +the snapshot tests are named in the format `{next_id}_{whats_being_tested}` (e.g. `011_remote_checks_failure`). + +If you have made changes which will change the output of the program and cause snapshots to fail, you can run +`cargo test -F test-save-snapshots`. This feature causes the executed command to save the `stdout`, `stderr`, and/or +exit code to the specified testing directory. + +If you are writing a net new test, you will need to create the test directory with your workflow or action file, and a +`test.json` file. Once you're done, you can save the results to that directy by running +`cargo test -F test-save-snapshots`. + +The `test.json` file contains the test configuration. It can usually be left empty (i.e. `{}`). + +```jsonc +// Example test.json +{ + "targets": { + "node": false, + "native": true + }, + "cli_args": [ + "--rootdir", + "tests/fixtures/011_subdir_globs/subdir", + "tests/fixtures/011_subdir_globs/subdir/glob.yml" + ] +} +``` + +# Testing Node/WASM Bindings + +To test against the Node/WASM bindings, you can run `npm test`, or `npm test:dev` (to skip optimisations). +Note that Node support is considered experimental, and does not have one to one feature parity with the native binary yet. +As such, some tests may fail, even on `main`. diff --git a/Cargo.lock b/Cargo.lock index 20f334c..0c4df35 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6,8 +6,10 @@ version = 4 name = "action-validator" version = "0.0.0-git" dependencies = [ + "assert_cmd", "clap", "console_error_panic_hook", + "fixtures", "glob", "is-terminal", "js-sys", @@ -56,9 +58,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.19" +version = "0.6.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "301af1932e46185686725e0fad2f8f2aa7da69dd70bf6ecc44d6b703844a3933" +checksum = "3ae563653d1938f79b1ab1b5e668c87c76a9930414574a6583a7b7e11a8e6192" dependencies = [ "anstyle", "anstyle-parse", @@ -86,22 +88,38 @@ dependencies = [ [[package]] name = "anstyle-query" -version = "1.1.3" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8bdeb6047d8983be085bab0ba1472e6dc604e7041dbf6fcd5e71523014fae9" +checksum = "9e231f6134f61b71076a3eab506c379d4f36122f2af15a9ff04415ea4c3339e2" dependencies = [ - "windows-sys", + "windows-sys 0.60.2", ] [[package]] name = "anstyle-wincon" -version = "3.0.9" +version = "3.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "403f75924867bb1033c59fbf0797484329750cfbe3c4325cd33127941fabc882" +checksum = "3e0633414522a32ffaac8ac6cc8f748e090c5717661fddeea04219e2344f5f2a" dependencies = [ "anstyle", "once_cell_polyfill", - "windows-sys", + "windows-sys 0.60.2", +] + +[[package]] +name = "assert_cmd" +version = "2.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bd389a4b2970a01282ee455294913c0a43724daedcd1a24c3eb0ec1c1320b66" +dependencies = [ + "anstyle", + "bstr", + "doc-comment", + "libc", + "predicates", + "predicates-core", + "predicates-tree", + "wait-timeout", ] [[package]] @@ -133,30 +151,42 @@ checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" [[package]] name = "bitflags" -version = "2.9.1" +version = "2.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394" + +[[package]] +name = "bstr" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" +checksum = "234113d19d0d7d613b40e86fb654acf958910802bcceab913a4f9e7cda03b1a4" +dependencies = [ + "memchr", + "regex-automata", + "serde", +] [[package]] name = "bumpalo" -version = "3.18.1" +version = "3.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793db76d6187cd04dff33004d8e6c9cc4e05cd330500379d2394209271b4aeee" +checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" [[package]] name = "cc" -version = "1.2.27" +version = "1.2.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d487aa071b5f64da6f19a3e848e3578944b726ee5a4854b82172f02aa876bfdc" +checksum = "5252b3d2648e5eedbc1a6f501e3c795e07025c1e93bbf8bbdd6eef7f447a6d54" dependencies = [ + "find-msvc-tools", "shlex", ] [[package]] name = "cfg-if" -version = "1.0.1" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" +checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9" [[package]] name = "chrono" @@ -172,9 +202,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.40" +version = "4.5.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40b6887a1d8685cebccf115538db5c0efe625ccac9696ad45c409d96566e910f" +checksum = "7eac00902d9d136acd712710d71823fb8ac8004ca445a89e73a41d45aa712931" dependencies = [ "clap_builder", "clap_derive", @@ -182,9 +212,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.40" +version = "4.5.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0c66c08ce9f0c698cbce5c0279d0bb6ac936d8674174fe48f736533b964f59e" +checksum = "2ad9bbf750e73b5884fb8a211a9424a1906c1e156724260fdae972f31d70e1d6" dependencies = [ "anstream", "anstyle", @@ -194,14 +224,14 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.40" +version = "4.5.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2c7947ae4cc3d851207c1adb5b5e260ff0cca11446b1d6d1423788e442257ce" +checksum = "bbfd7eae0b0f1a6e63d4b13c9c478de77c2eb546fba158ad50b4203dc24b9f9c" dependencies = [ "heck", "proc-macro2", "quote", - "syn", + "syn 2.0.106", ] [[package]] @@ -232,6 +262,37 @@ version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" +[[package]] +name = "crossbeam-deque" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + +[[package]] +name = "difflib" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8" + [[package]] name = "displaydoc" version = "0.2.5" @@ -240,9 +301,15 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.106", ] +[[package]] +name = "doc-comment" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" + [[package]] name = "downcast-rs" version = "1.2.1" @@ -274,11 +341,41 @@ dependencies = [ "regex", ] +[[package]] +name = "find-msvc-tools" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fd99930f64d146689264c637b5af2f0233a933bef0d8570e2526bf9e083192d" + +[[package]] +name = "fixtures" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d1253329670ef6ee65e8d72161a1fae66bc8ea23c12d40522cbdf5c2c35064" +dependencies = [ + "fixtures_proc", +] + +[[package]] +name = "fixtures_proc" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7d75770cda1757c6e2f63dc4fd1b8181836fae2d850793ae79d8dbafc5f2b89" +dependencies = [ + "globset", + "globwalk", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.106", + "unicode-xid", +] + [[package]] name = "form_urlencoded" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" dependencies = [ "percent-encoding", ] @@ -297,15 +394,39 @@ dependencies = [ [[package]] name = "glob" -version = "0.3.2" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" + +[[package]] +name = "globset" +version = "0.4.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" +checksum = "54a1028dfc5f5df5da8a56a73e6c153c9a9708ec57232470703592a3f18e49f5" +dependencies = [ + "aho-corasick", + "bstr", + "log", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "globwalk" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf760ebf69878d9fd8f110c89703d90ce35095324d1f1edcb595c63945ee757" +dependencies = [ + "bitflags", + "ignore", + "walkdir", +] [[package]] name = "hashbrown" -version = "0.15.4" +version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" [[package]] name = "heck" @@ -431,9 +552,9 @@ dependencies = [ [[package]] name = "idna" -version = "1.0.3" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" dependencies = [ "idna_adapter", "smallvec", @@ -450,11 +571,27 @@ dependencies = [ "icu_properties", ] +[[package]] +name = "ignore" +version = "0.4.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d89fd380afde86567dfba715db065673989d6253f42b88179abd3eae47bda4b" +dependencies = [ + "crossbeam-deque", + "globset", + "log", + "memchr", + "regex-automata", + "same-file", + "walkdir", + "winapi-util", +] + [[package]] name = "indexmap" -version = "2.9.0" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" +checksum = "f2481980430f9f78649238835720ddccc57e52df14ffce1c6f37391d61b563e9" dependencies = [ "equivalent", "hashbrown", @@ -468,7 +605,7 @@ checksum = "e04d7f318608d35d4b61ddd75cbdaee86b023ebe2bd5a66ee0915f0bf93095a9" dependencies = [ "hermit-abi", "libc", - "windows-sys", + "windows-sys 0.59.0", ] [[package]] @@ -485,9 +622,9 @@ checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] name = "js-sys" -version = "0.3.77" +version = "0.3.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" +checksum = "0c0b063578492ceec17683ef2f8c5e89121fbd0b172cbc280635ab7567db2738" dependencies = [ "once_cell", "wasm-bindgen", @@ -514,9 +651,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.174" +version = "0.2.175" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" +checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543" [[package]] name = "litemap" @@ -526,9 +663,9 @@ checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" [[package]] name = "log" -version = "0.4.27" +version = "0.4.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" +checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" [[package]] name = "memchr" @@ -569,9 +706,9 @@ checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" [[package]] name = "percent-encoding" -version = "2.3.1" +version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "phf" @@ -613,27 +750,78 @@ dependencies = [ [[package]] name = "potential_utf" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5a7c30837279ca13e7c867e9e40053bc68740f988cb07f7ca6df43cc734b585" +checksum = "84df19adbe5b5a0782edcab45899906947ab039ccf4573713735ee7de1e6b08a" dependencies = [ "zerovec", ] +[[package]] +name = "predicates" +version = "3.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5d19ee57562043d37e82899fade9a22ebab7be9cef5026b07fda9cdd4293573" +dependencies = [ + "anstyle", + "difflib", + "predicates-core", +] + +[[package]] +name = "predicates-core" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "727e462b119fe9c93fd0eb1429a5f7647394014cf3c04ab2c0350eeb09095ffa" + +[[package]] +name = "predicates-tree" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72dd2d6d381dfb73a193c7fca536518d7caee39fc8503f74e7dc0be0531b425c" +dependencies = [ + "predicates-core", + "termtree", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + [[package]] name = "proc-macro2" -version = "1.0.95" +version = "1.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" +checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" dependencies = [ "unicode-ident", ] [[package]] name = "psl" -version = "2.1.122" +version = "2.1.140" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98426d83dcbac622be1c1146e8763ccb4a2fe9bca707dd7446a842e186fa91aa" +checksum = "89a33878b44e45231ecbc8c619cc8059e4adab882b25812192676fe08dcf352f" dependencies = [ "psl-types", ] @@ -676,9 +864,9 @@ checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" [[package]] name = "regex" -version = "1.11.1" +version = "1.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +checksum = "23d7fd106d8c02486a8d64e778353d1cffe08ce79ac2e82f540c86d0facf6912" dependencies = [ "aho-corasick", "memchr", @@ -688,9 +876,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +checksum = "6b9458fa0bfeeac22b5ca447c63aaf45f28439a709ccd244698632f9aa6394d6" dependencies = [ "aho-corasick", "memchr", @@ -699,15 +887,15 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" +checksum = "caf4aa5b0f434c91fe5c7f1ecb6a5ece2130b02ad2a590589dda5146df959001" [[package]] name = "rustversion" -version = "1.0.21" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" [[package]] name = "ryu" @@ -752,14 +940,14 @@ checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.106", ] [[package]] name = "serde_json" -version = "1.0.140" +version = "1.0.143" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" +checksum = "d401abef1d108fbd9cbaebc3e46611f4b1021f714a0597a71f41ee463f5f4a5a" dependencies = [ "itoa", "memchr", @@ -812,9 +1000,19 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" -version = "2.0.104" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" +checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" dependencies = [ "proc-macro2", "quote", @@ -829,9 +1027,15 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.106", ] +[[package]] +name = "termtree" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f50febec83f5ee1df3015341d8bd429f2d1cc62bcba7ea2076759d315084683" + [[package]] name = "tinystr" version = "0.8.1" @@ -848,6 +1052,12 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + [[package]] name = "unsafe-libyaml" version = "0.2.11" @@ -865,13 +1075,14 @@ dependencies = [ [[package]] name = "url" -version = "2.5.4" +version = "2.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" +checksum = "08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b" dependencies = [ "form_urlencoded", "idna", "percent-encoding", + "serde", ] [[package]] @@ -888,9 +1099,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.17.0" +version = "1.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cf4199d1e5d15ddd86a694e4d0dffa9c323ce759fea589f00fef9d81cc1931d" +checksum = "2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2" dependencies = [ "getrandom", "js-sys", @@ -921,6 +1132,21 @@ dependencies = [ "uuid", ] +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "wait-timeout" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ac3b126d3914f9849036f826e054cbabdc8519970b8998ddaf3b5bd3c65f11" +dependencies = [ + "libc", +] + [[package]] name = "walkdir" version = "2.5.0" @@ -933,44 +1159,45 @@ dependencies = [ [[package]] name = "wasi" -version = "0.14.2+wasi-0.2.4" +version = "0.14.4+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" +checksum = "88a5f4a424faf49c3c2c344f166f0662341d470ea185e939657aaff130f0ec4a" dependencies = [ - "wit-bindgen-rt", + "wit-bindgen", ] [[package]] name = "wasm-bindgen" -version = "0.2.100" +version = "0.2.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" +checksum = "7e14915cadd45b529bb8d1f343c4ed0ac1de926144b746e2710f9cd05df6603b" dependencies = [ "cfg-if", "once_cell", "rustversion", "wasm-bindgen-macro", + "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.100" +version = "0.2.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" +checksum = "e28d1ba982ca7923fd01448d5c30c6864d0a14109560296a162f80f305fb93bb" dependencies = [ "bumpalo", "log", "proc-macro2", "quote", - "syn", + "syn 2.0.106", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.50" +version = "0.4.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" +checksum = "0ca85039a9b469b38336411d6d6ced91f3fc87109a2a27b0c197663f5144dffe" dependencies = [ "cfg-if", "js-sys", @@ -981,9 +1208,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.100" +version = "0.2.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" +checksum = "7c3d463ae3eff775b0c45df9da45d68837702ac35af998361e2c84e7c5ec1b0d" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -991,31 +1218,31 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.100" +version = "0.2.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" +checksum = "7bb4ce89b08211f923caf51d527662b75bdc9c9c7aab40f86dcb9fb85ac552aa" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.106", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.100" +version = "0.2.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +checksum = "f143854a3b13752c6950862c906306adb27c7e839f7414cec8fea35beab624c1" dependencies = [ "unicode-ident", ] [[package]] name = "wasm-bindgen-test" -version = "0.3.50" +version = "0.3.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66c8d5e33ca3b6d9fa3b4676d774c5778031d27a578c2b007f905acf816152c3" +checksum = "80cc7f8a4114fdaa0c58383caf973fc126cf004eba25c9dc639bccd3880d55ad" dependencies = [ "js-sys", "minicov", @@ -1026,20 +1253,20 @@ dependencies = [ [[package]] name = "wasm-bindgen-test-macro" -version = "0.3.50" +version = "0.3.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17d5042cc5fa009658f9a7333ef24291b1291a25b6382dd68862a7f3b969f69b" +checksum = "c5ada2ab788d46d4bda04c9d567702a79c8ced14f51f221646a16ed39d0e6a5d" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.106", ] [[package]] name = "web-sys" -version = "0.3.77" +version = "0.3.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" +checksum = "77e4b637749ff0d92b8fad63aa1f7cff3cbe125fd49c175cd6345e7272638b12" dependencies = [ "js-sys", "wasm-bindgen", @@ -1047,11 +1274,11 @@ dependencies = [ [[package]] name = "winapi-util" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +checksum = "0978bf7171b3d90bac376700cb56d606feb40f251a475a5d6634613564460b22" dependencies = [ - "windows-sys", + "windows-sys 0.60.2", ] [[package]] @@ -1075,7 +1302,7 @@ checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.106", ] [[package]] @@ -1086,7 +1313,7 @@ checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.106", ] [[package]] @@ -1119,7 +1346,16 @@ version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ - "windows-targets", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets 0.53.3", ] [[package]] @@ -1128,14 +1364,31 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_gnullvm", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm 0.52.6", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.53.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91" +dependencies = [ + "windows-link", + "windows_aarch64_gnullvm 0.53.0", + "windows_aarch64_msvc 0.53.0", + "windows_i686_gnu 0.53.0", + "windows_i686_gnullvm 0.53.0", + "windows_i686_msvc 0.53.0", + "windows_x86_64_gnu 0.53.0", + "windows_x86_64_gnullvm 0.53.0", + "windows_x86_64_msvc 0.53.0", ] [[package]] @@ -1144,42 +1397,84 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" + [[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" + [[package]] name = "windows_i686_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" +[[package]] +name = "windows_i686_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" + [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" + [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" +[[package]] +name = "windows_i686_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" + [[package]] name = "windows_x86_64_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" + [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" + [[package]] name = "windows_x86_64_msvc" version = "0.52.6" @@ -1187,13 +1482,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] -name = "wit-bindgen-rt" -version = "0.39.0" +name = "windows_x86_64_msvc" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" -dependencies = [ - "bitflags", -] +checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" + +[[package]] +name = "wit-bindgen" +version = "0.45.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c573471f125075647d03df72e026074b7203790d41351cd6edc96f46bcccd36" [[package]] name = "writeable" @@ -1221,7 +1519,7 @@ checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.106", "synstructure", ] @@ -1242,7 +1540,7 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.106", "synstructure", ] @@ -1259,9 +1557,9 @@ dependencies = [ [[package]] name = "zerovec" -version = "0.11.2" +version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a05eb080e015ba39cc9e23bbe5e7fb04d5fb040350f99f34e338d5fdd294428" +checksum = "e7aa2bd55086f1ab526693ecbe444205da57e25f4489879da80635a46d90e73b" dependencies = [ "yoke", "zerofrom", @@ -1276,5 +1574,5 @@ checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.106", ] diff --git a/Cargo.toml b/Cargo.toml index def1cf7..054d8c8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,10 @@ rust-version = "1.84.0" crate-type = ["cdylib", "rlib"] [features] +default = ["assert_cmd"] js = ["console_error_panic_hook", "valico/js"] +test-save-snapshots = [] +test-js = [] [dependencies] clap = { version = "4.0", features = ["derive"] } @@ -42,9 +45,11 @@ console_error_panic_hook = { version = "0.1.7", optional = true } serde-wasm-bindgen = "0.4.5" js-sys = "0.3.77" is-terminal = "0.4.7" +assert_cmd = { version = "2.0.8", optional = true } [dev-dependencies] wasm-bindgen-test = "0.3.34" +fixtures = "2.4.0" [profile.release] # Tell `rustc` to optimize for small code size. diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..e998592 --- /dev/null +++ b/build.rs @@ -0,0 +1,3 @@ +fn main() { + println!("cargo:rerun-if-changed=tests/fixtures"); +} diff --git a/package-lock.json b/package-lock.json index 23fef40..b40b52e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,9 @@ "name": "@action-validator/root", "version": "0.0.0-git", "license": "GPL-3.0-only", + "workspaces": [ + "packages/*" + ], "devDependencies": { "chalk": "5.2.0", "diff": "5.1.0", @@ -15,6 +18,14 @@ "wasm-pack": "0.13.1" } }, + "node_modules/@action-validator/cli": { + "resolved": "packages/cli", + "link": true + }, + "node_modules/@action-validator/core": { + "resolved": "packages/core", + "link": true + }, "node_modules/axios": { "version": "0.26.1", "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz", @@ -351,9 +362,37 @@ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true, "license": "ISC" + }, + "packages/cli": { + "name": "@action-validator/cli", + "version": "0.0.0-git", + "license": "GPL-3.0-only", + "bin": { + "action-validator": "cli.mjs" + }, + "devDependencies": { + "@action-validator/core": "file:../core" + }, + "peerDependencies": { + "@action-validator/core": "0.0.0-git" + } + }, + "packages/core": { + "name": "@action-validator/core", + "version": "0.0.0-git", + "license": "GPL-3.0-only" } }, "dependencies": { + "@action-validator/cli": { + "version": "file:packages/cli", + "requires": { + "@action-validator/core": "file:../core" + } + }, + "@action-validator/core": { + "version": "file:packages/core" + }, "axios": { "version": "0.26.1", "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz", diff --git a/package.json b/package.json index 8f8a0d4..45a579f 100644 --- a/package.json +++ b/package.json @@ -3,10 +3,12 @@ "private": true, "version": "0.0.0-git", "license": "GPL-3.0-only", + "workspaces": ["packages/*"], "scripts": { "build": "./scripts/build-wasm.sh", - "build:dev": "./scripts/build-wasm.sh", - "test": "node test/run.mjs", + "build:dev": "WASM_PACK_BUILD_FLAGS='--no-opt' ./scripts/build-wasm.sh", + "test": "./scripts/test-wasm.sh", + "test:dev": "WASM_PACK_BUILD_FLAGS='--no-opt' ./scripts/test-wasm.sh", "lint": "prettier --check .", "format": "prettier --write ." }, diff --git a/packages/cli/cli.mjs b/packages/cli/cli.mjs old mode 100644 new mode 100755 diff --git a/scripts/build-wasm.sh b/scripts/build-wasm.sh index 34695e2..a3135e5 100755 --- a/scripts/build-wasm.sh +++ b/scripts/build-wasm.sh @@ -2,7 +2,9 @@ set -euo pipefail -npx wasm-pack build --out-dir target/wasm-pack/build --no-typescript --target nodejs --features js +# [SC2086] Intenitonally omitting double quotes to allow word splitting of WASM_PACK_BUILD_FLAGS +# shellcheck disable=SC2086 +npx wasm-pack build ${WASM_PACK_BUILD_FLAGS:-} --out-dir target/wasm-pack/build --no-typescript --target nodejs --no-default-features --features js rm -rf packages/core/snippets cp -R target/wasm-pack/build/snippets packages/core/snippets cp target/wasm-pack/build/action_validator_bg.wasm packages/core/ diff --git a/scripts/test-wasm.sh b/scripts/test-wasm.sh new file mode 100755 index 0000000..8ff6e82 --- /dev/null +++ b/scripts/test-wasm.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +set -euo pipefail + +cargo test -F test-js diff --git a/src/schemastore b/src/schemastore index 03b4f37..acb7898 160000 --- a/src/schemastore +++ b/src/schemastore @@ -1 +1 @@ -Subproject commit 03b4f371a544bfcb6a8f4bd5ce6a324c586f2528 +Subproject commit acb78980a532436336c3f4d0b1a691d9ae7f0bc9 diff --git a/test/001_basic_workflow/validation_state.snap.json b/test/001_basic_workflow/validation_state.snap.json deleted file mode 100644 index c313801..0000000 --- a/test/001_basic_workflow/validation_state.snap.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "actionType": "workflow", - "errors": [] -} diff --git a/test/002_basic_action/validation_state.snap.json b/test/002_basic_action/validation_state.snap.json deleted file mode 100644 index 3a0fe83..0000000 --- a/test/002_basic_action/validation_state.snap.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "actionType": "action", - "errors": [] -} diff --git a/test/003_subdir_globs/cli_args b/test/003_subdir_globs/cli_args deleted file mode 100644 index eb7e32e..0000000 --- a/test/003_subdir_globs/cli_args +++ /dev/null @@ -1 +0,0 @@ ---rootdir 003_subdir_globs/subdir diff --git a/test/003_subdir_globs/validation_state.snap.json b/test/003_subdir_globs/validation_state.snap.json deleted file mode 100644 index c313801..0000000 --- a/test/003_subdir_globs/validation_state.snap.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "actionType": "workflow", - "errors": [] -} diff --git a/test/003_successful_globs/validation_state.snap.json b/test/003_successful_globs/validation_state.snap.json deleted file mode 100644 index c313801..0000000 --- a/test/003_successful_globs/validation_state.snap.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "actionType": "workflow", - "errors": [] -} diff --git a/test/004_failing_globs/exitcode b/test/004_failing_globs/exitcode deleted file mode 100644 index d00491f..0000000 --- a/test/004_failing_globs/exitcode +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/test/004_failing_globs/stdout b/test/004_failing_globs/stdout deleted file mode 100644 index 4179a2f..0000000 --- a/test/004_failing_globs/stdout +++ /dev/null @@ -1 +0,0 @@ -Fatal error validating 004_failing_globs/glob.yml diff --git a/test/004_failing_globs/validation_state.snap.json b/test/004_failing_globs/validation_state.snap.json deleted file mode 100644 index c313801..0000000 --- a/test/004_failing_globs/validation_state.snap.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "actionType": "workflow", - "errors": [] -} diff --git a/test/004a_failing_negative_glob/exitcode b/test/004a_failing_negative_glob/exitcode deleted file mode 100644 index d00491f..0000000 --- a/test/004a_failing_negative_glob/exitcode +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/test/004a_failing_negative_glob/stdout b/test/004a_failing_negative_glob/stdout deleted file mode 100644 index 8c3b53a..0000000 --- a/test/004a_failing_negative_glob/stdout +++ /dev/null @@ -1 +0,0 @@ -Fatal error validating 004a_failing_negative_glob/glob.yml diff --git a/test/004a_failing_negative_glob/validation_state.snap.json b/test/004a_failing_negative_glob/validation_state.snap.json deleted file mode 100644 index c313801..0000000 --- a/test/004a_failing_negative_glob/validation_state.snap.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "actionType": "workflow", - "errors": [] -} diff --git a/test/005_conditional_step_in_action/validation_state.snap.json b/test/005_conditional_step_in_action/validation_state.snap.json deleted file mode 100644 index 3a0fe83..0000000 --- a/test/005_conditional_step_in_action/validation_state.snap.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "actionType": "action", - "errors": [] -} diff --git a/test/006_workflow_dispatch_inputs_options/validation_state.snap.json b/test/006_workflow_dispatch_inputs_options/validation_state.snap.json deleted file mode 100644 index c313801..0000000 --- a/test/006_workflow_dispatch_inputs_options/validation_state.snap.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "actionType": "workflow", - "errors": [] -} diff --git a/test/007_funky_syntax/exitcode b/test/007_funky_syntax/exitcode deleted file mode 100644 index d00491f..0000000 --- a/test/007_funky_syntax/exitcode +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/test/007_funky_syntax/stdout b/test/007_funky_syntax/stdout deleted file mode 100644 index f57da30..0000000 --- a/test/007_funky_syntax/stdout +++ /dev/null @@ -1 +0,0 @@ -Fatal error validating 007_funky_syntax/rust-check.yml diff --git a/test/007_funky_syntax/validation_state.snap.json b/test/007_funky_syntax/validation_state.snap.json deleted file mode 100644 index 0ff3efe..0000000 --- a/test/007_funky_syntax/validation_state.snap.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "actionType": "workflow", - "errors": [ - { - "code": "parse_error", - "detail": "mapping values are not allowed in this context at line 38 column 15", - "path": "", - "title": "Parse Error", - "location": { - "index": 1069, - "line": 38, - "column": 15 - } - } - ] -} diff --git a/test/008_job_dependencies/exitcode b/test/008_job_dependencies/exitcode deleted file mode 100644 index d00491f..0000000 --- a/test/008_job_dependencies/exitcode +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/test/008_job_dependencies/stdout b/test/008_job_dependencies/stdout deleted file mode 100644 index 73dc3ee..0000000 --- a/test/008_job_dependencies/stdout +++ /dev/null @@ -1 +0,0 @@ -Fatal error validating 008_job_dependencies/test.yml diff --git a/test/008_job_dependencies/validation_state.snap.json b/test/008_job_dependencies/validation_state.snap.json deleted file mode 100644 index c504e36..0000000 --- a/test/008_job_dependencies/validation_state.snap.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "actionType": "workflow", - "errors": [ - { - "code": "unresolved_job", - "detail": "unresolved job asdf", - "path": "/jobs/build/needs", - "title": "Unresolved job" - } - ] -} diff --git a/test/009_multi_file/exitcode b/test/009_multi_file/exitcode deleted file mode 100644 index d00491f..0000000 --- a/test/009_multi_file/exitcode +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/test/009_multi_file/stdout b/test/009_multi_file/stdout deleted file mode 100644 index ec1a3fd..0000000 --- a/test/009_multi_file/stdout +++ /dev/null @@ -1 +0,0 @@ -Fatal error validating 009_multi_file/xinvalid.yml diff --git a/test/009_multi_file/validation_state.snap.json b/test/009_multi_file/validation_state.snap.json deleted file mode 100644 index fb78ced..0000000 --- a/test/009_multi_file/validation_state.snap.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "actionType": "workflow", - "errors": [ - { - "code": "parse_error", - "detail": "mapping values are not allowed in this context at line 36 column 15", - "path": "", - "title": "Parse Error", - "location": { - "index": 1069, - "line": 36, - "column": 15 - } - } - ] -} diff --git a/test/010_missing_shell_in_action/exitcode b/test/010_missing_shell_in_action/exitcode deleted file mode 100644 index d00491f..0000000 --- a/test/010_missing_shell_in_action/exitcode +++ /dev/null @@ -1 +0,0 @@ -1 diff --git a/test/010_missing_shell_in_action/stdout b/test/010_missing_shell_in_action/stdout deleted file mode 100644 index 93c3cda..0000000 --- a/test/010_missing_shell_in_action/stdout +++ /dev/null @@ -1 +0,0 @@ -Fatal error validating 010_missing_shell_in_action/action.yml diff --git a/test/run b/test/run deleted file mode 100755 index 48b5b11..0000000 --- a/test/run +++ /dev/null @@ -1,58 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -cd "$(dirname "${BASH_SOURCE[0]}")" - -readonly cmd="../target/debug/action-validator" - -if ! [ -x "$cmd" ]; then - echo "No action-validator to test; have you run 'cargo build' lately?" >&2 - exit 1 -fi - -for t in [0-9]*; do - expected_stdout="$(cat "$t/stdout" 2>/dev/null || true)" - expected_stderr="$(cat "$t/stderr" 2>/dev/null || true)" - expected_exitcode="$(cat "$t/exitcode" 2>/dev/null || echo 0)" - - dir="$(mktemp -d)" - trap 'rm -rf "$dir"' EXIT - - failed=n - rv=0 - - readarray -t -d '' testfiles < <(find "$t"/ -name '*.yml' -print0) - - EXTRA_ARGS="$(cat "$t/cli_args" 2>/dev/null || true)" - - "$cmd" $EXTRA_ARGS "${testfiles[@]}" >"$dir/stdout" 2>"$dir/stderr" || rv="$?" - stdout="$(cat "$dir"/stdout)" - stderr="$(cat "$dir"/stderr)" - - if [ "$rv" != "$expected_exitcode" ]; then - echo "Test $t exited with unexpected code: expected $expected_exitcode, got $rv" >&2 - failed=y - fi - - if [ "$stdout" != "$expected_stdout" ]; then - echo "Test $t produced unexpected stdout:" >&2 - diff -u <(echo "$expected_stdout") <(echo "$stdout") >&2 || true - failed=y - fi - - if [ "$stderr" != "$expected_stderr" ]; then - echo "Test $t produced unexpected stderr:" >&2 - diff -u <(echo "$expected_stderr") <(echo "$stderr") >&2 || true - failed=y - fi - - rm -rf "$dir" - trap "" EXIT - - if [ "$failed" = "y" ]; then - exit 1 - fi -done - -echo "All tests passed." diff --git a/test/run.mjs b/test/run.mjs deleted file mode 100644 index 7b026e6..0000000 --- a/test/run.mjs +++ /dev/null @@ -1,125 +0,0 @@ -// @ts-check -import chalk from "chalk"; -import * as diff from "diff"; -import fs from "fs"; -import * as action_validator from "../packages/core/action_validator.js"; - -const update = process.argv.includes("--update") || process.argv.includes("-u"); - -const start = Date.now(); - -const passed = fs - .readdirSync("test") - // get all directories in test/ - .map((entry) => `test/${entry}`) - .filter((entry) => fs.statSync(entry).isDirectory()) - // get the first .yml files in each directory - .map((testDir) => [testDir, ...fs.readdirSync(testDir)]) - .map(([testDir, ...entries]) => [ - testDir, - entries.filter((entry) => entry.endsWith(".yml"))[0], - ]) - // get the test fixture and snapshot files for each directory - .map(([testDir, testFixtureFileName]) => [ - `${testDir}/${testFixtureFileName}`, - `${testDir}/validation_state.snap.json`, - ]) - // read the files - .map(([testFixtureFile, testSnapshotFile]) => [ - testFixtureFile, - fs.readFileSync(testFixtureFile, "utf8"), - testSnapshotFile, - fs.readFileSync(testSnapshotFile, "utf8"), - ]) - // validate the test fixture files - .map(([testFixtureFile, testFixture, testSnapshotFile, oldSnapshot]) => { - let validationState; - - // treat action.yml files as actions and everything else as workflows - if (testFixtureFile.endsWith("action.yml")) { - console.log( - chalk.bold(` > ${testFixtureFile} `) + - chalk.bold.gray("(action file)") + - "\n" - ); - console.log(chalk.bold.gray("=== OUTPUT START ===")); - validationState = action_validator.validateAction(testFixture); - console.log(chalk.bold.gray("=== OUTPUT END ===")); - } else { - console.log( - chalk.bold(` > ${testFixtureFile} `) + - chalk.bold.gray("(workflow file)") + - "\n" - ); - console.log(chalk.bold.gray("=== OUTPUT START ===")); - validationState = action_validator.validateWorkflow(testFixture); - console.log(chalk.bold.gray("=== OUTPUT END ===")); - } - - // stringify the validation state and compare it to the snapshot - const newSnapshot = JSON.stringify(validationState, null, 2) + "\n"; - const isSnapshotMatch = newSnapshot === oldSnapshot; - - if (isSnapshotMatch) { - console.log(chalk.bold.green("\n SNAPSHOT MATCHED")); - } else { - // print the diff if the snapshot doesn't match - console.log( - chalk.bold[update ? "yellow" : "red"]("\n SNAPSHOT MISMATCH\n") - ); - console.log( - `${chalk.bold.gray("Diff:")} ${chalk.bold.red("red")} ${chalk.gray( - "for deletions," - )} ${chalk.bold.green("green")} ${chalk.gray( - "for additions," - )} ${chalk.bold.gray("grey")} ${chalk.gray("for common parts")}` - ); - diff.diffJson(oldSnapshot, newSnapshot).forEach((part) => { - const color = part.added ? "green" : part.removed ? "red" : "grey"; - process.stderr.write(chalk[color](part.value)); - }); - process.stderr.write("\n"); - } - - console.log("\n"); - - return [isSnapshotMatch, testFixtureFile, testSnapshotFile, newSnapshot]; - }) - .map( - update - ? // update any snapshots that don't match (or create new ones) - ([isSnapshotMatch, testFixtureFile, testSnapshotFile, newSnapshot]) => { - if (!isSnapshotMatch) { - console.log( - chalk.bold.yellow(`Updating snapshot for ${testFixtureFile}`) - ); - - // @ts-ignore -- no const assertions in JS files =( - fs.writeFileSync(testSnapshotFile, newSnapshot); - } - - return true; - } - : // check if any snapshots don't match - ([isSnapshotMatch, testFixtureFile]) => { - if (!isSnapshotMatch) { - console.log( - chalk.bold.red(`Snapshot mismatch for ${testFixtureFile}`) - ); - } - - return update || isSnapshotMatch; - } - ) - // check if all tests passed - .every((passed) => passed); - -// exit with a non-zero exit code if any tests failed -if (!passed) { - console.log(chalk.bold.red("\nFailed some tests")); - - process.exit(1); -} - -const end = Date.now(); -console.log(chalk.bold.green(`\nPassed all tests in ${(end - start) / 1000}s`)); diff --git a/tests/fixtures/001_basic_workflow/test.json b/tests/fixtures/001_basic_workflow/test.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/tests/fixtures/001_basic_workflow/test.json @@ -0,0 +1 @@ +{} diff --git a/test/001_basic_workflow/test.yml b/tests/fixtures/001_basic_workflow/test.yml similarity index 100% rename from test/001_basic_workflow/test.yml rename to tests/fixtures/001_basic_workflow/test.yml diff --git a/test/002_basic_action/action.yml b/tests/fixtures/002_basic_action/action.yml similarity index 100% rename from test/002_basic_action/action.yml rename to tests/fixtures/002_basic_action/action.yml diff --git a/tests/fixtures/002_basic_action/test.json b/tests/fixtures/002_basic_action/test.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/tests/fixtures/002_basic_action/test.json @@ -0,0 +1 @@ +{} diff --git a/tests/fixtures/003_successful_globs/excluded_path.json b/tests/fixtures/003_successful_globs/excluded_path.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/tests/fixtures/003_successful_globs/excluded_path.json @@ -0,0 +1 @@ +{} diff --git a/test/003_successful_globs/glob.yml b/tests/fixtures/003_successful_globs/glob.yml similarity index 74% rename from test/003_successful_globs/glob.yml rename to tests/fixtures/003_successful_globs/glob.yml index 2ba9749..e843dfa 100644 --- a/test/003_successful_globs/glob.yml +++ b/tests/fixtures/003_successful_globs/glob.yml @@ -3,8 +3,8 @@ name: Test on: push: paths: - - 003_successful_globs/* - - '!003_successful_globs/*.json' + - tests/fixtures/003_successful_globs/* + - '!tests/fixtures/003_successful_globs/*.json' defaults: run: diff --git a/tests/fixtures/003_successful_globs/test.json b/tests/fixtures/003_successful_globs/test.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/tests/fixtures/003_successful_globs/test.json @@ -0,0 +1 @@ +{} diff --git a/tests/fixtures/004_failing_globs/exitcode b/tests/fixtures/004_failing_globs/exitcode new file mode 100644 index 0000000..56a6051 --- /dev/null +++ b/tests/fixtures/004_failing_globs/exitcode @@ -0,0 +1 @@ +1 \ No newline at end of file diff --git a/test/004_failing_globs/glob.yml b/tests/fixtures/004_failing_globs/glob.yml similarity index 86% rename from test/004_failing_globs/glob.yml rename to tests/fixtures/004_failing_globs/glob.yml index 7c4d27e..dd9fb7a 100644 --- a/test/004_failing_globs/glob.yml +++ b/tests/fixtures/004_failing_globs/glob.yml @@ -3,7 +3,7 @@ name: Bad globs, no biscuit on: push: paths: - - 004_bad_globs/*.txt + - tests/fixtures/004_failing_globs/*.txt defaults: run: diff --git a/test/004_failing_globs/stderr b/tests/fixtures/004_failing_globs/stderr similarity index 66% rename from test/004_failing_globs/stderr rename to tests/fixtures/004_failing_globs/stderr index 2171874..e17de0d 100644 --- a/test/004_failing_globs/stderr +++ b/tests/fixtures/004_failing_globs/stderr @@ -3,13 +3,13 @@ Validation failed: ValidationState { Workflow, ), file_path: Some( - "004_failing_globs/glob.yml", + "{{repo}}/tests/fixtures/004_failing_globs/glob.yml", ), errors: [ NoFilesMatchingGlob { code: "glob_not_matched", detail: Some( - "Glob \"004_bad_globs/*.txt\" in /on/push/paths does not match any files", + "Glob \"tests/fixtures/004_failing_globs/*.txt\" in /on/push/paths does not match any files", ), path: "/on/push/paths", title: "Glob does not match any files", diff --git a/tests/fixtures/004_failing_globs/stdout b/tests/fixtures/004_failing_globs/stdout new file mode 100644 index 0000000..7a4a14f --- /dev/null +++ b/tests/fixtures/004_failing_globs/stdout @@ -0,0 +1 @@ +Fatal error validating {{repo}}/tests/fixtures/004_failing_globs/glob.yml diff --git a/tests/fixtures/004_failing_globs/test.json b/tests/fixtures/004_failing_globs/test.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/tests/fixtures/004_failing_globs/test.json @@ -0,0 +1 @@ +{} diff --git a/tests/fixtures/004a_failing_negative_glob/exitcode b/tests/fixtures/004a_failing_negative_glob/exitcode new file mode 100644 index 0000000..56a6051 --- /dev/null +++ b/tests/fixtures/004a_failing_negative_glob/exitcode @@ -0,0 +1 @@ +1 \ No newline at end of file diff --git a/test/004a_failing_negative_glob/glob.yml b/tests/fixtures/004a_failing_negative_glob/glob.yml similarity index 83% rename from test/004a_failing_negative_glob/glob.yml rename to tests/fixtures/004a_failing_negative_glob/glob.yml index 4cf6acc..577e41c 100644 --- a/test/004a_failing_negative_glob/glob.yml +++ b/tests/fixtures/004a_failing_negative_glob/glob.yml @@ -3,7 +3,7 @@ name: Bad globs, no biscuit on: push: paths: - - '!004a_failing_negative_glob/*.txt' + - '!tests/fixtures/004a_failing_negative_glob/*.txt' defaults: run: diff --git a/test/004a_failing_negative_glob/stderr b/tests/fixtures/004a_failing_negative_glob/stderr similarity index 64% rename from test/004a_failing_negative_glob/stderr rename to tests/fixtures/004a_failing_negative_glob/stderr index 029517a..b18be94 100644 --- a/test/004a_failing_negative_glob/stderr +++ b/tests/fixtures/004a_failing_negative_glob/stderr @@ -3,13 +3,13 @@ Validation failed: ValidationState { Workflow, ), file_path: Some( - "004a_failing_negative_glob/glob.yml", + "{{repo}}/tests/fixtures/004a_failing_negative_glob/glob.yml", ), errors: [ NoFilesMatchingGlob { code: "glob_not_matched", detail: Some( - "Glob \"!004a_failing_negative_glob/*.txt\" in /on/push/paths does not match any files", + "Glob \"!tests/fixtures/004a_failing_negative_glob/*.txt\" in /on/push/paths does not match any files", ), path: "/on/push/paths", title: "Glob does not match any files", diff --git a/tests/fixtures/004a_failing_negative_glob/stdout b/tests/fixtures/004a_failing_negative_glob/stdout new file mode 100644 index 0000000..c55beb0 --- /dev/null +++ b/tests/fixtures/004a_failing_negative_glob/stdout @@ -0,0 +1 @@ +Fatal error validating {{repo}}/tests/fixtures/004a_failing_negative_glob/glob.yml diff --git a/tests/fixtures/004a_failing_negative_glob/test.json b/tests/fixtures/004a_failing_negative_glob/test.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/tests/fixtures/004a_failing_negative_glob/test.json @@ -0,0 +1 @@ +{} diff --git a/test/005_conditional_step_in_action/action.yml b/tests/fixtures/005_conditional_step_in_action/action.yml similarity index 100% rename from test/005_conditional_step_in_action/action.yml rename to tests/fixtures/005_conditional_step_in_action/action.yml diff --git a/tests/fixtures/005_conditional_step_in_action/test.json b/tests/fixtures/005_conditional_step_in_action/test.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/tests/fixtures/005_conditional_step_in_action/test.json @@ -0,0 +1 @@ +{} diff --git a/tests/fixtures/006_workflow_dispatch_inputs_options/test.json b/tests/fixtures/006_workflow_dispatch_inputs_options/test.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/tests/fixtures/006_workflow_dispatch_inputs_options/test.json @@ -0,0 +1 @@ +{} diff --git a/test/006_workflow_dispatch_inputs_options/test.yml b/tests/fixtures/006_workflow_dispatch_inputs_options/test.yml similarity index 100% rename from test/006_workflow_dispatch_inputs_options/test.yml rename to tests/fixtures/006_workflow_dispatch_inputs_options/test.yml diff --git a/tests/fixtures/007_funky_syntax/exitcode b/tests/fixtures/007_funky_syntax/exitcode new file mode 100644 index 0000000..56a6051 --- /dev/null +++ b/tests/fixtures/007_funky_syntax/exitcode @@ -0,0 +1 @@ +1 \ No newline at end of file diff --git a/test/007_funky_syntax/rust-check.yml b/tests/fixtures/007_funky_syntax/rust-check.yml similarity index 100% rename from test/007_funky_syntax/rust-check.yml rename to tests/fixtures/007_funky_syntax/rust-check.yml diff --git a/test/007_funky_syntax/stderr b/tests/fixtures/007_funky_syntax/stderr similarity index 89% rename from test/007_funky_syntax/stderr rename to tests/fixtures/007_funky_syntax/stderr index 17c1d62..242b299 100644 --- a/test/007_funky_syntax/stderr +++ b/tests/fixtures/007_funky_syntax/stderr @@ -3,7 +3,7 @@ Validation failed: ValidationState { Workflow, ), file_path: Some( - "007_funky_syntax/rust-check.yml", + "{{repo}}/tests/fixtures/007_funky_syntax/rust-check.yml", ), errors: [ Parse { diff --git a/tests/fixtures/007_funky_syntax/stdout b/tests/fixtures/007_funky_syntax/stdout new file mode 100644 index 0000000..1a8310e --- /dev/null +++ b/tests/fixtures/007_funky_syntax/stdout @@ -0,0 +1 @@ +Fatal error validating {{repo}}/tests/fixtures/007_funky_syntax/rust-check.yml diff --git a/tests/fixtures/007_funky_syntax/test.json b/tests/fixtures/007_funky_syntax/test.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/tests/fixtures/007_funky_syntax/test.json @@ -0,0 +1 @@ +{} diff --git a/tests/fixtures/008_job_dependencies/exitcode b/tests/fixtures/008_job_dependencies/exitcode new file mode 100644 index 0000000..56a6051 --- /dev/null +++ b/tests/fixtures/008_job_dependencies/exitcode @@ -0,0 +1 @@ +1 \ No newline at end of file diff --git a/test/008_job_dependencies/stderr b/tests/fixtures/008_job_dependencies/stderr similarity index 84% rename from test/008_job_dependencies/stderr rename to tests/fixtures/008_job_dependencies/stderr index a8d64bf..592e8d6 100644 --- a/test/008_job_dependencies/stderr +++ b/tests/fixtures/008_job_dependencies/stderr @@ -3,7 +3,7 @@ Validation failed: ValidationState { Workflow, ), file_path: Some( - "008_job_dependencies/test.yml", + "{{repo}}/tests/fixtures/008_job_dependencies/test.yml", ), errors: [ UnresolvedJob { diff --git a/tests/fixtures/008_job_dependencies/stdout b/tests/fixtures/008_job_dependencies/stdout new file mode 100644 index 0000000..2c4d1ef --- /dev/null +++ b/tests/fixtures/008_job_dependencies/stdout @@ -0,0 +1 @@ +Fatal error validating {{repo}}/tests/fixtures/008_job_dependencies/test.yml diff --git a/tests/fixtures/008_job_dependencies/test.json b/tests/fixtures/008_job_dependencies/test.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/tests/fixtures/008_job_dependencies/test.json @@ -0,0 +1 @@ +{} diff --git a/test/008_job_dependencies/test.yml b/tests/fixtures/008_job_dependencies/test.yml similarity index 100% rename from test/008_job_dependencies/test.yml rename to tests/fixtures/008_job_dependencies/test.yml diff --git a/tests/fixtures/009_multi_file/exitcode b/tests/fixtures/009_multi_file/exitcode new file mode 100644 index 0000000..56a6051 --- /dev/null +++ b/tests/fixtures/009_multi_file/exitcode @@ -0,0 +1 @@ +1 \ No newline at end of file diff --git a/test/009_multi_file/stderr b/tests/fixtures/009_multi_file/stderr similarity index 90% rename from test/009_multi_file/stderr rename to tests/fixtures/009_multi_file/stderr index b4fe130..163df8e 100644 --- a/test/009_multi_file/stderr +++ b/tests/fixtures/009_multi_file/stderr @@ -3,7 +3,7 @@ Validation failed: ValidationState { Workflow, ), file_path: Some( - "009_multi_file/xinvalid.yml", + "{{repo}}/tests/fixtures/009_multi_file/xinvalid.yml", ), errors: [ Parse { diff --git a/tests/fixtures/009_multi_file/stdout b/tests/fixtures/009_multi_file/stdout new file mode 100644 index 0000000..8e20dc5 --- /dev/null +++ b/tests/fixtures/009_multi_file/stdout @@ -0,0 +1 @@ +Fatal error validating {{repo}}/tests/fixtures/009_multi_file/xinvalid.yml diff --git a/tests/fixtures/009_multi_file/test.json b/tests/fixtures/009_multi_file/test.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/tests/fixtures/009_multi_file/test.json @@ -0,0 +1 @@ +{} diff --git a/test/009_multi_file/valid.yml b/tests/fixtures/009_multi_file/valid.yml similarity index 100% rename from test/009_multi_file/valid.yml rename to tests/fixtures/009_multi_file/valid.yml diff --git a/test/009_multi_file/xinvalid.yml b/tests/fixtures/009_multi_file/xinvalid.yml similarity index 100% rename from test/009_multi_file/xinvalid.yml rename to tests/fixtures/009_multi_file/xinvalid.yml diff --git a/test/010_missing_shell_in_action/action.yml b/tests/fixtures/010_missing_shell_in_action/action.yml similarity index 100% rename from test/010_missing_shell_in_action/action.yml rename to tests/fixtures/010_missing_shell_in_action/action.yml diff --git a/tests/fixtures/010_missing_shell_in_action/exitcode b/tests/fixtures/010_missing_shell_in_action/exitcode new file mode 100644 index 0000000..56a6051 --- /dev/null +++ b/tests/fixtures/010_missing_shell_in_action/exitcode @@ -0,0 +1 @@ +1 \ No newline at end of file diff --git a/test/010_missing_shell_in_action/stderr b/tests/fixtures/010_missing_shell_in_action/stderr similarity index 98% rename from test/010_missing_shell_in_action/stderr rename to tests/fixtures/010_missing_shell_in_action/stderr index 84e3397..e6564ea 100644 --- a/test/010_missing_shell_in_action/stderr +++ b/tests/fixtures/010_missing_shell_in_action/stderr @@ -3,7 +3,7 @@ Validation failed: ValidationState { Action, ), file_path: Some( - "010_missing_shell_in_action/action.yml", + "{{repo}}/tests/fixtures/010_missing_shell_in_action/action.yml", ), errors: [ OneOf { diff --git a/tests/fixtures/010_missing_shell_in_action/stdout b/tests/fixtures/010_missing_shell_in_action/stdout new file mode 100644 index 0000000..61cb959 --- /dev/null +++ b/tests/fixtures/010_missing_shell_in_action/stdout @@ -0,0 +1 @@ +Fatal error validating {{repo}}/tests/fixtures/010_missing_shell_in_action/action.yml diff --git a/tests/fixtures/010_missing_shell_in_action/test.json b/tests/fixtures/010_missing_shell_in_action/test.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/tests/fixtures/010_missing_shell_in_action/test.json @@ -0,0 +1 @@ +{} diff --git a/test/003_subdir_globs/subdir/dummy.json b/tests/fixtures/011_subdir_globs/subdir/dummy.json similarity index 100% rename from test/003_subdir_globs/subdir/dummy.json rename to tests/fixtures/011_subdir_globs/subdir/dummy.json diff --git a/test/003_subdir_globs/subdir/glob.yml b/tests/fixtures/011_subdir_globs/subdir/glob.yml similarity index 100% rename from test/003_subdir_globs/subdir/glob.yml rename to tests/fixtures/011_subdir_globs/subdir/glob.yml diff --git a/tests/fixtures/011_subdir_globs/test.json b/tests/fixtures/011_subdir_globs/test.json new file mode 100644 index 0000000..60b9ffd --- /dev/null +++ b/tests/fixtures/011_subdir_globs/test.json @@ -0,0 +1,3 @@ +{ + "cli_args": ["--rootdir", "tests/fixtures/011_subdir_globs/subdir", "tests/fixtures/011_subdir_globs/subdir/glob.yml"] +} diff --git a/tests/snapshot_tests.rs b/tests/snapshot_tests.rs new file mode 100644 index 0000000..504d1e8 --- /dev/null +++ b/tests/snapshot_tests.rs @@ -0,0 +1,170 @@ +use std::env::current_dir; +use std::fs::File; +use std::io::BufReader; +use std::path::{Path, PathBuf}; +use std::{ffi::OsStr, fs}; + +use assert_cmd::Command; +use fixtures::fixtures; + +static REPO_DIR_WILDCARD: &str = "{{repo}}"; + +#[derive(Debug, serde::Deserialize)] +struct SnapshotTestConfig { + cli_args: Option>, +} + +#[derive(Debug)] +struct SnapshotTest { + config: SnapshotTestConfig, + current_dir: PathBuf, + test_dir: PathBuf, +} + +impl SnapshotTest { + fn new(test_dir: &Path) -> Self { + let test_config_file = test_dir.join("test.json"); + + let config: SnapshotTestConfig = serde_json::from_reader(BufReader::new( + File::open(&test_config_file).expect(&format!( + "missing test conifg file ({})", + test_config_file.to_string_lossy(), + )), + )) + .expect(&format!( + "invalid test config file ({})", + test_config_file.to_string_lossy(), + )); + + SnapshotTest { + config, + current_dir: current_dir().unwrap(), + test_dir: test_dir.to_path_buf(), + } + } + + fn build_command(&self) -> Command { + #[cfg(not(feature = "test-js"))] + { + Command::cargo_bin(env!("CARGO_PKG_NAME")).expect("binary to execute") + } + + #[cfg(feature = "test-js")] + { + let mut cmd = Command::new("npx"); + cmd.arg("@action-validator/cli"); + cmd + } + } + + fn execute(self) { + use std::ffi::OsString; + + let pwd = self.current_dir.to_str().unwrap(); + + let cli_args: Vec<_> = if let Some(cli_args) = &self.config.cli_args { + cli_args.iter().map(OsString::from).collect() + } else { + fs::read_dir(&self.test_dir) + .unwrap() + .filter_map(Result::ok) + .filter(|f| f.path().extension() == Some(OsStr::new("yml"))) + .map(|f| f.path().into_os_string()) + .collect() + }; + + #[cfg(not(feature = "test-save-snapshots"))] + { + let stderr = fs::read_to_string(self.test_dir.join("stderr")) + .unwrap_or(String::from("")) + .replace(REPO_DIR_WILDCARD, pwd); + + let stdout = fs::read_to_string(self.test_dir.join("stdout")) + .unwrap_or(String::from("")) + .replace(REPO_DIR_WILDCARD, pwd); + + let exitcode: i32 = fs::read_to_string(self.test_dir.join("exitcode")) + .map(|s| { + s.strip_suffix("\n") + .unwrap_or(s.as_str()) + .parse::() + .unwrap_or(0) + }) + .unwrap_or(0); + + self.build_command() + .args(&cli_args) + .assert() + .stdout(stdout) + .stderr(stderr) + .code(exitcode); + } + + #[cfg(feature = "test-save-snapshots")] + { + use std::io::prelude::*; + + let result = self + .build_command() + .args(&cli_args) + .ok() + .unwrap_or_else(|e| e.as_output().unwrap().to_owned()); + + if !result.stdout.is_empty() { + File::create(self.test_dir.join("stdout")) + .unwrap() + .write_all( + String::from_utf8(result.stdout) + .unwrap() + .replace(pwd, REPO_DIR_WILDCARD) + .as_bytes(), + ) + .unwrap(); + } + if !result.stderr.is_empty() { + File::create(self.test_dir.join("stderr")) + .unwrap() + .write_all( + String::from_utf8(result.stderr) + .unwrap() + .replace(pwd, REPO_DIR_WILDCARD) + .as_bytes(), + ) + .unwrap(); + } + if let Some(exitcode) = result.status.code() { + if exitcode > 0 { + File::create(self.test_dir.join("exitcode")) + .unwrap() + .write_all(exitcode.to_string().as_bytes()) + .unwrap(); + } + } + } + } +} + +#[fixtures(["tests/fixtures/*"])] +#[cfg_attr( + feature = "test-js", + fixtures::ignore( + paths = "tests/fixtures/003_successful_globs", + reason = "Glob support is not implemented for JS targets yet." + ), + fixtures::ignore( + paths = "tests/fixtures/004_failing_globs", + reason = "Glob support is not implemented for JS targets yet." + ), + fixtures::ignore( + paths = "tests/fixtures/004a_failing_negative_glob", + reason = "Glob support is not implemented for JS targets yet." + ), + fixtures::ignore( + paths = "tests/fixtures/011_subdir_globs", + reason = "Glob support is not implemented for JS targets yet." + ) +)] +#[test] +fn snapshot(dir: &Path) { + SnapshotTest::new(dir).execute(); +}