diff options
author | Nick Gerace <nickagerace@gmail.com> | 2023-03-28 17:50:36 -0400 |
---|---|---|
committer | Nick Gerace <nickagerace@gmail.com> | 2023-04-07 13:44:47 -0400 |
commit | f3a4c1563218ac35f8ecfe131de9eb8c50292a9e (patch) | |
tree | b949bb567eaebc108b118d65485d7b4e5eac3c6f | |
parent | bb91ee33ca811f8cf28791710c40e8c4fe0b0aa3 (diff) | |
download | gfold-f3a4c1563218ac35f8ecfe131de9eb8c50292a9e.zip |
Restore cargo xtask
Primary:
- Restore cargo xtask to the repository
- Polish "size" and "loose-bench" tasks and integrate them with cargo
xtask
- Update documentation to reflect new xtask changes
- Move ci to use cargo xtask
Secondary:
- Remove unneeded run from gfold test
Signed-off-by: Nick Gerace <nickagerace@gmail.com>
-rw-r--r-- | .cargo/config | 3 | ||||
-rw-r--r-- | .github/workflows/ci.yml | 23 | ||||
-rw-r--r-- | Cargo.lock | 401 | ||||
-rw-r--r-- | Cargo.toml | 2 | ||||
-rw-r--r-- | crates/bench-loosely/Cargo.toml | 7 | ||||
-rw-r--r-- | crates/bench-loosely/src/main.rs | 180 | ||||
-rw-r--r-- | crates/gfold/Cargo.toml | 4 | ||||
-rw-r--r-- | crates/gfold/src/main.rs | 16 | ||||
-rw-r--r-- | crates/size/Cargo.toml | 7 | ||||
-rw-r--r-- | crates/size/src/main.rs | 54 | ||||
-rw-r--r-- | crates/xtask/Cargo.toml | 12 | ||||
-rw-r--r-- | crates/xtask/src/main.rs | 69 | ||||
-rw-r--r-- | crates/xtask/src/task.rs | 118 | ||||
-rw-r--r-- | crates/xtask/src/task/bloat.rs | 13 | ||||
-rw-r--r-- | crates/xtask/src/task/build.rs | 12 | ||||
-rw-r--r-- | crates/xtask/src/task/build_release.rs | 12 | ||||
-rw-r--r-- | crates/xtask/src/task/ci.rs | 19 | ||||
-rw-r--r-- | crates/xtask/src/task/loose_bench.rs | 142 | ||||
-rw-r--r-- | crates/xtask/src/task/prepare.rs | 15 | ||||
-rw-r--r-- | crates/xtask/src/task/scan.rs | 13 | ||||
-rw-r--r-- | crates/xtask/src/task/size.rs | 49 | ||||
-rw-r--r-- | docs/DEVELOPING.md | 49 | ||||
-rw-r--r-- | docs/RELEASE.md | 6 |
23 files changed, 738 insertions, 488 deletions
diff --git a/.cargo/config b/.cargo/config index 9825746..337141e 100644 --- a/.cargo/config +++ b/.cargo/config @@ -1,2 +1,5 @@ [build] rustdocflags = "--document-private-items" + +[alias] +xtask = "run -q --manifest-path ./crates/xtask/Cargo.toml --"
\ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cde6f1d..6adf7dd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -26,28 +26,11 @@ jobs: toolchain: stable override: true components: rustfmt, clippy - - uses: actions-rs/cargo@v1 - with: - command: fmt - args: --all -- --check - uses: Swatinem/rust-cache@v1 - uses: actions-rs/cargo@v1 with: - command: clippy - args: -- -D warnings - - uses: actions-rs/cargo@v1 - with: - command: doc - args: --all - env: - RUSTDOCFLAGS: "-Dwarnings" - - uses: actions-rs/cargo@v1 - with: - command: test - - uses: actions-rs/cargo@v1 - with: - command: build - args: --locked + command: xtask + args: ci build: name: "Test / Build" runs-on: ${{ matrix.os }} @@ -68,4 +51,4 @@ jobs: - uses: actions-rs/cargo@v1 with: command: build - args: --locked + args: --all-targets --locked @@ -18,6 +18,46 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] +name = "anstream" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "342258dd14006105c2b75ab1bd7543a03bdf0cfc94383303ac212a04939dff6f" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-wincon", + "concolor-override", + "concolor-query", + "is-terminal", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23ea9e81bd02e310c216d080f6223c179012256e5151c41db88d12c88a1684d2" + +[[package]] +name = "anstyle-parse" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7d1bb534e9efed14f3e5f44e7dd1a4f709384023a4165199a4241e18dff0116" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-wincon" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3127af6145b149f3287bb9a0d10ad9c5692dba8c53ad48285e5bec4063834fa" +dependencies = [ + "anstyle", + "windows-sys 0.45.0", +] + +[[package]] name = "anyhow" version = "1.0.70" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -48,25 +88,12 @@ dependencies = [ ] [[package]] -name = "bench-loosely" -version = "0.1.0" -dependencies = [ - "dirs 4.0.0", -] - -[[package]] name = "bitflags" version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] -name = "bitflags" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "487f1e0fcbe47deb8b0574e646def1c903389d95241dd1bbcc6ce4a715dfc0c1" - -[[package]] name = "cc" version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -83,39 +110,59 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "4.1.11" +version = "4.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42dfd32784433290c51d92c438bb72ea5063797fc3cc9a21a8c4346bebbb2098" +checksum = "046ae530c528f252094e4a77886ee1374437744b2bff1497aa898bbddbbb29b3" dependencies = [ - "bitflags 2.0.2", + "clap_builder", "clap_derive", - "clap_lex", - "is-terminal", "once_cell", +] + +[[package]] +name = "clap_builder" +version = "4.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "223163f58c9a40c3b0a43e1c4b50a9ce09f007ea2cb1ec258a687945b4b7929f" +dependencies = [ + "anstream", + "anstyle", + "bitflags", + "clap_lex", "strsim", - "termcolor", ] [[package]] name = "clap_derive" -version = "4.1.9" +version = "4.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fddf67631444a3a3e3e5ac51c36a5e01335302de677bd78759eaa90ab1f46644" +checksum = "3f9644cd56d6b87dbe899ef8b053e331c0637664e9e21a33dfcdc36093f5c5c4" dependencies = [ "heck", - "proc-macro-error", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.13", ] [[package]] name = "clap_lex" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a2dd5a6fe8c6e3502f568a6353e5273bbb15193ad9a89e457b9970798efbea1" + +[[package]] +name = "concolor-override" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a855d4a1978dc52fb0536a04d384c2c0c1aa273597f08b77c8c4d3b2eec6037f" + +[[package]] +name = "concolor-query" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "033f6b7a4acb1f358c742aaca805c939ee73b4c6209ae4318ec7aca81c42e646" +checksum = "88d11d52c3d7ca2e6d0040212be9e4dbbcd78b6447f535b6b561f449427944cf" dependencies = [ - "os_str_bytes", + "windows-sys 0.45.0", ] [[package]] @@ -179,31 +226,11 @@ checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" [[package]] name = "dirs" -version = "4.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" -dependencies = [ - "dirs-sys 0.3.7", -] - -[[package]] -name = "dirs" version = "5.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dece029acd3353e3a58ac2e3eb3c8d6c35827a892edc6cc4138ef9c33df46ecd" dependencies = [ - "dirs-sys 0.4.0", -] - -[[package]] -name = "dirs-sys" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" -dependencies = [ - "libc", - "redox_users", - "winapi", + "dirs-sys", ] [[package]] @@ -235,13 +262,13 @@ dependencies = [ [[package]] name = "errno" -version = "0.2.8" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" +checksum = "50d6a0976c999d473fe89ad888d5a284e55366d9dc9038b1ba2aa15128c4afa0" dependencies = [ "errno-dragonfly", "libc", - "winapi", + "windows-sys 0.45.0", ] [[package]] @@ -274,9 +301,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" +checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4" dependencies = [ "cfg-if", "libc", @@ -289,7 +316,7 @@ version = "4.3.2" dependencies = [ "anyhow", "clap", - "dirs 5.0.0", + "dirs", "env_logger", "git2", "log", @@ -315,7 +342,7 @@ version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ccf7f68c2995f392c49fffb4f95ae2c873297830eb25c6bc4c114ce8f4562acc" dependencies = [ - "bitflags 1.3.2", + "bitflags", "libc", "libgit2-sys", "log", @@ -367,9 +394,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "1.9.2" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ "autocfg", "hashbrown", @@ -386,25 +413,25 @@ dependencies = [ [[package]] name = "io-lifetimes" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09270fd4fa1111bc614ed2246c7ef56239a3063d5be0d1ec3b589c505d400aeb" +checksum = "9c66c74d2ae7e79a5a8f7ac924adbe38ee42a859c6539ad869eb51f0b52dc220" dependencies = [ "hermit-abi 0.3.1", "libc", - "windows-sys 0.45.0", + "windows-sys 0.48.0", ] [[package]] name = "is-terminal" -version = "0.4.5" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8687c819457e979cc940d09cb16e42a1bf70aa6b60a549de6d3a62a0ee90c69e" +checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f" dependencies = [ "hermit-abi 0.3.1", "io-lifetimes", "rustix", - "windows-sys 0.45.0", + "windows-sys 0.48.0", ] [[package]] @@ -424,9 +451,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.140" +version = "0.2.141" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c" +checksum = "3304a64d199bb964be99741b7a14d26972741915b3649639149b2479bb46f4b5" [[package]] name = "libgit2-sys" @@ -454,9 +481,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.1.4" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" +checksum = "d59d8c75012853d2e872fb56bc8a2e53718e2cafe1a4c823143141c6d90c322f" [[package]] name = "log" @@ -517,12 +544,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" [[package]] -name = "os_str_bytes" -version = "6.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ceedf44fb00f2d1984b0bc98102627ce622e083e49a5bacdb3e514fa4238e267" - -[[package]] name = "output_vt100" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -556,34 +577,10 @@ dependencies = [ ] [[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.52" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d0e1ae9e836cc3beddd63db0df682593d7e2d3d891ae8c9083d2113e1744224" +checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435" dependencies = [ "unicode-ident", ] @@ -625,7 +622,16 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" dependencies = [ - "bitflags 1.3.2", + "bitflags", +] + +[[package]] +name = "redox_syscall" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +dependencies = [ + "bitflags", ] [[package]] @@ -635,31 +641,37 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" dependencies = [ "getrandom", - "redox_syscall", + "redox_syscall 0.2.16", "thiserror", ] [[package]] name = "rustc-demangle" -version = "0.1.21" +version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" +checksum = "d4a36c42d1873f9a77c53bde094f9664d9891bc604a45b4798fd2c389ed12e5b" [[package]] name = "rustix" -version = "0.36.11" +version = "0.37.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db4165c9963ab29e422d6c26fbc1d37f15bace6b2810221f9d925023480fcf0e" +checksum = "1aef160324be24d31a62147fae491c14d2204a3865c7ca8c3b0d7f7bcb3ea635" dependencies = [ - "bitflags 1.3.2", + "bitflags", "errno", "io-lifetimes", "libc", "linux-raw-sys", - "windows-sys 0.45.0", + "windows-sys 0.48.0", ] [[package]] +name = "rustversion" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f3208ce4d8448b3f3e7d168a73f5e0c43a61e32930de3bceeccedb388b6bf06" + +[[package]] name = "ryu" version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -673,29 +685,29 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "serde" -version = "1.0.158" +version = "1.0.159" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "771d4d9c4163ee138805e12c710dd365e4f44be8be0503cb1bb9eb989425d9c9" +checksum = "3c04e8343c3daeec41f58990b9d77068df31209f2af111e059e9fe9646693065" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.158" +version = "1.0.159" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e801c1712f48475582b7696ac71e0ca34ebb30e09338425384269d9717c62cad" +checksum = "4c614d17805b093df4b147b51339e7e44bf05ef59fba1e45d83500bcfb4d8585" dependencies = [ "proc-macro2", "quote", - "syn 2.0.3", + "syn 2.0.13", ] [[package]] name = "serde_json" -version = "1.0.94" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c533a59c9d8a93a09c6ab31f0fd5e5f4dd1b8fc9434804029839884765d04ea" +checksum = "d721eca97ac802aa7777b701877c8004d950fc142651367300d21c1cc0194744" dependencies = [ "itoa", "ryu", @@ -712,17 +724,32 @@ dependencies = [ ] [[package]] -name = "size" -version = "0.1.0" +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "strum" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f" dependencies = [ - "dirs 4.0.0", + "strum_macros", ] [[package]] -name = "strsim" -version = "0.10.0" +name = "strum_macros" +version = "0.24.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn 1.0.109", +] [[package]] name = "syn" @@ -737,9 +764,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.3" +version = "2.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8234ae35e70582bfa0f1fedffa6daa248e41dd045310b19800c4a36382c8f60" +checksum = "4c9da457c5285ac1f936ebd076af6dac17a61cfe7826f2076b4d015cf47bc8ec" dependencies = [ "proc-macro2", "quote", @@ -748,15 +775,15 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.4.0" +version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af18f7ae1acd354b992402e9ec5864359d693cd8a79dcbef59f76891701c1e95" +checksum = "b9fbec84f381d5795b08656e4912bec604d162bff9291d6189a78f4c8ab87998" dependencies = [ "cfg-if", "fastrand", - "redox_syscall", + "redox_syscall 0.3.5", "rustix", - "windows-sys 0.42.0", + "windows-sys 0.45.0", ] [[package]] @@ -785,7 +812,7 @@ checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.3", + "syn 2.0.13", ] [[package]] @@ -826,9 +853,9 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.19.7" +version = "0.19.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc18466501acd8ac6a3f615dd29a3438f8ca6bb3b19537138b3106e575621274" +checksum = "239410c8609e8125456927e6707163a3b1fdb40561e4b803bc041f466ccfdc13" dependencies = [ "indexmap", "serde", @@ -839,9 +866,9 @@ dependencies = [ [[package]] name = "unicode-bidi" -version = "0.3.12" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d502c968c6a838ead8e69b2ee18ec708802f99db92a0d156705ec9ef801993b" +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" [[package]] name = "unicode-ident" @@ -870,16 +897,16 @@ dependencies = [ ] [[package]] -name = "vcpkg" -version = "0.2.15" +name = "utf8parse" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" [[package]] -name = "version_check" -version = "0.9.4" +name = "vcpkg" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" [[package]] name = "wasi" @@ -920,26 +947,20 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows-sys" -version = "0.42.0" +version = "0.45.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" 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", + "windows-targets 0.42.2", ] [[package]] name = "windows-sys" -version = "0.45.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets", + "windows-targets 0.48.0", ] [[package]] @@ -948,13 +969,28 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" 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", + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-targets" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +dependencies = [ + "windows_aarch64_gnullvm 0.48.0", + "windows_aarch64_msvc 0.48.0", + "windows_i686_gnu 0.48.0", + "windows_i686_msvc 0.48.0", + "windows_x86_64_gnu 0.48.0", + "windows_x86_64_gnullvm 0.48.0", + "windows_x86_64_msvc 0.48.0", ] [[package]] @@ -964,51 +1000,104 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" [[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" + +[[package]] name = "windows_aarch64_msvc" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" [[package]] +name = "windows_aarch64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" + +[[package]] name = "windows_i686_gnu" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" [[package]] +name = "windows_i686_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" + +[[package]] name = "windows_i686_msvc" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" [[package]] +name = "windows_i686_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" + +[[package]] name = "windows_x86_64_gnu" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" [[package]] +name = "windows_x86_64_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" + +[[package]] name = "windows_x86_64_gnullvm" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" [[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" + +[[package]] name = "windows_x86_64_msvc" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" [[package]] +name = "windows_x86_64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" + +[[package]] name = "winnow" -version = "0.3.6" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23d020b441f92996c80d94ae9166e8501e59c7bb56121189dc9eab3bd8216966" +checksum = "ae8970b36c66498d8ff1d66685dc86b91b29db0c7739899012f63a63814b4b28" dependencies = [ "memchr", ] [[package]] +name = "xtask" +version = "0.1.0" +dependencies = [ + "clap", + "dirs", + "strum", + "termcolor", + "thiserror", +] + +[[package]] name = "yansi" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1,5 +1,5 @@ [workspace] -members = ["crates/*"] +members = ["crates/gfold", "crates/xtask"] default-members = ["crates/gfold"] [profile.release.package.gfold] diff --git a/crates/bench-loosely/Cargo.toml b/crates/bench-loosely/Cargo.toml deleted file mode 100644 index d090406..0000000 --- a/crates/bench-loosely/Cargo.toml +++ /dev/null @@ -1,7 +0,0 @@ -[package] -name = "bench-loosely" -version = "0.1.0" -edition = "2021" - -[dependencies] -dirs = "4.0" diff --git a/crates/bench-loosely/src/main.rs b/crates/bench-loosely/src/main.rs deleted file mode 100644 index 52aa498..0000000 --- a/crates/bench-loosely/src/main.rs +++ /dev/null @@ -1,180 +0,0 @@ -//! This is the loose bench for gfold. Why use a loose bench over a precise one? Most of gfold -//! development happens with a mobile processor, which is prone to performance fluctuations over -//! background I/O operations, battery life and temperature. Moreover, the "real world" use case of -//! gfold is via CLI and not a library. Thus, this loose bench executes gfold as a CLI similarly -//! to real world use. This benchmark is not precise and is designed to give a high level overview. - -// TODO(nick): add consistency deviation. We should see how far each result strays from the average. -// We want gfold to perform consistently as well as quickly. - -use std::path::Path; -use std::process::Command; -use std::time::{Duration, Instant}; - -fn main() { - let global_instant = Instant::now(); - - let manifest_dir = Path::new(env!("CARGO_MANIFEST_DIR")); - let repo = manifest_dir - .parent() - .expect("could not get parent") - .parent() - .expect("could not get parent"); - - println!("running in {:?}: cargo build --release", &repo); - let output = Command::new("cargo") - .arg("build") - .arg("--release") - .current_dir(repo) - .output() - .expect("could not execute command"); - if !output.status.success() { - panic!("command failed: \"cargo build --release\""); - } - - let binary = repo.join("target").join("release").join("gfold"); - let home_path = dirs::home_dir().expect("could not find home directory"); - let installed = home_path.join(".cargo").join("bin").join("gfold"); - let home = home_path.to_str().expect("could not convert to str"); - - // Add "1" to total runs to ensure caching does not skew results. We need one - // "warm up" run. - let runs = 41; - - // Loosely bench using the home directory as the target. - let mut home_new_durations = Vec::new(); - let mut home_old_durations = Vec::new(); - let mut first = true; - for run in 0..runs { - println!("group {} of {} in {}", run + 1, runs, home); - - // Alternate at the halfway point. Though, it is doubtful that this would actually change anything. - // Only calculate the average after the first run to avoid caching skewing results. - if run > runs / 2 { - let (old_duration, new_duration) = loose_bench(&installed, &binary, &home_path); - if first { - first = false; - } else { - home_new_durations.push(new_duration); - home_old_durations.push(old_duration); - } - } else { - let (new_duration, old_duration) = loose_bench(&binary, &installed, &home_path); - if first { - first = false; - } else { - home_new_durations.push(new_duration); - home_old_durations.push(old_duration); - } - } - } - - // Loosely bench with the parent directory of the repository as the target. - let parent_of_repo = repo.parent().expect("could not get parent"); - let parent = parent_of_repo.to_str().expect("could not convert to str"); - let mut parent_new_durations = Vec::new(); - let mut parent_old_durations = Vec::new(); - let mut first = true; - for run in 0..runs { - println!("group {} of {} in {}", run + 1, runs, parent); - - // Alternate at the halfway point. Though, it is doubtful that this would actually change anything. - // Only calculate the average after the first run to avoid caching skewing results. - if run > runs / 2 { - let (old_duration, new_duration) = loose_bench(&installed, &binary, parent_of_repo); - if first { - first = false; - } else { - parent_new_durations.push(new_duration); - parent_old_durations.push(old_duration); - } - } else { - let (new_duration, old_duration) = loose_bench(&binary, &installed, parent_of_repo); - if first { - first = false; - } else { - parent_new_durations.push(new_duration); - parent_old_durations.push(old_duration); - } - } - } - - // Print the averages. Start with a multi-platform empty newline print. - println!(); - println!( - "Average: {:?} - {} - {}", - average_duration(&home_new_durations), - home, - &binary.display(), - ); - println!( - "Average: {:?} - {} - {}", - average_duration(&home_old_durations), - home, - &installed.display(), - ); - println!( - "Average: {:?} - {} - {}", - average_duration(&parent_new_durations), - parent, - &binary.display(), - ); - println!( - "Average: {:?} - {} - {}", - average_duration(&parent_old_durations), - parent, - &installed.display(), - ); - - // Display the global duration for the entire script. Start with a multi-platform empty newline - // print. - println!(); - println!("Total duration: {:?}", global_instant.elapsed()); -} - -fn loose_bench(first: &Path, second: &Path, target: &Path) -> (Duration, Duration) { - let first_duration = execute(first, target); - let second_duration = execute(second, target); - let (first_text, second_text) = match first_duration { - first_duration if first_duration > second_duration => ("LOST", "WON "), - first_duration if first_duration < second_duration => ("WON ", "LOST"), - _ => ("TIE ", "TIE "), - }; - - println!( - " {} @ {:?} - {}", - first_text, - first_duration, - first.to_str().expect("could not convert to str"), - ); - println!( - " {} @ {:?} - {}", - second_text, - second_duration, - second.to_str().expect("could not convert to str"), - ); - (first_duration, second_duration) -} - -fn execute(binary: &Path, target: &Path) -> Duration { - let start = Instant::now(); - let output = Command::new(binary) - .arg("-i") - .arg(target) - .output() - .expect("could not execute command"); - let duration = start.elapsed(); - - // Check for failure _after_ the bench finishes. - if !output.status.success() { - panic!("bench failed"); - } - - duration -} - -fn average_duration(durations: &[Duration]) -> Duration { - let sum = durations.iter().sum::<Duration>(); - let count = durations.len() as f32; - sum.div_f32(count) -} diff --git a/crates/gfold/Cargo.toml b/crates/gfold/Cargo.toml index 76daf14..fdb581f 100644 --- a/crates/gfold/Cargo.toml +++ b/crates/gfold/Cargo.toml @@ -14,7 +14,7 @@ version = "4.3.2" [dependencies] anyhow = { version = "1.0", features = ["backtrace"] } -clap = { version = "4.1", features = ["derive"] } +clap = { version = "4.2", features = ["derive"] } dirs = "5.0" env_logger = { version = "0.10", features = ["humantime"], default_features = false } git2 = { version = "0.16", default_features = false } @@ -28,4 +28,4 @@ toml = "0.7" [dev-dependencies] pretty_assertions = "1.3" -tempfile = "3.4" +tempfile = "3.5" diff --git a/crates/gfold/src/main.rs b/crates/gfold/src/main.rs index 964fd5e..47175b5 100644 --- a/crates/gfold/src/main.rs +++ b/crates/gfold/src/main.rs @@ -50,9 +50,8 @@ mod tests { use tempfile::tempdir; use crate::collector::{RepositoryCollection, RepositoryCollector}; - use crate::config::{ColorMode, Config, DisplayMode}; + use crate::config::{Config, DisplayMode}; use crate::repository_view::RepositoryView; - use crate::run::RunHarness; use crate::status::Status; /// This integration test for `gfold` covers an end-to-end usage scenario. It uses the @@ -129,15 +128,8 @@ mod tests { commit_head_and_create_branch(&repository, "needtopush")?; repository.set_head("refs/heads/needtopush")?; - // Run once with default display mode. - let mut config = Config::try_config_default()?; - config.path = root.path().to_path_buf(); - config.color_mode = ColorMode::Never; - let run_harness = RunHarness::new(&config); - run_harness.run()?; - - // Now, let's run a second time, but generate the collection directly and ensure the - // resulting views match what we expect. + // Generate the collection directly with a default config and ensure the resulting views + // match what we expect. let mut expected_collection = RepositoryCollection::new(); let expected_views_key = root .path() @@ -216,6 +208,8 @@ mod tests { expected_collection.insert(Some(nested_expected_views_key), nested_expected_views_raw); // Generate a collection. Use classic display mode to avoid collecting email results. + let mut config = Config::try_config_default()?; + config.path = root.path().to_path_buf(); config.display_mode = DisplayMode::Classic; let found_collection = RepositoryCollector::run(&config.path, config.display_mode)?; diff --git a/crates/size/Cargo.toml b/crates/size/Cargo.toml deleted file mode 100644 index 9b56e93..0000000 --- a/crates/size/Cargo.toml +++ /dev/null @@ -1,7 +0,0 @@ -[package] -name = "size" -version = "0.1.0" -edition = "2021" - -[dependencies] -dirs = "4.0" diff --git a/crates/size/src/main.rs b/crates/size/src/main.rs deleted file mode 100644 index bd9b313..0000000 --- a/crates/size/src/main.rs +++ /dev/null @@ -1,54 +0,0 @@ -use std::fs; -use std::fs::Metadata; -use std::io; -use std::path::{Path, PathBuf}; -use std::process::Command; - -fn main() { - let manifest_dir = Path::new(env!("CARGO_MANIFEST_DIR")); - let repo = manifest_dir - .parent() - .expect("could not get parent") - .parent() - .expect("could not get parent"); - - println!("running in {:?}: cargo build --release", &repo); - let output = Command::new("cargo") - .arg("build") - .arg("--release") - .current_dir(repo) - .output() - .expect("could not execute command"); - if !output.status.success() { - panic!("command failed: \"cargo build --release\""); - } - - let binary = repo.join("target").join("release").join("gfold"); - let metadata = fs::metadata(&binary).expect("could not get metadata"); - print_binary_size(&metadata, &binary); - - // Check if the binary is currently installed to compare release build sizes. If it is not, - // we can skip this check. - let home = dirs::home_dir().expect("could not find home directory"); - let installed = home.join(".cargo").join("bin").join("gfold"); - match fs::metadata(&installed) { - Ok(metadata) => { - print_binary_size(&metadata, &installed); - } - Err(e) if e.kind() == io::ErrorKind::NotFound => {} - Err(e) => panic!( - "encountered error when trying to get metadata for file: {}", - e.to_string() - ), - } -} - -fn print_binary_size(metadata: &Metadata, path: &PathBuf) { - // Divisor used to perform human readable size conversion. - // 1048576.0 = 1024.0 * 1024.0 - println!( - "{:.3} MB - {}", - metadata.len() as f64 / 1048576.0, - path.to_str().expect("could not convert to str") - ); -} diff --git a/crates/xtask/Cargo.toml b/crates/xtask/Cargo.toml new file mode 100644 index 0000000..901a138 --- /dev/null +++ b/crates/xtask/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "xtask" +version = "0.1.0" +edition = "2021" +publish = false + +[dependencies] +clap = { version = "4.2", features = ["derive"] } +dirs = "5.0" +strum = { version = "0.24", features = ["derive"] } +termcolor = "1.2" +thiserror = "1.0"
\ No newline at end of file diff --git a/crates/xtask/src/main.rs b/crates/xtask/src/main.rs new file mode 100644 index 0000000..c1d7d5a --- /dev/null +++ b/crates/xtask/src/main.rs @@ -0,0 +1,69 @@ +//! This crate is an example of the [`cargo-xtask`](https://github.com/matklad/cargo-xtask) pattern. + +mod task; + +use clap::{Parser, Subcommand}; +use std::io; +use std::process::Output; +use strum::Display; +use thiserror::Error; + +pub use task::TaskHarness; +pub use task::TaskRunner; + +#[derive(Error, Debug)] +pub enum TaskError { + #[error(transparent)] + Io(#[from] io::Error), + + #[error("cargo command failed")] + CargoCommandFailed, + #[error("could not determine repository root")] + CouldNotDetermineRepositoryRoot, + #[error("home directory not found")] + HomeDirectoryNotFound, + #[error("invalid task provided: {0}")] + InvalidTaskProvided(String), + #[error("repository does not have parent directory (this should be impossible)")] + RepositoryDoesNotHaveParentDirectory, + #[error("command during loose bench was not successful: {0:?}")] + UnsuccessfulCommandDuringLooseBench(Output), +} + +pub type TaskResult<T> = Result<T, TaskError>; + +#[derive(Parser)] +#[command(long_about = None)] +struct Cli { + #[command(subcommand)] + command: Task, +} + +#[derive(Display, Subcommand)] +#[strum(serialize_all = "kebab-case")] +pub enum Task { + /// Scan for potential bloat + Bloat, + /// Build all targets + Build, + /// Build all targets, scan and check binary size + BuildRelease, + /// Run the ci suite + Ci, + /// Perform loose bench + LooseBench, + /// Run update, and baseline lints and checks + Prepare, + /// Scan for vulnerabilities and unused dependencies + Scan, + /// Get the release binary size (and compare to the installed binary size from "crates.io", if + /// it exists) + Size, +} + +fn main() -> TaskResult<()> { + let cli = Cli::parse(); + let mut harness = TaskHarness::new()?; + harness.task(cli.command)?; + Ok(()) +} diff --git a/crates/xtask/src/task.rs b/crates/xtask/src/task.rs new file mode 100644 index 0000000..d5d4bc9 --- /dev/null +++ b/crates/xtask/src/task.rs @@ -0,0 +1,118 @@ +mod bloat; +mod build; +mod build_release; +mod ci; +mod loose_bench; +mod prepare; +mod scan; +mod size; + +use std::io::Write; +use std::path::{Path, PathBuf}; +use std::process::Command; +use termcolor::{ColorChoice, ColorSpec, StandardStream, WriteColor}; + +use crate::task::bloat::RunBloat; +use crate::task::build::RunBuild; +use crate::task::build_release::RunBuildRelease; +use crate::task::ci::RunCi; +use crate::task::loose_bench::RunLooseBench; +use crate::task::prepare::RunPrepare; +use crate::task::scan::RunScan; +use crate::task::size::RunSize; +use crate::{Task, TaskError, TaskResult}; + +const CARGO_MANIFEST_DIR: &str = env!("CARGO_MANIFEST_DIR"); +const CRATE: &str = "gfold"; +const ROOT_PREFIX: &str = "xtask"; + +pub struct TaskHarness { + root: PathBuf, + prefix: Vec<String>, +} + +pub trait TaskRunner { + fn run(harness: &mut TaskHarness) -> TaskResult<()>; +} + +enum WriteKind { + Stdout, + Stderr, +} + +impl TaskHarness { + pub fn new() -> TaskResult<Self> { + let root = match Path::new(CARGO_MANIFEST_DIR).ancestors().nth(2) { + Some(found_root) => found_root.to_path_buf(), + None => return Err(TaskError::CouldNotDetermineRepositoryRoot), + }; + Ok(Self { + root, + prefix: vec![ROOT_PREFIX.to_string()], + }) + } + + pub fn task(&mut self, task: Task) -> TaskResult<()> { + self.prefix.push(task.to_string()); + + match task { + Task::Bloat => RunBloat::run(self)?, + Task::Build => RunBuild::run(self)?, + Task::BuildRelease => RunBuildRelease::run(self)?, + Task::Ci => RunCi::run(self)?, + Task::Prepare => RunPrepare::run(self)?, + Task::Scan => RunScan::run(self)?, + Task::Size => RunSize::run(self)?, + Task::LooseBench => RunLooseBench::run(self)?, + } + + self.prefix.pop(); + Ok(()) + } + + pub fn stdout(&self, contents: impl AsRef<str>) -> TaskResult<()> { + self.write(contents, WriteKind::Stdout) + } + + pub fn stderr(&self, contents: impl AsRef<str>) -> TaskResult<()> { + self.write(contents, WriteKind::Stderr) + } + + fn write(&self, contents: impl AsRef<str>, kind: WriteKind) -> TaskResult<()> { + let mut buffer = match kind { + WriteKind::Stdout => StandardStream::stdout(ColorChoice::Auto), + WriteKind::Stderr => StandardStream::stderr(ColorChoice::Auto), + }; + + buffer.set_color(ColorSpec::new().set_bold(true))?; + write!(&mut buffer, "{} ", self.prefix.join(":"))?; + + buffer.reset()?; + writeln!(&mut buffer, "{}", contents.as_ref())?; + Ok(()) + } + + fn cargo( + &self, + args: &'static str, + env: Option<(&'static str, &'static str)>, + ) -> TaskResult<()> { + let mut cmd = Command::new("cargo"); + if let Some((key, value)) = env { + cmd.env(key, value); + self.stdout(format!("{key}={value} cargo {args}"))?; + } else { + self.stdout(format!("cargo {args}"))?; + } + match cmd + .current_dir(&self.root) + .env("CARGO_TERM_COLOR", "always") + .args(args.trim().split(' ')) + .status()? + .success() + { + true => Ok(()), + false => Err(TaskError::CargoCommandFailed), + } + } +} diff --git a/crates/xtask/src/task/bloat.rs b/crates/xtask/src/task/bloat.rs new file mode 100644 index 0000000..7880036 --- /dev/null +++ b/crates/xtask/src/task/bloat.rs @@ -0,0 +1,13 @@ +use crate::TaskHarness; +use crate::TaskResult; +use crate::TaskRunner; + +pub struct RunBloat; + +impl TaskRunner for RunBloat { + fn run(harness: &mut TaskHarness) -> TaskResult<()> { + harness.cargo("bloat --release", None)?; + harness.cargo("bloat --release --crates", None)?; + Ok(()) + } +} diff --git a/crates/xtask/src/task/build.rs b/crates/xtask/src/task/build.rs new file mode 100644 index 0000000..e1ea8a2 --- /dev/null +++ b/crates/xtask/src/task/build.rs @@ -0,0 +1,12 @@ +use crate::task::TaskRunner; +use crate::TaskHarness; +use crate::TaskResult; + +pub struct RunBuild; + +impl TaskRunner for RunBuild { + fn run(harness: &mut TaskHarness) -> TaskResult<()> { + harness.cargo("build --all-targets", None)?; + Ok(()) + } +} diff --git a/crates/xtask/src/task/build_release.rs b/crates/xtask/src/task/build_release.rs new file mode 100644 index 0000000..64b5e63 --- /dev/null +++ b/crates/xtask/src/task/build_release.rs @@ -0,0 +1,12 @@ +use crate::TaskHarness; +use crate::TaskResult; +use crate::TaskRunner; + +pub struct RunBuildRelease; + +impl TaskRunner for RunBuildRelease { + fn run(harness: &mut TaskHarness) -> TaskResult<()> { + harness.cargo("build --release", None)?; + Ok(()) + } +} diff --git a/crates/xtask/src/task/ci.rs b/crates/xtask/src/task/ci.rs new file mode 100644 index 0000000..979f499 --- /dev/null +++ b/crates/xtask/src/task/ci.rs @@ -0,0 +1,19 @@ +use crate::TaskResult; +use crate::{TaskHarness, TaskRunner}; + +pub struct RunCi; + +impl TaskRunner for RunCi { + fn run(harness: &mut TaskHarness) -> TaskResult<()> { + harness.cargo("fmt --all -- --check", None)?; + harness.cargo("check --all-targets --all-features --workspace", None)?; + harness.cargo( + "clippy --all-targets --all-features --no-deps --workspace -- -D warnings", + None, + )?; + harness.cargo("doc --all --no-deps", Some(("RUSTDOCFLAGS", "-Dwarnings")))?; + harness.cargo("test --all-targets", None)?; + harness.cargo("build --locked --all-targets", None)?; + Ok(()) + } +} diff --git a/crates/xtask/src/task/loose_bench.rs b/crates/xtask/src/task/loose_bench.rs new file mode 100644 index 0000000..91c0ee7 --- /dev/null +++ b/crates/xtask/src/task/loose_bench.rs @@ -0,0 +1,142 @@ +//! This is the loose bench for gfold. Why use a loose bench over a precise one? Most of gfold +//! development happens with a mobile processor, which is prone to performance fluctuations over +//! background I/O operations, battery life and temperature. Moreover, the "real world" use case of +//! gfold is via CLI and not a library. Thus, this loose bench executes gfold as a CLI similarly +//! to real world use. This benchmark is neither precise nor "scientific" and is purely designed to +//! give a high level performance overview. + +// TODO(nick): add consistency deviation. We should see how far each result strays from the average. +// We want gfold to perform consistently as well as quickly. + +use std::cmp::Ordering; +use std::path::Path; +use std::process::Command; +use std::time::{Duration, Instant}; + +use crate::{Task, TaskError, TaskResult}; +use crate::{TaskHarness, TaskRunner}; + +pub struct RunLooseBench; + +const RUNS: usize = 100; + +impl TaskRunner for RunLooseBench { + fn run(harness: &mut TaskHarness) -> TaskResult<()> { + let global_instant = Instant::now(); + + harness.task(Task::BuildRelease)?; + + let release = harness.root.join("target").join("release").join("gfold"); + let home = dirs::home_dir().ok_or(TaskError::HomeDirectoryNotFound)?; + let installed = home.join(".cargo").join("bin").join("gfold"); + let target = harness + .root + .parent() + .ok_or(TaskError::RepositoryDoesNotHaveParentDirectory)?; + + // Loosely bench with the parent directory of the repository as the target. + let mut release_durations = Vec::new(); + let mut installed_durations = Vec::new(); + let mut first = true; + + // Add "1" to total runs to ensure caching does not skew results. We need one + // "warm up" run. + let runs_with_warm_up = RUNS + 1; + for run in 0..runs_with_warm_up { + println!("run {run} of {RUNS}"); + + // Alternate at the halfway point. Though, it is doubtful that this would actually + // change anything. Only calculate the average after the first run to avoid caching + // skewing results. + if run > RUNS / 2 { + let (old_duration, new_duration) = + harness.loose_bench(&installed, &release, target)?; + if first { + first = false; + } else { + release_durations.push(new_duration); + installed_durations.push(old_duration); + } + } else { + let (new_duration, old_duration) = + harness.loose_bench(&release, &installed, target)?; + if first { + first = false; + } else { + release_durations.push(new_duration); + installed_durations.push(old_duration); + } + } + } + + let release_average = harness.average_duration(&release_durations); + let installed_average = harness.average_duration(&installed_durations); + let (difference, label) = match release_average.cmp(&installed_average) { + Ordering::Greater => ( + release_average - installed_average, + "installed was faster than release", + ), + Ordering::Less => ( + installed_average - release_average, + "release was faster than installed", + ), + Ordering::Equal => (Duration::from_millis(0), "tied"), + }; + + println!( + " +target: {} + + release {release_average:.2?} {} + installed {installed_average:.2?} {} + difference {difference:.2?} ({label}) + +loose bench duration: {:.2?}", + target.display(), + &release.display(), + &installed.display(), + global_instant.elapsed() + ); + Ok(()) + } +} + +impl TaskHarness { + fn loose_bench( + &self, + first: &Path, + second: &Path, + target: &Path, + ) -> TaskResult<(Duration, Duration)> { + let first_duration = self.execute_gfold(first, target)?; + let second_duration = self.execute_gfold(second, target)?; + + let (first_text, second_text) = match first_duration.cmp(&second_duration) { + Ordering::Greater => ("slower", "faster"), + Ordering::Less => ("faster", "slower"), + Ordering::Equal => ("tied ", "tied "), + }; + + println!(" {first_text} {first_duration:.2?} {}", first.display(),); + println!( + " {second_text} {second_duration:.2?} {}", + second.display(), + ); + Ok((first_duration, second_duration)) + } + + fn execute_gfold(&self, binary: &Path, target: &Path) -> TaskResult<Duration> { + let start = Instant::now(); + let output = Command::new(binary).arg("-i").arg(target).output()?; + match output.status.success() { + true => Ok(start.elapsed()), + false => Err(TaskError::UnsuccessfulCommandDuringLooseBench(output)), + } + } + + fn average_duration(&self, durations: &[Duration]) -> Duration { + let sum = durations.iter().sum::<Duration>(); + let count = durations.len() as f32; + sum.div_f32(count) + } +} diff --git a/crates/xtask/src/task/prepare.rs b/crates/xtask/src/task/prepare.rs new file mode 100644 index 0000000..eef2506 --- /dev/null +++ b/crates/xtask/src/task/prepare.rs @@ -0,0 +1,15 @@ +use crate::TaskResult; +use crate::{TaskHarness, TaskRunner}; + +pub struct RunPrepare; + +impl TaskRunner for RunPrepare { + fn run(harness: &mut TaskHarness) -> TaskResult<()> { + harness.cargo("update", None)?; + harness.cargo("fmt", None)?; + harness.cargo("check --all-targets --all-features --workspace", None)?; + harness.cargo("fix --edition-idioms --allow-dirty --allow-staged", None)?; + harness.cargo("clippy --all-features --all-targets --workspace --no-deps --fix --allow-dirty --allow-staged", None)?; + Ok(()) + } +} diff --git a/crates/xtask/src/task/scan.rs b/crates/xtask/src/task/scan.rs new file mode 100644 index 0000000..207bcc2 --- /dev/null +++ b/crates/xtask/src/task/scan.rs @@ -0,0 +1,13 @@ +use crate::{Task, TaskResult}; +use crate::{TaskHarness, TaskRunner}; + +pub struct RunScan; + +impl TaskRunner for RunScan { + fn run(harness: &mut TaskHarness) -> TaskResult<()> { + harness.task(Task::Prepare)?; + harness.cargo("+nightly udeps", None)?; + harness.cargo("audit", None)?; + Ok(()) + } +} diff --git a/crates/xtask/src/task/size.rs b/crates/xtask/src/task/size.rs new file mode 100644 index 0000000..b8ee730 --- /dev/null +++ b/crates/xtask/src/task/size.rs @@ -0,0 +1,49 @@ +use std::path::PathBuf; +use std::{fs, io}; + +use crate::task::CRATE; +use crate::TaskResult; +use crate::{Task, TaskError}; +use crate::{TaskHarness, TaskRunner}; + +pub struct RunSize; + +impl TaskRunner for RunSize { + fn run(harness: &mut TaskHarness) -> TaskResult<()> { + harness.task(Task::BuildRelease)?; + + let binary = harness.root.join("target").join("release").join(CRATE); + harness.print_binary_size(&binary, false)?; + + // Check if the binary is currently installed to compare release build sizes. If it is not, + // we can skip this check. + let home = dirs::home_dir().ok_or(TaskError::HomeDirectoryNotFound)?; + let installed = home.join(".cargo").join("bin").join(CRATE); + harness.print_binary_size(&installed, true)?; + Ok(()) + } +} + +impl TaskHarness { + fn print_binary_size(&self, binary: &PathBuf, skip_if_not_found: bool) -> TaskResult<()> { + let size = match fs::metadata(binary) { + Ok(metadata) => metadata.len() as f64 / 1048576.0, + Err(e) if e.kind() == io::ErrorKind::NotFound => match skip_if_not_found { + true => { + self.stdout(format!("skipping, binary not found: {}", binary.display()))?; + return Ok(()); + } + false => { + self.stderr(format!("error binary not found: {}", binary.display()))?; + return Err(e.into()); + } + }, + Err(e) => return Err(e.into()), + }; + + // Divisor used to perform human readable size conversion. + // 1048576.0 = 1024.0 * 1024.0 + self.stdout(format!("{:.3} MB - {}", size, binary.display()))?; + Ok(()) + } +} diff --git a/docs/DEVELOPING.md b/docs/DEVELOPING.md index f13e2dd..fa369bd 100644 --- a/docs/DEVELOPING.md +++ b/docs/DEVELOPING.md @@ -2,50 +2,9 @@ This document contains information related to development. -## Preparing Changes +## `cargo xtask` -First, update dependencies and tidy your changes. +This repository uses the [`cargo-xtask`](https://github.com/matklad/cargo-xtask) pattern for local development +and automation. -```shell -cargo fmt -cargo update -cargo fix --edition-idioms --allow-dirty --allow-staged -cargo clippy --all-features --all-targets --no-deps -``` - -Now, ensure that lints, tests, and builds succeed. - -```shell -cargo fmt --all -- --check -cargo build --all-targets -cargo clippy -- -D warnings -RUSTDOCFLAGS="-Dwarnings" cargo doc --all --no-deps -cargo test -- --nocapture -``` - -If you'd like to mass "fix" everything, you should commit/save existing work and execute the following: - -```shell -cargo fix --all-targets --all-features --allow-dirty --allow-staged -cargo clippy --fix --all-features --all-targets --allow-dirty --allow-staged -``` - -## Running Performance Tests - -See available packages with the following command: - -```shell -cargo run -p -``` - -## Optional Checks - -The following checks are optional and should be run occasionally. - -```shell -# This command requires a nightly toolchain to be installed. -cargo +nightly udeps -cargo bloat --release -cargo bloat --release --crates -cargo audit -```
\ No newline at end of file +To see what commands are available, execute `cargo xtask` from the root of the repository.
\ No newline at end of file diff --git a/docs/RELEASE.md b/docs/RELEASE.md index 4b87ee0..8b36897 100644 --- a/docs/RELEASE.md +++ b/docs/RELEASE.md @@ -13,11 +13,7 @@ Steps should be executed in sequential order. - [ ] Verify that everything looks/works as expected: ```shell -cargo fmt --all -- --check -cargo clippy -- -D warnings -cargo test -RUSTDOCFLAGS="-Dwarnings" cargo doc --all --no-deps -cargo build --all-targets +cargo xtask ci ``` - [ ] Create and _do not merge_ a commit with the following message: `Update to <tag>` |