From 91d48b29231edd6c26d516cff265127d6702b0ba Mon Sep 17 00:00:00 2001 From: Erich Gubler Date: Mon, 20 Mar 2023 10:42:39 -0400 Subject: [PATCH] build: move from `make` to `cargo xtask` workflows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Re-implement `naga` development workflows using [`cargo xtask`]. Convert `make` logic and shader test configuration as file with Bash variables into an `xtask` crate and YAML files, respectively. Pros: * We now have a _portable_ workflow everywhere, which means Windows folks and people who don't install `make` don't have to suffer. 😮‍💨 * Workflow logic is now relatively easy to inspect and change. Whew! 💁🏻‍♂️💦 * Contributors can use their existing Rust knowledge to contribute to developer experience. 🎉 * `cargo xtask` is a relatively well-known convention for workflows in the ecosystem. * We can do fancy things like allow folks to run at different log levels for workflows, depending on their tastes. Cons: * There's now a non-trivial compile step to project workflow. Incremental rebuilds seem to be pretty short, though! * Code is much more verbose than the (very) terse `make` implementation. [`cargo xtask`]: https://github.com/matklad/cargo-xtask --- .cargo/config.toml | 2 + .github/workflows/validation-linux.yml | 14 +- .github/workflows/validation-macos.yml | 8 +- .github/workflows/validation-windows.yml | 17 +- Cargo.toml | 1 + Makefile | 131 -------- tests/out/hlsl/access.hlsl.config | 3 - tests/out/hlsl/access.ron | 20 ++ tests/out/hlsl/array-in-ctor.hlsl.config | 3 - tests/out/hlsl/array-in-ctor.ron | 12 + tests/out/hlsl/atomicOps.hlsl.config | 3 - tests/out/hlsl/atomicOps.ron | 12 + tests/out/hlsl/binding-arrays.hlsl.config | 3 - tests/out/hlsl/binding-arrays.ron | 12 + tests/out/hlsl/bitcast.hlsl.config | 3 - tests/out/hlsl/bitcast.ron | 12 + tests/out/hlsl/boids.hlsl.config | 3 - tests/out/hlsl/boids.ron | 12 + tests/out/hlsl/break-if.hlsl.config | 3 - tests/out/hlsl/break-if.ron | 12 + tests/out/hlsl/collatz.hlsl.config | 3 - tests/out/hlsl/collatz.ron | 12 + tests/out/hlsl/control-flow.hlsl.config | 3 - tests/out/hlsl/control-flow.ron | 12 + tests/out/hlsl/do-while.hlsl.config | 3 - tests/out/hlsl/do-while.ron | 12 + tests/out/hlsl/empty-global-name.hlsl.config | 3 - tests/out/hlsl/empty-global-name.ron | 12 + tests/out/hlsl/empty.hlsl.config | 3 - tests/out/hlsl/empty.ron | 12 + tests/out/hlsl/fragment-output.hlsl.config | 3 - tests/out/hlsl/fragment-output.ron | 16 + tests/out/hlsl/functions.hlsl.config | 3 - tests/out/hlsl/functions.ron | 12 + tests/out/hlsl/globals.hlsl.config | 3 - tests/out/hlsl/globals.ron | 12 + tests/out/hlsl/hlsl-keyword.hlsl.config | 3 - tests/out/hlsl/hlsl-keyword.ron | 12 + tests/out/hlsl/image.hlsl.config | 3 - tests/out/hlsl/image.ron | 40 +++ tests/out/hlsl/interface.hlsl.config | 3 - tests/out/hlsl/interface.ron | 24 ++ tests/out/hlsl/interpolate.hlsl.config | 3 - tests/out/hlsl/interpolate.ron | 16 + .../inv-hyperbolic-trig-functions.hlsl.config | 3 - .../hlsl/inv-hyperbolic-trig-functions.ron | 12 + tests/out/hlsl/math-functions.hlsl.config | 3 - tests/out/hlsl/math-functions.ron | 12 + tests/out/hlsl/operators.hlsl.config | 3 - tests/out/hlsl/operators.ron | 12 + tests/out/hlsl/padding.hlsl.config | 3 - tests/out/hlsl/padding.ron | 12 + tests/out/hlsl/push-constants.hlsl.config | 3 - tests/out/hlsl/push-constants.ron | 16 + tests/out/hlsl/quad-vert.hlsl.config | 3 - tests/out/hlsl/quad-vert.ron | 12 + tests/out/hlsl/quad.hlsl.config | 3 - tests/out/hlsl/quad.ron | 20 ++ tests/out/hlsl/shadow.hlsl.config | 3 - tests/out/hlsl/shadow.ron | 20 ++ tests/out/hlsl/skybox.hlsl.config | 3 - tests/out/hlsl/skybox.ron | 16 + tests/out/hlsl/standard.hlsl.config | 3 - tests/out/hlsl/standard.ron | 12 + tests/out/hlsl/texture-arg.hlsl.config | 3 - tests/out/hlsl/texture-arg.ron | 12 + .../hlsl/workgroup-uniform-load.hlsl.config | 3 - tests/out/hlsl/workgroup-uniform-load.ron | 12 + tests/out/hlsl/workgroup-var-init.hlsl.config | 3 - tests/out/hlsl/workgroup-var-init.ron | 12 + tests/snapshots.rs | 56 +--- xtask/.gitignore | 2 + xtask/Cargo.lock | 117 +++++++ xtask/Cargo.toml | 19 ++ xtask/hlsl-snapshots/Cargo.toml | 8 + xtask/hlsl-snapshots/src/lib.rs | 97 ++++++ xtask/src/cli.rs | 160 +++++++++ xtask/src/fs.rs | 10 + xtask/src/glob.rs | 37 +++ xtask/src/main.rs | 305 ++++++++++++++++++ xtask/src/path.rs | 11 + xtask/src/process.rs | 78 +++++ xtask/src/result.rs | 33 ++ 83 files changed, 1389 insertions(+), 277 deletions(-) create mode 100644 .cargo/config.toml delete mode 100644 Makefile delete mode 100644 tests/out/hlsl/access.hlsl.config create mode 100644 tests/out/hlsl/access.ron delete mode 100644 tests/out/hlsl/array-in-ctor.hlsl.config create mode 100644 tests/out/hlsl/array-in-ctor.ron delete mode 100644 tests/out/hlsl/atomicOps.hlsl.config create mode 100644 tests/out/hlsl/atomicOps.ron delete mode 100644 tests/out/hlsl/binding-arrays.hlsl.config create mode 100644 tests/out/hlsl/binding-arrays.ron delete mode 100644 tests/out/hlsl/bitcast.hlsl.config create mode 100644 tests/out/hlsl/bitcast.ron delete mode 100644 tests/out/hlsl/boids.hlsl.config create mode 100644 tests/out/hlsl/boids.ron delete mode 100644 tests/out/hlsl/break-if.hlsl.config create mode 100644 tests/out/hlsl/break-if.ron delete mode 100644 tests/out/hlsl/collatz.hlsl.config create mode 100644 tests/out/hlsl/collatz.ron delete mode 100644 tests/out/hlsl/control-flow.hlsl.config create mode 100644 tests/out/hlsl/control-flow.ron delete mode 100644 tests/out/hlsl/do-while.hlsl.config create mode 100644 tests/out/hlsl/do-while.ron delete mode 100644 tests/out/hlsl/empty-global-name.hlsl.config create mode 100644 tests/out/hlsl/empty-global-name.ron delete mode 100644 tests/out/hlsl/empty.hlsl.config create mode 100644 tests/out/hlsl/empty.ron delete mode 100644 tests/out/hlsl/fragment-output.hlsl.config create mode 100644 tests/out/hlsl/fragment-output.ron delete mode 100644 tests/out/hlsl/functions.hlsl.config create mode 100644 tests/out/hlsl/functions.ron delete mode 100644 tests/out/hlsl/globals.hlsl.config create mode 100644 tests/out/hlsl/globals.ron delete mode 100644 tests/out/hlsl/hlsl-keyword.hlsl.config create mode 100644 tests/out/hlsl/hlsl-keyword.ron delete mode 100644 tests/out/hlsl/image.hlsl.config create mode 100644 tests/out/hlsl/image.ron delete mode 100644 tests/out/hlsl/interface.hlsl.config create mode 100644 tests/out/hlsl/interface.ron delete mode 100644 tests/out/hlsl/interpolate.hlsl.config create mode 100644 tests/out/hlsl/interpolate.ron delete mode 100644 tests/out/hlsl/inv-hyperbolic-trig-functions.hlsl.config create mode 100644 tests/out/hlsl/inv-hyperbolic-trig-functions.ron delete mode 100644 tests/out/hlsl/math-functions.hlsl.config create mode 100644 tests/out/hlsl/math-functions.ron delete mode 100644 tests/out/hlsl/operators.hlsl.config create mode 100644 tests/out/hlsl/operators.ron delete mode 100644 tests/out/hlsl/padding.hlsl.config create mode 100644 tests/out/hlsl/padding.ron delete mode 100644 tests/out/hlsl/push-constants.hlsl.config create mode 100644 tests/out/hlsl/push-constants.ron delete mode 100644 tests/out/hlsl/quad-vert.hlsl.config create mode 100644 tests/out/hlsl/quad-vert.ron delete mode 100644 tests/out/hlsl/quad.hlsl.config create mode 100644 tests/out/hlsl/quad.ron delete mode 100644 tests/out/hlsl/shadow.hlsl.config create mode 100644 tests/out/hlsl/shadow.ron delete mode 100644 tests/out/hlsl/skybox.hlsl.config create mode 100644 tests/out/hlsl/skybox.ron delete mode 100644 tests/out/hlsl/standard.hlsl.config create mode 100644 tests/out/hlsl/standard.ron delete mode 100644 tests/out/hlsl/texture-arg.hlsl.config create mode 100644 tests/out/hlsl/texture-arg.ron delete mode 100644 tests/out/hlsl/workgroup-uniform-load.hlsl.config create mode 100644 tests/out/hlsl/workgroup-uniform-load.ron delete mode 100644 tests/out/hlsl/workgroup-var-init.hlsl.config create mode 100644 tests/out/hlsl/workgroup-var-init.ron create mode 100644 xtask/.gitignore create mode 100644 xtask/Cargo.lock create mode 100644 xtask/Cargo.toml create mode 100644 xtask/hlsl-snapshots/Cargo.toml create mode 100644 xtask/hlsl-snapshots/src/lib.rs create mode 100644 xtask/src/cli.rs create mode 100644 xtask/src/fs.rs create mode 100644 xtask/src/glob.rs create mode 100644 xtask/src/main.rs create mode 100644 xtask/src/path.rs create mode 100644 xtask/src/process.rs create mode 100644 xtask/src/result.rs diff --git a/.cargo/config.toml b/.cargo/config.toml new file mode 100644 index 0000000000..4b01400617 --- /dev/null +++ b/.cargo/config.toml @@ -0,0 +1,2 @@ +[alias] +xtask = "run --manifest-path xtask/Cargo.toml --" diff --git a/.github/workflows/validation-linux.yml b/.github/workflows/validation-linux.yml index e253e0a42e..0c1525e7db 100644 --- a/.github/workflows/validation-linux.yml +++ b/.github/workflows/validation-linux.yml @@ -8,6 +8,7 @@ on: - 'tests/out/dot/*.dot' - 'tests/out/wgsl/*.wgsl' - 'src/front/wgsl/*' + - 'xtask/**' jobs: validate-linux: @@ -19,10 +20,15 @@ jobs: - name: Install tools run: sudo apt-get install spirv-tools glslang-tools graphviz - - run: make validate-spv + - uses: Swatinem/rust-cache@v2 + with: + workspaces: | + xtask -> target - - run: make validate-glsl + - run: cargo xtask validate spv - - run: make validate-dot + - run: cargo xtask validate glsl - - run: make validate-wgsl + - run: cargo xtask validate dot + + - run: cargo xtask validate wgsl diff --git a/.github/workflows/validation-macos.yml b/.github/workflows/validation-macos.yml index 535a0622b3..c06563dc12 100644 --- a/.github/workflows/validation-macos.yml +++ b/.github/workflows/validation-macos.yml @@ -4,6 +4,7 @@ on: paths: - '.github/workflows/validation-macos.yml' - 'tests/out/msl/*.msl' + - 'xtask/**' jobs: validate-macos: @@ -12,4 +13,9 @@ jobs: steps: - uses: actions/checkout@v3 - - run: make validate-msl + - uses: Swatinem/rust-cache@v2 + with: + workspaces: | + xtask -> target + + - run: cargo xtask validate msl diff --git a/.github/workflows/validation-windows.yml b/.github/workflows/validation-windows.yml index 03942a6782..9278f89dfe 100644 --- a/.github/workflows/validation-windows.yml +++ b/.github/workflows/validation-windows.yml @@ -4,6 +4,7 @@ on: paths: - '.github/workflows/validation-windows.yml' - 'tests/out/hlsl/*.hlsl' + - 'xtask/**' jobs: validate-windows-dxc: @@ -15,8 +16,12 @@ jobs: - name: Add DirectXShaderCompiler uses: napokue/setup-dxc@v1.1.0 - - run: make validate-hlsl-dxc - shell: sh + - uses: Swatinem/rust-cache@v2 + with: + workspaces: | + xtask -> target + + - run: cargo xtask validate hlsl dxc validate-windows-fxc: name: HLSL via FXC @@ -33,5 +38,9 @@ jobs: | Out-File -FilePath $Env:GITHUB_PATH -Encoding utf8 -Append shell: powershell - - run: make validate-hlsl-fxc - shell: sh + - uses: Swatinem/rust-cache@v2 + with: + workspaces: | + xtask -> target + + - run: cargo xtask validate hlsl fxc diff --git a/Cargo.toml b/Cargo.toml index 7417995dc1..e01d506882 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -68,6 +68,7 @@ unicode-xid = { version = "0.2.3", optional = true } bincode = "1" criterion = { version = "0.3", features = [] } diff = "0.1" +hlsl-snapshots = { path = "./xtask/hlsl-snapshots"} # Require at least version 0.7.1 of ron, this version changed how floating points are # serialized by forcing them to always have the decimal part, this makes it backwards # incompatible with our tests because we do a syntatic diff and not a semantic one. diff --git a/Makefile b/Makefile deleted file mode 100644 index 606e616bd6..0000000000 --- a/Makefile +++ /dev/null @@ -1,131 +0,0 @@ -.PHONY: all clean validate-spv validate-msl validate-glsl validate-dot validate-wgsl validate-hlsl-dxc validate-hlsl-fxc -.SECONDARY: boids.metal quad.metal -SNAPSHOTS_BASE_IN=tests/in -SNAPSHOTS_BASE_OUT=tests/out - -all: - cargo fmt - cargo test --all-features --workspace - cargo clippy --all-features --workspace -- -D warnings - -clean: - rm *.metal *.air *.metallib *.vert *.frag *.comp *.spv - -bench: - #rm -Rf target/criterion - cargo bench - -%.metal: $(SNAPSHOTS_BASE_IN)/%.wgsl $(wildcard src/*.rs src/**/*.rs examples/*.rs) - cargo run --features wgsl-in,msl-out -- $< $@ - -%.air: %.metal - xcrun -sdk macosx metal -c $< -mmacosx-version-min=10.11 - -%.metallib: %.air - xcrun -sdk macosx metallib $< -o $@ - -%.dot: $(SNAPSHOTS_BASE_IN)/%.wgsl $(wildcard src/*.rs src/front/wgsl/*.rs src/back/dot/*.rs bin/naga.rs) - cargo run --features wgsl-in,dot-out -- $< $@ - -%.png: %.dot - dot -Tpng $< -o $@ - -validate-spv: $(SNAPSHOTS_BASE_OUT)/spv/*.spvasm - @set -e && for file in $^ ; do \ - echo "Validating" $${file#"$(SNAPSHOTS_BASE_OUT)/"}; \ - version_line=$$(head -2 $${file} | tail -1); \ - version=$${version_line#"; Version: "};\ - cat $${file} | spirv-as --target-env spv$${version} - -o - | spirv-val -; \ - done - -validate-msl: $(SNAPSHOTS_BASE_OUT)/msl/*.msl - @set -e && for file in $^ ; do \ - echo "Validating" $${file#"$(SNAPSHOTS_BASE_OUT)/"}; \ - header=$$(head -n1 $${file}); \ - cat $${file} | xcrun -sdk macosx metal -mmacosx-version-min=10.11 -std=macos-$${header:13:8} -x metal - -o /dev/null; \ - done - -validate-glsl: $(SNAPSHOTS_BASE_OUT)/glsl/*.glsl - @set -e && for file in $(SNAPSHOTS_BASE_OUT)/glsl/*.Vertex.glsl ; do \ - echo "Validating" $${file#"$(SNAPSHOTS_BASE_OUT)/"};\ - cat $${file} | glslangValidator --stdin -S vert; \ - done - @set -e && for file in $(SNAPSHOTS_BASE_OUT)/glsl/*.Fragment.glsl ; do \ - echo "Validating" $${file#"$(SNAPSHOTS_BASE_OUT)/"};\ - cat $${file} | glslangValidator --stdin -S frag; \ - done - @set -e && for file in $(SNAPSHOTS_BASE_OUT)/glsl/*.Compute.glsl ; do \ - echo "Validating" $${file#"$(SNAPSHOTS_BASE_OUT)/"};\ - cat $${file} | glslangValidator --stdin -S comp; \ - done - -validate-dot: $(SNAPSHOTS_BASE_OUT)/dot/*.dot - @set -e && for file in $^ ; do \ - echo "Validating" $${file#"$(SNAPSHOTS_BASE_OUT)/"}; \ - cat $${file} | dot -o /dev/null; \ - done - -validate-wgsl: $(SNAPSHOTS_BASE_OUT)/wgsl/*.wgsl - @set -e && for file in $^ ; do \ - echo "Validating" $${file#"$(SNAPSHOTS_BASE_OUT)/"}; \ - cargo run $${file}; \ - done - -validate-hlsl-dxc: SHELL:=/usr/bin/env bash # required because config files uses arrays -validate-hlsl-dxc: $(SNAPSHOTS_BASE_OUT)/hlsl/*.hlsl - @set -e && for file in $^ ; do \ - DXC_PARAMS="-Wno-parentheses-equality -Zi -Qembed_debug -Od"; \ - echo "Validating" $${file#"$(SNAPSHOTS_BASE_OUT)/"}; \ - config="$$(dirname $${file})/$$(basename $${file}).config"; \ - . $${config}; \ - for (( i=0; i<$${#vertex[@]}; i++ )); do \ - name=`echo $${vertex[i]} | cut -d \: -f 1`; \ - profile=`echo $${vertex[i]} | cut -d \: -f 2`; \ - (set -x; dxc $${file} -T $${profile} -E $${name} $${DXC_PARAMS} > /dev/null); \ - done; \ - for (( i=0; i<$${#fragment[@]}; i++ )); do \ - name=`echo $${fragment[i]} | cut -d \: -f 1`; \ - profile=`echo $${fragment[i]} | cut -d \: -f 2`; \ - (set -x; dxc $${file} -T $${profile} -E $${name} $${DXC_PARAMS} > /dev/null); \ - done; \ - for (( i=0; i<$${#compute[@]}; i++ )); do \ - name=`echo $${compute[i]} | cut -d \: -f 1`; \ - profile=`echo $${compute[i]} | cut -d \: -f 2`; \ - (set -x; dxc $${file} -T $${profile} -E $${name} $${DXC_PARAMS} > /dev/null); \ - done; \ - echo "======================"; \ - done - -validate-hlsl-fxc: SHELL:=/usr/bin/env bash # required because config files uses arrays -validate-hlsl-fxc: $(SNAPSHOTS_BASE_OUT)/hlsl/*.hlsl - @set -e && for file in $^ ; do \ - FXC_PARAMS="-Zi -Od"; \ - echo "Validating" $${file#"$(SNAPSHOTS_BASE_OUT)/"}; \ - config="$$(dirname $${file})/$$(basename $${file}).config"; \ - . $${config}; \ - for (( i=0; i<$${#vertex[@]}; i++ )); do \ - name=`echo $${vertex[i]} | cut -d \: -f 1`; \ - profile=`echo $${vertex[i]} | cut -d \: -f 2`; \ - sm=`echo $${profile} | cut -d \_ -f 2`; \ - if (( sm < 6 )); then \ - (set -x; fxc $${file} -T $${profile} -E $${name} $${FXC_PARAMS} > /dev/null); \ - fi \ - done; \ - for (( i=0; i<$${#fragment[@]}; i++ )); do \ - name=`echo $${fragment[i]} | cut -d \: -f 1`; \ - profile=`echo $${fragment[i]} | cut -d \: -f 2`; \ - sm=`echo $${profile} | cut -d \_ -f 2`; \ - if (( sm < 6 )); then \ - (set -x; fxc $${file} -T $${profile} -E $${name} $${FXC_PARAMS} > /dev/null); \ - fi \ - done; \ - for (( i=0; i<$${#compute[@]}; i++ )); do \ - name=`echo $${compute[i]} | cut -d \: -f 1`; \ - profile=`echo $${compute[i]} | cut -d \: -f 2`; \ - sm=`echo $${profile} | cut -d \_ -f 2`; \ - if (( sm < 6 )); then \ - (set -x; fxc $${file} -T $${profile} -E $${name} $${FXC_PARAMS} > /dev/null); \ - fi \ - done; \ - echo "======================"; \ - done diff --git a/tests/out/hlsl/access.hlsl.config b/tests/out/hlsl/access.hlsl.config deleted file mode 100644 index de7719bdff..0000000000 --- a/tests/out/hlsl/access.hlsl.config +++ /dev/null @@ -1,3 +0,0 @@ -vertex=(foo_vert:vs_5_1 ) -fragment=(foo_frag:ps_5_1 ) -compute=(assign_through_ptr:cs_5_1 ) diff --git a/tests/out/hlsl/access.ron b/tests/out/hlsl/access.ron new file mode 100644 index 0000000000..73c9e44448 --- /dev/null +++ b/tests/out/hlsl/access.ron @@ -0,0 +1,20 @@ +( + vertex:[ + ( + entry_point:"foo_vert", + target_profile:"vs_5_1", + ), + ], + fragment:[ + ( + entry_point:"foo_frag", + target_profile:"ps_5_1", + ), + ], + compute:[ + ( + entry_point:"assign_through_ptr", + target_profile:"cs_5_1", + ), + ], +) diff --git a/tests/out/hlsl/array-in-ctor.hlsl.config b/tests/out/hlsl/array-in-ctor.hlsl.config deleted file mode 100644 index 522d99ed1a..0000000000 --- a/tests/out/hlsl/array-in-ctor.hlsl.config +++ /dev/null @@ -1,3 +0,0 @@ -vertex=() -fragment=() -compute=(cs_main:cs_5_1 ) diff --git a/tests/out/hlsl/array-in-ctor.ron b/tests/out/hlsl/array-in-ctor.ron new file mode 100644 index 0000000000..5c261e59b2 --- /dev/null +++ b/tests/out/hlsl/array-in-ctor.ron @@ -0,0 +1,12 @@ +( + vertex:[ + ], + fragment:[ + ], + compute:[ + ( + entry_point:"cs_main", + target_profile:"cs_5_1", + ), + ], +) diff --git a/tests/out/hlsl/atomicOps.hlsl.config b/tests/out/hlsl/atomicOps.hlsl.config deleted file mode 100644 index 522d99ed1a..0000000000 --- a/tests/out/hlsl/atomicOps.hlsl.config +++ /dev/null @@ -1,3 +0,0 @@ -vertex=() -fragment=() -compute=(cs_main:cs_5_1 ) diff --git a/tests/out/hlsl/atomicOps.ron b/tests/out/hlsl/atomicOps.ron new file mode 100644 index 0000000000..5c261e59b2 --- /dev/null +++ b/tests/out/hlsl/atomicOps.ron @@ -0,0 +1,12 @@ +( + vertex:[ + ], + fragment:[ + ], + compute:[ + ( + entry_point:"cs_main", + target_profile:"cs_5_1", + ), + ], +) diff --git a/tests/out/hlsl/binding-arrays.hlsl.config b/tests/out/hlsl/binding-arrays.hlsl.config deleted file mode 100644 index 98453a04ee..0000000000 --- a/tests/out/hlsl/binding-arrays.hlsl.config +++ /dev/null @@ -1,3 +0,0 @@ -vertex=() -fragment=(main:ps_5_1 ) -compute=() diff --git a/tests/out/hlsl/binding-arrays.ron b/tests/out/hlsl/binding-arrays.ron new file mode 100644 index 0000000000..341a4c528e --- /dev/null +++ b/tests/out/hlsl/binding-arrays.ron @@ -0,0 +1,12 @@ +( + vertex:[ + ], + fragment:[ + ( + entry_point:"main", + target_profile:"ps_5_1", + ), + ], + compute:[ + ], +) diff --git a/tests/out/hlsl/bitcast.hlsl.config b/tests/out/hlsl/bitcast.hlsl.config deleted file mode 100644 index 246c485cf7..0000000000 --- a/tests/out/hlsl/bitcast.hlsl.config +++ /dev/null @@ -1,3 +0,0 @@ -vertex=() -fragment=() -compute=(main:cs_5_1 ) diff --git a/tests/out/hlsl/bitcast.ron b/tests/out/hlsl/bitcast.ron new file mode 100644 index 0000000000..a07b03300b --- /dev/null +++ b/tests/out/hlsl/bitcast.ron @@ -0,0 +1,12 @@ +( + vertex:[ + ], + fragment:[ + ], + compute:[ + ( + entry_point:"main", + target_profile:"cs_5_1", + ), + ], +) diff --git a/tests/out/hlsl/boids.hlsl.config b/tests/out/hlsl/boids.hlsl.config deleted file mode 100644 index 246c485cf7..0000000000 --- a/tests/out/hlsl/boids.hlsl.config +++ /dev/null @@ -1,3 +0,0 @@ -vertex=() -fragment=() -compute=(main:cs_5_1 ) diff --git a/tests/out/hlsl/boids.ron b/tests/out/hlsl/boids.ron new file mode 100644 index 0000000000..a07b03300b --- /dev/null +++ b/tests/out/hlsl/boids.ron @@ -0,0 +1,12 @@ +( + vertex:[ + ], + fragment:[ + ], + compute:[ + ( + entry_point:"main", + target_profile:"cs_5_1", + ), + ], +) diff --git a/tests/out/hlsl/break-if.hlsl.config b/tests/out/hlsl/break-if.hlsl.config deleted file mode 100644 index 246c485cf7..0000000000 --- a/tests/out/hlsl/break-if.hlsl.config +++ /dev/null @@ -1,3 +0,0 @@ -vertex=() -fragment=() -compute=(main:cs_5_1 ) diff --git a/tests/out/hlsl/break-if.ron b/tests/out/hlsl/break-if.ron new file mode 100644 index 0000000000..a07b03300b --- /dev/null +++ b/tests/out/hlsl/break-if.ron @@ -0,0 +1,12 @@ +( + vertex:[ + ], + fragment:[ + ], + compute:[ + ( + entry_point:"main", + target_profile:"cs_5_1", + ), + ], +) diff --git a/tests/out/hlsl/collatz.hlsl.config b/tests/out/hlsl/collatz.hlsl.config deleted file mode 100644 index 246c485cf7..0000000000 --- a/tests/out/hlsl/collatz.hlsl.config +++ /dev/null @@ -1,3 +0,0 @@ -vertex=() -fragment=() -compute=(main:cs_5_1 ) diff --git a/tests/out/hlsl/collatz.ron b/tests/out/hlsl/collatz.ron new file mode 100644 index 0000000000..a07b03300b --- /dev/null +++ b/tests/out/hlsl/collatz.ron @@ -0,0 +1,12 @@ +( + vertex:[ + ], + fragment:[ + ], + compute:[ + ( + entry_point:"main", + target_profile:"cs_5_1", + ), + ], +) diff --git a/tests/out/hlsl/control-flow.hlsl.config b/tests/out/hlsl/control-flow.hlsl.config deleted file mode 100644 index 246c485cf7..0000000000 --- a/tests/out/hlsl/control-flow.hlsl.config +++ /dev/null @@ -1,3 +0,0 @@ -vertex=() -fragment=() -compute=(main:cs_5_1 ) diff --git a/tests/out/hlsl/control-flow.ron b/tests/out/hlsl/control-flow.ron new file mode 100644 index 0000000000..a07b03300b --- /dev/null +++ b/tests/out/hlsl/control-flow.ron @@ -0,0 +1,12 @@ +( + vertex:[ + ], + fragment:[ + ], + compute:[ + ( + entry_point:"main", + target_profile:"cs_5_1", + ), + ], +) diff --git a/tests/out/hlsl/do-while.hlsl.config b/tests/out/hlsl/do-while.hlsl.config deleted file mode 100644 index 98453a04ee..0000000000 --- a/tests/out/hlsl/do-while.hlsl.config +++ /dev/null @@ -1,3 +0,0 @@ -vertex=() -fragment=(main:ps_5_1 ) -compute=() diff --git a/tests/out/hlsl/do-while.ron b/tests/out/hlsl/do-while.ron new file mode 100644 index 0000000000..341a4c528e --- /dev/null +++ b/tests/out/hlsl/do-while.ron @@ -0,0 +1,12 @@ +( + vertex:[ + ], + fragment:[ + ( + entry_point:"main", + target_profile:"ps_5_1", + ), + ], + compute:[ + ], +) diff --git a/tests/out/hlsl/empty-global-name.hlsl.config b/tests/out/hlsl/empty-global-name.hlsl.config deleted file mode 100644 index 246c485cf7..0000000000 --- a/tests/out/hlsl/empty-global-name.hlsl.config +++ /dev/null @@ -1,3 +0,0 @@ -vertex=() -fragment=() -compute=(main:cs_5_1 ) diff --git a/tests/out/hlsl/empty-global-name.ron b/tests/out/hlsl/empty-global-name.ron new file mode 100644 index 0000000000..a07b03300b --- /dev/null +++ b/tests/out/hlsl/empty-global-name.ron @@ -0,0 +1,12 @@ +( + vertex:[ + ], + fragment:[ + ], + compute:[ + ( + entry_point:"main", + target_profile:"cs_5_1", + ), + ], +) diff --git a/tests/out/hlsl/empty.hlsl.config b/tests/out/hlsl/empty.hlsl.config deleted file mode 100644 index 246c485cf7..0000000000 --- a/tests/out/hlsl/empty.hlsl.config +++ /dev/null @@ -1,3 +0,0 @@ -vertex=() -fragment=() -compute=(main:cs_5_1 ) diff --git a/tests/out/hlsl/empty.ron b/tests/out/hlsl/empty.ron new file mode 100644 index 0000000000..a07b03300b --- /dev/null +++ b/tests/out/hlsl/empty.ron @@ -0,0 +1,12 @@ +( + vertex:[ + ], + fragment:[ + ], + compute:[ + ( + entry_point:"main", + target_profile:"cs_5_1", + ), + ], +) diff --git a/tests/out/hlsl/fragment-output.hlsl.config b/tests/out/hlsl/fragment-output.hlsl.config deleted file mode 100644 index 2bf0efbf76..0000000000 --- a/tests/out/hlsl/fragment-output.hlsl.config +++ /dev/null @@ -1,3 +0,0 @@ -vertex=() -fragment=(main_vec4vec3_:ps_5_1 main_vec2scalar:ps_5_1 ) -compute=() diff --git a/tests/out/hlsl/fragment-output.ron b/tests/out/hlsl/fragment-output.ron new file mode 100644 index 0000000000..9dfaf7393b --- /dev/null +++ b/tests/out/hlsl/fragment-output.ron @@ -0,0 +1,16 @@ +( + vertex:[ + ], + fragment:[ + ( + entry_point:"main_vec4vec3_", + target_profile:"ps_5_1", + ), + ( + entry_point:"main_vec2scalar", + target_profile:"ps_5_1", + ), + ], + compute:[ + ], +) diff --git a/tests/out/hlsl/functions.hlsl.config b/tests/out/hlsl/functions.hlsl.config deleted file mode 100644 index 246c485cf7..0000000000 --- a/tests/out/hlsl/functions.hlsl.config +++ /dev/null @@ -1,3 +0,0 @@ -vertex=() -fragment=() -compute=(main:cs_5_1 ) diff --git a/tests/out/hlsl/functions.ron b/tests/out/hlsl/functions.ron new file mode 100644 index 0000000000..a07b03300b --- /dev/null +++ b/tests/out/hlsl/functions.ron @@ -0,0 +1,12 @@ +( + vertex:[ + ], + fragment:[ + ], + compute:[ + ( + entry_point:"main", + target_profile:"cs_5_1", + ), + ], +) diff --git a/tests/out/hlsl/globals.hlsl.config b/tests/out/hlsl/globals.hlsl.config deleted file mode 100644 index 246c485cf7..0000000000 --- a/tests/out/hlsl/globals.hlsl.config +++ /dev/null @@ -1,3 +0,0 @@ -vertex=() -fragment=() -compute=(main:cs_5_1 ) diff --git a/tests/out/hlsl/globals.ron b/tests/out/hlsl/globals.ron new file mode 100644 index 0000000000..a07b03300b --- /dev/null +++ b/tests/out/hlsl/globals.ron @@ -0,0 +1,12 @@ +( + vertex:[ + ], + fragment:[ + ], + compute:[ + ( + entry_point:"main", + target_profile:"cs_5_1", + ), + ], +) diff --git a/tests/out/hlsl/hlsl-keyword.hlsl.config b/tests/out/hlsl/hlsl-keyword.hlsl.config deleted file mode 100644 index b9f047558a..0000000000 --- a/tests/out/hlsl/hlsl-keyword.hlsl.config +++ /dev/null @@ -1,3 +0,0 @@ -vertex=() -fragment=(fs_main:ps_5_1 ) -compute=() diff --git a/tests/out/hlsl/hlsl-keyword.ron b/tests/out/hlsl/hlsl-keyword.ron new file mode 100644 index 0000000000..eac1b945d2 --- /dev/null +++ b/tests/out/hlsl/hlsl-keyword.ron @@ -0,0 +1,12 @@ +( + vertex:[ + ], + fragment:[ + ( + entry_point:"fs_main", + target_profile:"ps_5_1", + ), + ], + compute:[ + ], +) diff --git a/tests/out/hlsl/image.hlsl.config b/tests/out/hlsl/image.hlsl.config deleted file mode 100644 index 8194e213f1..0000000000 --- a/tests/out/hlsl/image.hlsl.config +++ /dev/null @@ -1,3 +0,0 @@ -vertex=(queries:vs_5_1 levels_queries:vs_5_1 ) -fragment=(texture_sample:ps_5_1 texture_sample_comparison:ps_5_1 gather:ps_5_1 depth_no_comparison:ps_5_1 ) -compute=(main:cs_5_1 depth_load:cs_5_1 ) diff --git a/tests/out/hlsl/image.ron b/tests/out/hlsl/image.ron new file mode 100644 index 0000000000..f5ca4931d4 --- /dev/null +++ b/tests/out/hlsl/image.ron @@ -0,0 +1,40 @@ +( + vertex:[ + ( + entry_point:"queries", + target_profile:"vs_5_1", + ), + ( + entry_point:"levels_queries", + target_profile:"vs_5_1", + ), + ], + fragment:[ + ( + entry_point:"texture_sample", + target_profile:"ps_5_1", + ), + ( + entry_point:"texture_sample_comparison", + target_profile:"ps_5_1", + ), + ( + entry_point:"gather", + target_profile:"ps_5_1", + ), + ( + entry_point:"depth_no_comparison", + target_profile:"ps_5_1", + ), + ], + compute:[ + ( + entry_point:"main", + target_profile:"cs_5_1", + ), + ( + entry_point:"depth_load", + target_profile:"cs_5_1", + ), + ], +) diff --git a/tests/out/hlsl/interface.hlsl.config b/tests/out/hlsl/interface.hlsl.config deleted file mode 100644 index d7e51aecf7..0000000000 --- a/tests/out/hlsl/interface.hlsl.config +++ /dev/null @@ -1,3 +0,0 @@ -vertex=(vertex:vs_5_1 vertex_two_structs:vs_5_1 ) -fragment=(fragment:ps_5_1 ) -compute=(compute:cs_5_1 ) diff --git a/tests/out/hlsl/interface.ron b/tests/out/hlsl/interface.ron new file mode 100644 index 0000000000..948962b991 --- /dev/null +++ b/tests/out/hlsl/interface.ron @@ -0,0 +1,24 @@ +( + vertex:[ + ( + entry_point:"vertex", + target_profile:"vs_5_1", + ), + ( + entry_point:"vertex_two_structs", + target_profile:"vs_5_1", + ), + ], + fragment:[ + ( + entry_point:"fragment", + target_profile:"ps_5_1", + ), + ], + compute:[ + ( + entry_point:"compute", + target_profile:"cs_5_1", + ), + ], +) diff --git a/tests/out/hlsl/interpolate.hlsl.config b/tests/out/hlsl/interpolate.hlsl.config deleted file mode 100644 index e08910d1e5..0000000000 --- a/tests/out/hlsl/interpolate.hlsl.config +++ /dev/null @@ -1,3 +0,0 @@ -vertex=(vert_main:vs_5_1 ) -fragment=(frag_main:ps_5_1 ) -compute=() diff --git a/tests/out/hlsl/interpolate.ron b/tests/out/hlsl/interpolate.ron new file mode 100644 index 0000000000..d0046b04dd --- /dev/null +++ b/tests/out/hlsl/interpolate.ron @@ -0,0 +1,16 @@ +( + vertex:[ + ( + entry_point:"vert_main", + target_profile:"vs_5_1", + ), + ], + fragment:[ + ( + entry_point:"frag_main", + target_profile:"ps_5_1", + ), + ], + compute:[ + ], +) diff --git a/tests/out/hlsl/inv-hyperbolic-trig-functions.hlsl.config b/tests/out/hlsl/inv-hyperbolic-trig-functions.hlsl.config deleted file mode 100644 index 98453a04ee..0000000000 --- a/tests/out/hlsl/inv-hyperbolic-trig-functions.hlsl.config +++ /dev/null @@ -1,3 +0,0 @@ -vertex=() -fragment=(main:ps_5_1 ) -compute=() diff --git a/tests/out/hlsl/inv-hyperbolic-trig-functions.ron b/tests/out/hlsl/inv-hyperbolic-trig-functions.ron new file mode 100644 index 0000000000..341a4c528e --- /dev/null +++ b/tests/out/hlsl/inv-hyperbolic-trig-functions.ron @@ -0,0 +1,12 @@ +( + vertex:[ + ], + fragment:[ + ( + entry_point:"main", + target_profile:"ps_5_1", + ), + ], + compute:[ + ], +) diff --git a/tests/out/hlsl/math-functions.hlsl.config b/tests/out/hlsl/math-functions.hlsl.config deleted file mode 100644 index 98453a04ee..0000000000 --- a/tests/out/hlsl/math-functions.hlsl.config +++ /dev/null @@ -1,3 +0,0 @@ -vertex=() -fragment=(main:ps_5_1 ) -compute=() diff --git a/tests/out/hlsl/math-functions.ron b/tests/out/hlsl/math-functions.ron new file mode 100644 index 0000000000..341a4c528e --- /dev/null +++ b/tests/out/hlsl/math-functions.ron @@ -0,0 +1,12 @@ +( + vertex:[ + ], + fragment:[ + ( + entry_point:"main", + target_profile:"ps_5_1", + ), + ], + compute:[ + ], +) diff --git a/tests/out/hlsl/operators.hlsl.config b/tests/out/hlsl/operators.hlsl.config deleted file mode 100644 index 246c485cf7..0000000000 --- a/tests/out/hlsl/operators.hlsl.config +++ /dev/null @@ -1,3 +0,0 @@ -vertex=() -fragment=() -compute=(main:cs_5_1 ) diff --git a/tests/out/hlsl/operators.ron b/tests/out/hlsl/operators.ron new file mode 100644 index 0000000000..a07b03300b --- /dev/null +++ b/tests/out/hlsl/operators.ron @@ -0,0 +1,12 @@ +( + vertex:[ + ], + fragment:[ + ], + compute:[ + ( + entry_point:"main", + target_profile:"cs_5_1", + ), + ], +) diff --git a/tests/out/hlsl/padding.hlsl.config b/tests/out/hlsl/padding.hlsl.config deleted file mode 100644 index 875a4fa4a3..0000000000 --- a/tests/out/hlsl/padding.hlsl.config +++ /dev/null @@ -1,3 +0,0 @@ -vertex=(vertex:vs_5_1 ) -fragment=() -compute=() diff --git a/tests/out/hlsl/padding.ron b/tests/out/hlsl/padding.ron new file mode 100644 index 0000000000..46dfdd83e3 --- /dev/null +++ b/tests/out/hlsl/padding.ron @@ -0,0 +1,12 @@ +( + vertex:[ + ( + entry_point:"vertex", + target_profile:"vs_5_1", + ), + ], + fragment:[ + ], + compute:[ + ], +) diff --git a/tests/out/hlsl/push-constants.hlsl.config b/tests/out/hlsl/push-constants.hlsl.config deleted file mode 100644 index f214655f7c..0000000000 --- a/tests/out/hlsl/push-constants.hlsl.config +++ /dev/null @@ -1,3 +0,0 @@ -vertex=(vert_main:vs_5_1 ) -fragment=(main:ps_5_1 ) -compute=() diff --git a/tests/out/hlsl/push-constants.ron b/tests/out/hlsl/push-constants.ron new file mode 100644 index 0000000000..e444486559 --- /dev/null +++ b/tests/out/hlsl/push-constants.ron @@ -0,0 +1,16 @@ +( + vertex:[ + ( + entry_point:"vert_main", + target_profile:"vs_5_1", + ), + ], + fragment:[ + ( + entry_point:"main", + target_profile:"ps_5_1", + ), + ], + compute:[ + ], +) diff --git a/tests/out/hlsl/quad-vert.hlsl.config b/tests/out/hlsl/quad-vert.hlsl.config deleted file mode 100644 index f72fafd91f..0000000000 --- a/tests/out/hlsl/quad-vert.hlsl.config +++ /dev/null @@ -1,3 +0,0 @@ -vertex=(main:vs_5_1 ) -fragment=() -compute=() diff --git a/tests/out/hlsl/quad-vert.ron b/tests/out/hlsl/quad-vert.ron new file mode 100644 index 0000000000..8240856a5c --- /dev/null +++ b/tests/out/hlsl/quad-vert.ron @@ -0,0 +1,12 @@ +( + vertex:[ + ( + entry_point:"main", + target_profile:"vs_5_1", + ), + ], + fragment:[ + ], + compute:[ + ], +) diff --git a/tests/out/hlsl/quad.hlsl.config b/tests/out/hlsl/quad.hlsl.config deleted file mode 100644 index 7a37fc4b06..0000000000 --- a/tests/out/hlsl/quad.hlsl.config +++ /dev/null @@ -1,3 +0,0 @@ -vertex=(vert_main:vs_5_1 ) -fragment=(frag_main:ps_5_1 fs_extra:ps_5_1 ) -compute=() diff --git a/tests/out/hlsl/quad.ron b/tests/out/hlsl/quad.ron new file mode 100644 index 0000000000..de90552356 --- /dev/null +++ b/tests/out/hlsl/quad.ron @@ -0,0 +1,20 @@ +( + vertex:[ + ( + entry_point:"vert_main", + target_profile:"vs_5_1", + ), + ], + fragment:[ + ( + entry_point:"frag_main", + target_profile:"ps_5_1", + ), + ( + entry_point:"fs_extra", + target_profile:"ps_5_1", + ), + ], + compute:[ + ], +) diff --git a/tests/out/hlsl/shadow.hlsl.config b/tests/out/hlsl/shadow.hlsl.config deleted file mode 100644 index 40d109c83c..0000000000 --- a/tests/out/hlsl/shadow.hlsl.config +++ /dev/null @@ -1,3 +0,0 @@ -vertex=(vs_main:vs_5_1 ) -fragment=(fs_main:ps_5_1 fs_main_without_storage:ps_5_1 ) -compute=() diff --git a/tests/out/hlsl/shadow.ron b/tests/out/hlsl/shadow.ron new file mode 100644 index 0000000000..69be5b25e0 --- /dev/null +++ b/tests/out/hlsl/shadow.ron @@ -0,0 +1,20 @@ +( + vertex:[ + ( + entry_point:"vs_main", + target_profile:"vs_5_1", + ), + ], + fragment:[ + ( + entry_point:"fs_main", + target_profile:"ps_5_1", + ), + ( + entry_point:"fs_main_without_storage", + target_profile:"ps_5_1", + ), + ], + compute:[ + ], +) diff --git a/tests/out/hlsl/skybox.hlsl.config b/tests/out/hlsl/skybox.hlsl.config deleted file mode 100644 index 541ec21756..0000000000 --- a/tests/out/hlsl/skybox.hlsl.config +++ /dev/null @@ -1,3 +0,0 @@ -vertex=(vs_main:vs_5_1 ) -fragment=(fs_main:ps_5_1 ) -compute=() diff --git a/tests/out/hlsl/skybox.ron b/tests/out/hlsl/skybox.ron new file mode 100644 index 0000000000..27b0c4af4d --- /dev/null +++ b/tests/out/hlsl/skybox.ron @@ -0,0 +1,16 @@ +( + vertex:[ + ( + entry_point:"vs_main", + target_profile:"vs_5_1", + ), + ], + fragment:[ + ( + entry_point:"fs_main", + target_profile:"ps_5_1", + ), + ], + compute:[ + ], +) diff --git a/tests/out/hlsl/standard.hlsl.config b/tests/out/hlsl/standard.hlsl.config deleted file mode 100644 index a2606f3ab7..0000000000 --- a/tests/out/hlsl/standard.hlsl.config +++ /dev/null @@ -1,3 +0,0 @@ -vertex=() -fragment=(derivatives:ps_5_1 ) -compute=() diff --git a/tests/out/hlsl/standard.ron b/tests/out/hlsl/standard.ron new file mode 100644 index 0000000000..82373299d8 --- /dev/null +++ b/tests/out/hlsl/standard.ron @@ -0,0 +1,12 @@ +( + vertex:[ + ], + fragment:[ + ( + entry_point:"derivatives", + target_profile:"ps_5_1", + ), + ], + compute:[ + ], +) diff --git a/tests/out/hlsl/texture-arg.hlsl.config b/tests/out/hlsl/texture-arg.hlsl.config deleted file mode 100644 index 98453a04ee..0000000000 --- a/tests/out/hlsl/texture-arg.hlsl.config +++ /dev/null @@ -1,3 +0,0 @@ -vertex=() -fragment=(main:ps_5_1 ) -compute=() diff --git a/tests/out/hlsl/texture-arg.ron b/tests/out/hlsl/texture-arg.ron new file mode 100644 index 0000000000..341a4c528e --- /dev/null +++ b/tests/out/hlsl/texture-arg.ron @@ -0,0 +1,12 @@ +( + vertex:[ + ], + fragment:[ + ( + entry_point:"main", + target_profile:"ps_5_1", + ), + ], + compute:[ + ], +) diff --git a/tests/out/hlsl/workgroup-uniform-load.hlsl.config b/tests/out/hlsl/workgroup-uniform-load.hlsl.config deleted file mode 100644 index 648d3b0d9f..0000000000 --- a/tests/out/hlsl/workgroup-uniform-load.hlsl.config +++ /dev/null @@ -1,3 +0,0 @@ -vertex=() -fragment=() -compute=(test_workgroupUniformLoad:cs_5_1 ) diff --git a/tests/out/hlsl/workgroup-uniform-load.ron b/tests/out/hlsl/workgroup-uniform-load.ron new file mode 100644 index 0000000000..17e926cdeb --- /dev/null +++ b/tests/out/hlsl/workgroup-uniform-load.ron @@ -0,0 +1,12 @@ +( + vertex:[ + ], + fragment:[ + ], + compute:[ + ( + entry_point:"test_workgroupUniformLoad", + target_profile:"cs_5_1", + ), + ], +) diff --git a/tests/out/hlsl/workgroup-var-init.hlsl.config b/tests/out/hlsl/workgroup-var-init.hlsl.config deleted file mode 100644 index 246c485cf7..0000000000 --- a/tests/out/hlsl/workgroup-var-init.hlsl.config +++ /dev/null @@ -1,3 +0,0 @@ -vertex=() -fragment=() -compute=(main:cs_5_1 ) diff --git a/tests/out/hlsl/workgroup-var-init.ron b/tests/out/hlsl/workgroup-var-init.ron new file mode 100644 index 0000000000..a07b03300b --- /dev/null +++ b/tests/out/hlsl/workgroup-var-init.ron @@ -0,0 +1,12 @@ +( + vertex:[ + ], + fragment:[ + ], + compute:[ + ( + entry_point:"main", + target_profile:"cs_5_1", + ), + ], +) diff --git a/tests/snapshots.rs b/tests/snapshots.rs index e51c6ced4f..1ea52b46ce 100644 --- a/tests/snapshots.rs +++ b/tests/snapshots.rs @@ -348,56 +348,30 @@ fn write_output_hlsl( // We need a config file for validation script // This file contains an info about profiles (shader stages) contains inside generated shader // This info will be passed to dxc - let mut config_str = String::new(); - let mut vertex_str = String::from("vertex=("); - let mut fragment_str = String::from("fragment=("); - let mut compute_str = String::from("compute=("); + let mut config = hlsl_snapshots::Config::empty(); for (index, ep) in module.entry_points.iter().enumerate() { let name = match reflection_info.entry_point_names[index] { Ok(ref name) => name, Err(_) => continue, }; match ep.stage { - naga::ShaderStage::Vertex => { - write!( - vertex_str, - "{}:{}_{} ", - name, - ep.stage.to_hlsl_str(), - options.shader_model.to_str(), - ) - .unwrap(); - } - naga::ShaderStage::Fragment => { - write!( - fragment_str, - "{}:{}_{} ", - name, - ep.stage.to_hlsl_str(), - options.shader_model.to_str(), - ) - .unwrap(); - } - naga::ShaderStage::Compute => { - write!( - compute_str, - "{}:{}_{} ", - name, - ep.stage.to_hlsl_str(), - options.shader_model.to_str(), - ) - .unwrap(); - } + naga::ShaderStage::Vertex => &mut config.vertex, + naga::ShaderStage::Fragment => &mut config.fragment, + naga::ShaderStage::Compute => &mut config.compute, } + .push(hlsl_snapshots::ConfigItem { + entry_point: name.clone(), + target_profile: format!( + "{}_{}", + ep.stage.to_hlsl_str(), + options.shader_model.to_str() + ), + }); } - writeln!(config_str, "{vertex_str})\n{fragment_str})\n{compute_str})").unwrap(); - - fs::write( - destination.join(format!("hlsl/{file_name}.hlsl.config")), - config_str, - ) - .unwrap(); + config + .to_file(destination.join(format!("hlsl/{file_name}.ron"))) + .unwrap(); } #[cfg(feature = "wgsl-out")] diff --git a/xtask/.gitignore b/xtask/.gitignore new file mode 100644 index 0000000000..c7ee281fad --- /dev/null +++ b/xtask/.gitignore @@ -0,0 +1,2 @@ +!Cargo.lock +target/ diff --git a/xtask/Cargo.lock b/xtask/Cargo.lock new file mode 100644 index 0000000000..88ece956bd --- /dev/null +++ b/xtask/Cargo.lock @@ -0,0 +1,117 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "anyhow" +version = "1.0.70" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7de8ce5e0f9f8d88245311066a578d72b7af3e7088f32783804676302df237e4" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "either" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" + +[[package]] +name = "env_logger" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0" +dependencies = [ + "log", +] + +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + +[[package]] +name = "hlsl-snapshots" +version = "0.1.0" +dependencies = [ + "anyhow", + "nanoserde", +] + +[[package]] +name = "libc" +version = "0.2.140" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c" + +[[package]] +name = "log" +version = "0.4.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "nanoserde" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "755e7965536bc54d7c9fba2df5ada5bf835b0443fd613f0a53fa199a301839d3" +dependencies = [ + "nanoserde-derive", +] + +[[package]] +name = "nanoserde-derive" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed7a94da6c6181c35d043fc61c43ac96d3a5d739e7b8027f77650ba41504d6ab" + +[[package]] +name = "once_cell" +version = "1.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" + +[[package]] +name = "pico-args" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" + +[[package]] +name = "shell-words" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde" + +[[package]] +name = "which" +version = "4.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2441c784c52b289a054b7201fc93253e288f094e2f4be9058343127c4226a269" +dependencies = [ + "either", + "libc", + "once_cell", +] + +[[package]] +name = "xtask" +version = "0.1.0" +dependencies = [ + "anyhow", + "env_logger", + "glob", + "hlsl-snapshots", + "log", + "pico-args", + "shell-words", + "which", +] diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml new file mode 100644 index 0000000000..4214df66f1 --- /dev/null +++ b/xtask/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "xtask" +version = "0.1.0" +edition = "2021" +publish = false + +[dependencies] +anyhow = "1" +env_logger = { version = "0.10.0", default-features = false } +glob = "0.3.1" +hlsl-snapshots = { path = "./hlsl-snapshots"} +log = "0.4.17" +pico-args = "0.5.0" +shell-words = "1.1.0" +which = "4.4.0" + +[workspace] + +members = [".", "./hlsl-snapshots"] diff --git a/xtask/hlsl-snapshots/Cargo.toml b/xtask/hlsl-snapshots/Cargo.toml new file mode 100644 index 0000000000..8cd662ef47 --- /dev/null +++ b/xtask/hlsl-snapshots/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "hlsl-snapshots" +version = "0.1.0" +edition = "2021" + +[dependencies] +anyhow = "1" +nanoserde = "0.1.32" diff --git a/xtask/hlsl-snapshots/src/lib.rs b/xtask/hlsl-snapshots/src/lib.rs new file mode 100644 index 0000000000..616aa73f01 --- /dev/null +++ b/xtask/hlsl-snapshots/src/lib.rs @@ -0,0 +1,97 @@ +use std::{error::Error, fmt::Display, fs, io, path::Path}; + +use anyhow::{anyhow, ensure}; +use nanoserde::{self, DeRon, DeRonErr, SerRon}; + +#[derive(Debug)] +struct BadRonParse(BadRonParseKind); + +impl Display for BadRonParse { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "failed to read RON configuration of HLSL snapshot test") + } +} + +impl Error for BadRonParse { + fn source(&self) -> Option<&(dyn Error + 'static)> { + Some(&self.0) + } +} + +#[derive(Debug)] +enum BadRonParseKind { + Read { source: io::Error }, + Parse { source: DeRonErr }, + Empty, +} + +impl Display for BadRonParseKind { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + BadRonParseKind::Read { source } => Display::fmt(source, f), + BadRonParseKind::Parse { source } => Display::fmt(source, f), + BadRonParseKind::Empty => write!(f, "no configuration was specified"), + } + } +} + +impl Error for BadRonParseKind { + fn source(&self) -> Option<&(dyn Error + 'static)> { + match self { + BadRonParseKind::Read { source } => source.source(), + BadRonParseKind::Parse { source } => source.source(), + BadRonParseKind::Empty => None, + } + } +} + +#[derive(Debug, DeRon, SerRon)] +pub struct Config { + pub vertex: Vec, + pub fragment: Vec, + pub compute: Vec, +} + +impl Config { + pub fn empty() -> Self { + Self { + vertex: Default::default(), + fragment: Default::default(), + compute: Default::default(), + } + } + + pub fn from_path(path: impl AsRef) -> anyhow::Result { + let path = path.as_ref(); + let raw_config = fs::read_to_string(path) + .map_err(|source| BadRonParse(BadRonParseKind::Read { source }))?; + let config = Config::deserialize_ron(&raw_config) + .map_err(|source| BadRonParse(BadRonParseKind::Parse { source }))?; + ensure!(!config.is_empty(), BadRonParse(BadRonParseKind::Empty)); + Ok(config) + } + + pub fn to_file(&self, path: impl AsRef) -> anyhow::Result<()> { + let path = path.as_ref(); + let mut s = self.serialize_ron(); + s.push('\n'); + fs::write(path, &s).map_err(|e| anyhow!("failed to write to {}: {e}", path.display())) + } + + pub fn is_empty(&self) -> bool { + let Self { + vertex, + fragment, + compute, + } = self; + vertex.is_empty() && fragment.is_empty() && compute.is_empty() + } +} + +#[derive(Debug, DeRon, SerRon)] +pub struct ConfigItem { + pub entry_point: String, + /// See also + /// . + pub target_profile: String, +} diff --git a/xtask/src/cli.rs b/xtask/src/cli.rs new file mode 100644 index 0000000000..c6fd6d2a69 --- /dev/null +++ b/xtask/src/cli.rs @@ -0,0 +1,160 @@ +use std::process::exit; + +use anyhow::{anyhow, bail, ensure, Context}; +use pico_args::Arguments; + +const HELP: &str = "\ +Usage: xtask + +Commands: + all + bench [--clean] + validate + dot + glsl + hlsl + dxc + fxc + msl + spv + +Options: + -h, --help Print help +"; + +#[derive(Debug)] +pub(crate) struct Args { + pub subcommand: Subcommand, +} + +impl Args { + pub fn parse() -> Self { + let mut args = Arguments::from_env(); + log::debug!("parsing args: {args:?}"); + if args.contains("--help") { + eprint!("{HELP}"); + exit(101); + } + match (|| -> anyhow::Result<_> { + let subcommand = Subcommand::parse(args)?; + Ok(Self { subcommand }) + })() { + Ok(this) => this, + Err(e) => { + eprintln!("{:?}", anyhow!(e)); + exit(1) + } + } + } +} + +#[derive(Debug)] +pub(crate) enum Subcommand { + All, + Bench { clean: bool }, + Validate(ValidateSubcommand), +} + +impl Subcommand { + fn parse(mut args: Arguments) -> anyhow::Result { + args.subcommand() + .context("failed to parse subcommand") + .and_then(|parsed| match parsed.as_deref() { + None => bail!("no subcommand specified; see `--help` for more details"), + Some("all") => { + ensure_remaining_args_empty(args)?; + Ok(Self::All) + } + Some("bench") => { + let clean = args.contains("--clean"); + ensure_remaining_args_empty(args)?; + Ok(Self::Bench { clean }) + } + Some("validate") => Ok(Self::Validate(ValidateSubcommand::parse(args)?)), + Some(other) => { + bail!("unrecognized subcommand {other:?}; see `--help` for more details") + } + }) + } +} + +#[derive(Debug)] +pub(crate) enum ValidateSubcommand { + Spirv, + Metal, + Glsl, + Dot, + Wgsl, + Hlsl(ValidateHlslCommand), +} + +impl ValidateSubcommand { + fn parse(mut args: Arguments) -> Result { + args.subcommand() + .context("failed to parse `validate` subcommand") + .and_then(|parsed| match parsed.as_deref() { + None => bail!("no `validate` subcommand specified; see `--help` for more details"), + Some("spv") => { + ensure_remaining_args_empty(args)?; + Ok(Self::Spirv) + } + Some("msl") => { + ensure_remaining_args_empty(args)?; + Ok(Self::Metal) + } + Some("glsl") => { + ensure_remaining_args_empty(args)?; + Ok(Self::Glsl) + } + Some("dot") => { + ensure_remaining_args_empty(args)?; + Ok(Self::Dot) + } + Some("wgsl") => { + ensure_remaining_args_empty(args)?; + Ok(Self::Wgsl) + } + Some("hlsl") => Ok(Self::Hlsl(ValidateHlslCommand::parse(args)?)), + Some(other) => bail!( + "unrecognized `validate` subcommand {other:?}; see `--help` for more details" + ), + }) + } +} + +#[derive(Debug)] +pub(crate) enum ValidateHlslCommand { + Dxc, + Fxc, +} + +impl ValidateHlslCommand { + fn parse(mut args: Arguments) -> anyhow::Result { + args.subcommand() + .context("failed to parse `hlsl` subcommand") + .and_then(|parsed| match parsed.as_deref() { + None => bail!("no `hlsl` subcommand specified; see `--help` for more details"), + Some("dxc") => { + ensure_remaining_args_empty(args)?; + Ok(Self::Dxc) + } + Some("fxc") => { + ensure_remaining_args_empty(args)?; + Ok(Self::Fxc) + } + Some(other) => { + bail!("unrecognized `hlsl` subcommand {other:?}; see `--help` for more details") + } + }) + } +} + +fn ensure_remaining_args_empty(args: Arguments) -> anyhow::Result<()> { + let remaining_args = args.finish(); + ensure!( + remaining_args.is_empty(), + "not all arguments were parsed (remaining: {remaining_args:?}); fix your invocation, \ + please!" + ); + Ok(()) +} diff --git a/xtask/src/fs.rs b/xtask/src/fs.rs new file mode 100644 index 0000000000..98870fc9f9 --- /dev/null +++ b/xtask/src/fs.rs @@ -0,0 +1,10 @@ +use std::{fs::File, path::Path}; + +use anyhow::Context; + +pub(crate) use std::fs::*; + +pub(crate) fn open_file(path: impl AsRef) -> anyhow::Result { + let path = path.as_ref(); + File::open(path).with_context(|| format!("failed to open {path:?}")) +} diff --git a/xtask/src/glob.rs b/xtask/src/glob.rs new file mode 100644 index 0000000000..d69891e78a --- /dev/null +++ b/xtask/src/glob.rs @@ -0,0 +1,37 @@ +use std::path::Path; + +use anyhow::Context; +use glob::glob; + +use crate::result::{ErrorStatus, LogIfError}; + +pub(crate) fn visit_files( + path: impl AsRef, + glob_expr: &str, + mut f: impl FnMut(&Path) -> anyhow::Result<()>, +) -> ErrorStatus { + let path = path.as_ref(); + let glob_expr = path.join(glob_expr); + let glob_expr = glob_expr.to_str().unwrap(); + + let mut status = ErrorStatus::NoFailuresFound; + glob(glob_expr) + .context("glob pattern {path:?} is invalid") + .unwrap() + .for_each(|path_res| { + if let Some(path) = path_res + .with_context(|| format!("error while iterating over glob {path:?}")) + .log_if_err_found(&mut status) + { + if path + .metadata() + .with_context(|| format!("failed to fetch metadata for {path:?}")) + .log_if_err_found(&mut status) + .map_or(false, |m| m.is_file()) + { + f(&path).log_if_err_found(&mut status); + } + } + }); + status +} diff --git a/xtask/src/main.rs b/xtask/src/main.rs new file mode 100644 index 0000000000..17156db735 --- /dev/null +++ b/xtask/src/main.rs @@ -0,0 +1,305 @@ +use std::{ + io::{BufRead, BufReader}, + path::Path, + process::{ExitCode, Stdio}, +}; + +use anyhow::{bail, Context}; +use cli::Args; + +use crate::{ + cli::{Subcommand, ValidateHlslCommand, ValidateSubcommand}, + fs::{open_file, remove_dir_all}, + glob::visit_files, + path::join_path, + process::{which, EasyCommand}, + result::{ErrorStatus, LogIfError}, +}; + +mod cli; +mod fs; +mod glob; +mod path; +mod process; +mod result; + +fn main() -> ExitCode { + env_logger::builder() + .filter_level(log::LevelFilter::Info) + .parse_default_env() + .format_indent(Some(0)) + .init(); + + let args = Args::parse(); + + match run(args) { + Ok(()) => ExitCode::SUCCESS, + Err(e) => { + log::error!("{e:?}"); + ExitCode::FAILURE + } + } +} + +fn run(args: Args) -> anyhow::Result<()> { + let snapshots_base_out = join_path(["tests", "out"]); + + let Args { subcommand } = args; + + assert!(which("cargo").is_ok()); + + match subcommand { + Subcommand::All => { + EasyCommand::simple("cargo", ["fmt"]).success()?; + EasyCommand::simple("cargo", ["test", "--all-features", "--workspace"]).success()?; + EasyCommand::simple( + "cargo", + [ + "clippy", + "--all-features", + "--workspace", + "--", + "-D", + "warnings", + ], + ) + .success()?; + Ok(()) + } + Subcommand::Bench { clean } => { + if clean { + let criterion_artifact_dir = join_path(["target", "criterion"]); + log::info!("removing {}", criterion_artifact_dir.display()); + remove_dir_all(&criterion_artifact_dir) + .with_context(|| format!("failed to remove {criterion_artifact_dir:?}"))?; + } + EasyCommand::simple("cargo", ["bench"]).success() + } + Subcommand::Validate(cmd) => { + let ack_visiting = |path: &Path| log::info!("Validating {}", path.display()); + let err_status = match cmd { + ValidateSubcommand::Spirv => { + let spirv_as = "spirv-as"; + which(spirv_as)?; + + let spirv_val = "spirv-val"; + which(spirv_val)?; + + visit_files(snapshots_base_out, "spv/*.spvasm", |path| { + ack_visiting(path); + let second_line = { + let mut file = BufReader::new(open_file(path)?); + let mut buf = String::new(); + file.read_line(&mut buf).with_context(|| { + format!("failed to read first line from {path:?}") + })?; + buf.clear(); + file.read_line(&mut buf).with_context(|| { + format!("failed to read second line from {path:?}") + })?; + buf + }; + let expected_header_prefix = "; Version: "; + let Some(version) = + second_line.strip_prefix(expected_header_prefix) else { + bail!( + "no {expected_header_prefix:?} header found in {path:?}" + ); + }; + let file = open_file(path)?; + let mut spirv_as_cmd = EasyCommand::new(spirv_as, |cmd| { + cmd.stdin(Stdio::from(file)) + .stdout(Stdio::piped()) + .arg("--target-env") + .arg(format!("spv{version}")) + .args(["-", "-o", "-"]) + }); + let child = spirv_as_cmd + .spawn() + .with_context(|| format!("failed to spawn {cmd:?}"))?; + EasyCommand::new(spirv_val, |cmd| cmd.stdin(child.stdout.unwrap())) + .success() + }) + } + ValidateSubcommand::Metal => { + let xcrun = "xcrun"; + which(xcrun)?; + visit_files(snapshots_base_out, "msl/*.msl", |path| { + ack_visiting(path); + let first_line = { + let mut file = BufReader::new(open_file(path)?); + let mut buf = String::new(); + file.read_line(&mut buf) + .with_context(|| format!("failed to read header from {path:?}"))?; + buf + }; + let expected_header_prefix = "// language: "; + let Some(language) = + first_line.strip_prefix(expected_header_prefix) else { + bail!( + "no {expected_header_prefix:?} header found in {path:?}" + ); + }; + let language = language.strip_suffix('\n').unwrap_or(language); + + let file = open_file(path)?; + EasyCommand::new(xcrun, |cmd| { + cmd.stdin(Stdio::from(file)) + .args(["-sdk", "macosx", "metal", "-mmacosx-version-min=10.11"]) + .arg(format!("-std=macos-{language}")) + .args(["-x", "metal", "-", "-o", "/dev/null"]) + }) + .success() + }) + } + ValidateSubcommand::Glsl => { + let glslang_validator = "glslangValidator"; + which(glslang_validator)?; + let mut err_status = ErrorStatus::NoFailuresFound; + for (glob, type_arg) in [ + ("glsl/*.Vertex.glsl", "vert"), + ("glsl/*.Fragment.glsl", "frag"), + ("glsl/*.Compute.glsl", "comp"), + ] { + let type_err_status = visit_files(&snapshots_base_out, glob, |path| { + ack_visiting(path); + let file = open_file(path)?; + EasyCommand::new(glslang_validator, |cmd| { + cmd.stdin(Stdio::from(file)) + .args(["--stdin", "-S"]) + .arg(type_arg) + }) + .success() + }); + err_status = err_status.merge(type_err_status); + } + err_status + } + ValidateSubcommand::Dot => { + let dot = "dot"; + which(dot)?; + visit_files(snapshots_base_out, "dot/*.dot", |path| { + ack_visiting(path); + let file = open_file(path)?; + EasyCommand::new(dot, |cmd| { + cmd.stdin(Stdio::from(file)).stdout(Stdio::null()) + }) + .success() + }) + } + ValidateSubcommand::Wgsl => { + visit_files(snapshots_base_out, "wgsl/*.wgsl", |path| { + ack_visiting(path); + EasyCommand::new("cargo", |cmd| cmd.args(["run", "--"]).arg(path)).success() + }) + } + ValidateSubcommand::Hlsl(cmd) => { + let visit_hlsl = |consume_config_item: &mut dyn FnMut( + &Path, + hlsl_snapshots::ConfigItem, + ) + -> anyhow::Result<()>| { + visit_files(snapshots_base_out, "hlsl/*.hlsl", |path| { + ack_visiting(path); + let hlsl_snapshots::Config { + vertex, + fragment, + compute, + } = hlsl_snapshots::Config::from_path(path.with_extension("ron"))?; + let mut status = ErrorStatus::NoFailuresFound; + [vertex, fragment, compute] + .into_iter() + .flatten() + .for_each(|shader| { + consume_config_item(path, shader).log_if_err_found(&mut status); + }); + match status { + ErrorStatus::NoFailuresFound => Ok(()), + ErrorStatus::OneOrMoreFailuresFound => bail!( + "one or more shader HLSL shader tests failed for {}", + path.display() + ), + } + }) + }; + let validate = |bin, file: &_, config_item, params: &[_]| { + let hlsl_snapshots::ConfigItem { + entry_point, + target_profile, + } = config_item; + EasyCommand::new(bin, |cmd| { + cmd.arg(file) + .arg("-T") + .arg(&target_profile) + .arg("-E") + .arg(&entry_point) + .args(params) + .stdout(Stdio::null()) + }) + .success() + .with_context(|| { + format!( + "failed to validate entry point {entry_point:?} with profile \ + {target_profile:?}" + ) + }) + }; + match cmd { + ValidateHlslCommand::Dxc => { + let bin = "dxc"; + which(bin)?; + visit_hlsl(&mut |file, config_item| { + // Reference: + // . + validate( + bin, + file, + config_item, + &["-Wno-parentheses-equality", "-Zi", "-Qembed_debug", "-Od"], + ) + }) + } + ValidateHlslCommand::Fxc => { + let bin = "fxc"; + which(bin)?; + visit_hlsl(&mut |file, config_item| { + let Some(Ok(shader_model_major_version)) = config_item + .target_profile + .split('_') + .nth(1) + .map(|segment| segment.parse::()) else { + bail!( + "expected target profile of the form \ + `{{model}}_{{major}}_{{minor}}`, found invalid target \ + profile {:?} in file {}", + config_item.target_profile, + file.display() + ) + }; + // NOTE: This isn't implemented by `fxc.exe`; see + // . + if shader_model_major_version < 6 { + // Reference: + // . + validate(bin, file, config_item, &["-Zi", "-Od"]) + } else { + log::debug!( + "skipping config. item {config_item:?} because the \ + shader model major version is > 6" + ); + Ok(()) + } + }) + } + } + } + }; + match err_status { + ErrorStatus::NoFailuresFound => Ok(()), + ErrorStatus::OneOrMoreFailuresFound => { + bail!("failed to validate one or more files, see above output for more details") + } + } + } + } +} diff --git a/xtask/src/path.rs b/xtask/src/path.rs new file mode 100644 index 0000000000..4ba3a0ba4a --- /dev/null +++ b/xtask/src/path.rs @@ -0,0 +1,11 @@ +use std::path::{Path, PathBuf}; + +pub(crate) fn join_path(iter: I) -> PathBuf +where + P: AsRef, + I: IntoIterator, +{ + let mut path = PathBuf::new(); + path.extend(iter); + path +} diff --git a/xtask/src/process.rs b/xtask/src/process.rs new file mode 100644 index 0000000000..37a24f1b6e --- /dev/null +++ b/xtask/src/process.rs @@ -0,0 +1,78 @@ +use std::{ + ffi::{OsStr, OsString}, + fmt::{self, Display}, + iter::once, + ops::{Deref, DerefMut}, + process::Command, +}; + +use anyhow::{ensure, Context}; + +#[derive(Debug)] +pub(crate) struct EasyCommand { + inner: Command, +} + +impl EasyCommand { + pub fn new(cmd: C, config: impl FnOnce(&mut Command) -> &mut Command) -> Self + where + C: AsRef, + { + let mut inner = Command::new(cmd); + config(&mut inner); + Self { inner } + } + + pub fn simple(cmd: C, args: I) -> Self + where + C: AsRef, + A: AsRef, + I: IntoIterator, + { + Self::new(cmd, |cmd| cmd.args(args)) + } + + pub fn success(&mut self) -> anyhow::Result<()> { + let Self { inner } = self; + log::debug!("running {inner:?}"); + let status = inner + .status() + .with_context(|| format!("failed to run {self}"))?; + ensure!( + status.success(), + "{self} failed to run; exit code: {:?}", + status.code() + ); + Ok(()) + } +} + +impl Deref for EasyCommand { + type Target = Command; + + fn deref(&self) -> &Self::Target { + &self.inner + } +} + +impl DerefMut for EasyCommand { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.inner + } +} + +pub(crate) fn which(binary_name: &str) -> anyhow::Result { + ::which::which(binary_name) + .with_context(|| format!("unable to find `{binary_name}` binary")) + .map(|buf| buf.file_name().unwrap().to_owned()) +} + +impl Display for EasyCommand { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let Self { inner } = self; + let prog = inner.get_program().to_string_lossy(); + let args = inner.get_args().map(|a| a.to_string_lossy()); + let shell_words = shell_words::join(once(prog).chain(args)); + write!(f, "`{shell_words}`") + } +} diff --git a/xtask/src/result.rs b/xtask/src/result.rs new file mode 100644 index 0000000000..e351ebf4cf --- /dev/null +++ b/xtask/src/result.rs @@ -0,0 +1,33 @@ +#[derive(Clone, Copy, Debug)] +pub(crate) enum ErrorStatus { + NoFailuresFound, + OneOrMoreFailuresFound, +} + +impl ErrorStatus { + pub(crate) fn merge(self, other: Self) -> Self { + match (self, other) { + (Self::OneOrMoreFailuresFound, _) | (_, Self::OneOrMoreFailuresFound) => { + Self::OneOrMoreFailuresFound + } + (Self::NoFailuresFound, Self::NoFailuresFound) => Self::NoFailuresFound, + } + } +} + +pub(crate) trait LogIfError { + fn log_if_err_found(self, status: &mut ErrorStatus) -> Option; +} + +impl LogIfError for anyhow::Result { + fn log_if_err_found(self, status: &mut ErrorStatus) -> Option { + match self { + Ok(t) => Some(t), + Err(e) => { + log::error!("{e:?}"); + *status = status.merge(ErrorStatus::OneOrMoreFailuresFound); + None + } + } + } +}