diff --git a/.github/workflows/push.yaml b/.github/workflows/push.yaml index 3f0bd481..e48fea0d 100644 --- a/.github/workflows/push.yaml +++ b/.github/workflows/push.yaml @@ -36,11 +36,11 @@ jobs: - name: Run a full build run: cargo xtask test-build - test-rust-gpu-releases: + test-rust-gpu: strategy: fail-fast: false matrix: - rust-gpu-version: + include: # As well as testing on each OS, we also want to test to make sure we're still supporting # older versions of `rust-gpu`. However, we can assume that these tests are already okay # across platforms, so we only need to test on Linux, the chepeast in terms of minutes. @@ -52,13 +52,53 @@ jobs: # """ # It's probably easily fixable. But also `0.7.0` was released in April 2023, so there's # unlikely many users of it? - - 0.8.0 - - 0.9.0 + - rust-gpu-version: 0.8.0 + glam-version: 0.24.2 + - rust-gpu-version: 0.9.0 + glam-version: 0.24.2 + + # target spec introduction + # last version before + # * fails: compiler too old, `serde` using `#[diagnostic]` +# - rust-gpu-version: cc752312c3de6813a41189e46476d5c1be5e0bbe +# glam-version: 0.30.7 + # first version requiring target specs + # * fails: target spec mismatch! + # * resolution: Since this is just a few commits, I'd be fine ignoring it. +# - rust-gpu-version: 02cefd101014f66b79dffb20a2c2b5b7c9038401 +# glam-version: 0.30.7 + # target specs change again just a few commits later + # * fails: compiler too old, `proc-macro2` using `Literal::byte_character`. + # * resolution: want to support, can't be bothered to hack in old proc-macro2 versions +# - rust-gpu-version: bbb61f58b3d24f3f64745050eb214b90bf6dcce9 +# glam-version: 0.30.7 + + # testing rustc 1.5 months later + - rust-gpu-version: eea8998df9dc2fd8e7a65c5b5b7ae20c238a665a + glam-version: 0.29.3 + + # just after target specs v2 refactor, we updated to rustc 1.85 and needed to change them again + # before + - rust-gpu-version: a547c6e45266d613d9fec673e869d7a96181e47b + glam-version: =0.30.7 + # after + - rust-gpu-version: 2326b87fe1542eeb898065e36ac949307b55386d + glam-version: =0.30.7 + + # glam semver breakage due to vector type refactor + # before, glam was fixed to <=0.30.7 in this commit + - rust-gpu-version: f79c4181a5dc2d37303947b113f190930c6c1ce6 + glam-version: =0.30.7 + # after, glam >0.30.8 + - rust-gpu-version: e767f24f2565baf1a71bbaf84d453d181cab2417 runs-on: ubuntu-latest env: RUST_LOG: debug steps: - uses: actions/checkout@v4 + - if: ${{ matrix.glam-version }} + name: set glam version + run: cargo xtask set-dependency glam ${{ matrix.glam-version }} - name: Run a full build run: cargo xtask test-build --rust-gpu-version ${{ matrix.rust-gpu-version }} @@ -77,7 +117,7 @@ jobs: # to update the branch protection rules when the test matrix changes test_success: runs-on: ubuntu-24.04 - needs: [test-os, test-rust-gpu-releases, lint] + needs: [test-os, test-rust-gpu, lint] # Hack for buggy GitHub Actions behavior with skipped checks: https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/collaborating-on-repositories-with-code-quality-features/troubleshooting-required-status-checks#handling-skipped-but-required-checks if: ${{ always() }} steps: @@ -85,7 +125,7 @@ jobs: - run: | echo "Checking statuses..." [[ "${{ needs.test-os.result }}" == "success" ]] || exit 1 - [[ "${{ needs.test-rust-gpu-releases.result }}" == "success" ]] || exit 1 + [[ "${{ needs.test-rust-gpu.result }}" == "success" ]] || exit 1 [[ "${{ needs.lint.result }}" == "success" ]] || exit 1 defaults: diff --git a/crates/shader-crate-template/Cargo.lock b/crates/shader-crate-template/Cargo.lock index 29a1a182..a61d1e83 100644 --- a/crates/shader-crate-template/Cargo.lock +++ b/crates/shader-crate-template/Cargo.lock @@ -61,6 +61,7 @@ dependencies = [ name = "rust-gpu-shader-crate-template" version = "0.1.0" dependencies = [ + "glam", "spirv-std", ] diff --git a/crates/shader-crate-template/Cargo.toml b/crates/shader-crate-template/Cargo.toml index 18fb6783..a3363f4a 100644 --- a/crates/shader-crate-template/Cargo.toml +++ b/crates/shader-crate-template/Cargo.toml @@ -10,6 +10,7 @@ crate-type = ["rlib", "cdylib"] [dependencies] # TODO: use a simple crate version once v0.10.0 is released spirv-std = { git = "https://github.com/Rust-GPU/rust-gpu", rev = "2aa4d4f8a8ba73103501562cfca17b8163e5a887" } +glam = { version = "0.30.8", default-features = false } [package.metadata.rust-gpu.build] # Where to output the compiled shader. Defaults to where `cargo gpu` is called from. diff --git a/crates/xtask/src/main.rs b/crates/xtask/src/main.rs index 8eec0beb..076c57c1 100644 --- a/crates/xtask/src/main.rs +++ b/crates/xtask/src/main.rs @@ -20,6 +20,19 @@ enum Cli { /// Build using the specified version of `spirv-std`. #[clap(long)] rust_gpu_version: Option, + /// The version of glam to use + #[clap(long)] + glam_version: Option, + }, + /// Set a dependency in the shader-crate-template to some version + SetDependency { + /// the dependency to modify + package: String, + /// the version to set it to + version: String, + /// the git repo to use, if version is a commit rev + #[clap(long)] + git: Option, }, } @@ -48,10 +61,16 @@ struct ShaderCrateTemplateCargoTomlWriter { original_shader_crate_lock_file: String, /// Parsed toml table table: toml::Table, + /// false will reset Cargo.toml when this is dropped + persistent: bool, } impl Drop for ShaderCrateTemplateCargoTomlWriter { fn drop(&mut self) { + if self.persistent { + return; + } + log::info!("reverting overwrite of Cargo.toml"); std::fs::write( format!("{SHADER_CRATE_PATH}/Cargo.toml"), @@ -67,9 +86,15 @@ impl Drop for ShaderCrateTemplateCargoTomlWriter { } } +impl Default for ShaderCrateTemplateCargoTomlWriter { + fn default() -> Self { + Self::new(false) + } +} + impl ShaderCrateTemplateCargoTomlWriter { /// Create a new one - fn new() -> Self { + fn new(persistent: bool) -> Self { let original_shader_crate_template_str = std::fs::read_to_string(format!("{SHADER_CRATE_PATH}/Cargo.toml")).unwrap(); let table = toml::from_str::(&original_shader_crate_template_str).unwrap(); @@ -79,6 +104,7 @@ impl ShaderCrateTemplateCargoTomlWriter { original_shader_crate_template_str, original_shader_crate_lock_file, table, + persistent, } } @@ -128,40 +154,129 @@ impl ShaderCrateTemplateCargoTomlWriter { Ok(()) } - /// Replace the `spirv-std` dependency version - fn replace_spirv_std_version(&mut self, version: String) -> anyhow::Result<()> { + /// Add or replace a dependency in the shader-crate-template + fn set_dependency(&mut self, package: &str, version: &DependencyVersion) -> anyhow::Result<()> { let dependencies = self.get_cargo_dependencies_table(); - let spirv_std = dependencies.get_mut("spirv-std").unwrap(); - *spirv_std = toml::Value::String(version); - self.write_shader_crate_cargo_toml_changes()?; - Ok(()) + if let Some(value) = dependencies.get_mut(package) { + version.modify_toml(value); + self.write_shader_crate_cargo_toml_changes()?; + Ok(()) + } else { + anyhow::bail!("Crate `{package}` not found") + } + } + + /// Replace the `spirv-std` dependency version + fn set_spirv_std_version(&mut self, version: &str) -> anyhow::Result<()> { + self.set_dependency( + "spirv-std", + &DependencyVersion::parse( + version.into(), + Some("https://github.com/Rust-GPU/rust-gpu".into()), + )?, + ) + } + + /// Replace the `glam` dependency version + fn set_dependency_glam(&mut self, version: &str) -> anyhow::Result<()> { + self.set_dependency( + "glam", + &DependencyVersion::parse( + version.into(), + Some("https://github.com/bitshifter/glam-rs".into()), + )?, + ) + } +} + +/// The version of a dependency +#[non_exhaustive] +pub enum DependencyVersion { + /// Don't change anything, don't replace the dependency nor add it when it's not there. + Latest, + /// A version dependency for crates.io + Crates(String), + /// A git dependency on a specific rev + Git { + /// git repo + git: String, + /// git commit revision + rev: String, + }, +} + +impl DependencyVersion { + /// Try to parse a version from a string + /// + /// # Errors + /// if `version` is a commit rev, `git` must be specified + pub fn parse(version: String, git: Option) -> anyhow::Result { + if version == "latest" { + Ok(Self::Latest) + } else if version.contains('.') { + Ok(Self::Crates(version)) + } else { + Ok(Self::Git { + git: git.context("specifying a revision requires a git repo")?, + rev: version, + }) + } + } + + /// Convert this version to a toml value, may fail if we want the latest version + #[must_use] + pub fn to_toml(&self) -> Option { + match self { + Self::Latest => None, + Self::Crates(version) => Some(toml::Table::from_iter([( + "version".to_owned(), + toml::Value::String(version.clone()), + )])), + Self::Git { git, rev } => Some(toml::Table::from_iter([ + ("git".to_owned(), toml::Value::String(git.clone())), + ("rev".to_owned(), toml::Value::String(rev.clone())), + ])), + } + } + + /// Convert this version to a toml value, may fail if we want the latest version + pub fn modify_toml(&self, toml: &mut toml::Value) { + if let Some(mut table) = self.to_toml() { + let mut copy = |key: &str| { + if let Some(src_table) = toml.as_table_mut() { + if let Some(value) = src_table.remove(key) { + table.insert(key.to_owned(), value); + } + } + }; + copy("default-features"); + copy("features"); + *toml = toml::Value::Table(table); + } } } /// Run the xtask. -fn main() { +fn main() -> anyhow::Result<()> { env_logger::builder().init(); - let cli = Cli::parse(); - - match cli { + match &cli { Cli::TestBuild { - rust_gpu_version: maybe_rust_gpu_version, + rust_gpu_version, + glam_version, } => { log::info!("installing cargo gpu"); - cmd(["cargo", "install", "--path", "crates/cargo-gpu"]).unwrap(); + cmd(["cargo", "install", "--path", "crates/cargo-gpu"])?; log::info!("setup project"); - let dir = tempfile::TempDir::with_prefix("test-shader-output").unwrap(); - let mut overwriter = ShaderCrateTemplateCargoTomlWriter::new(); - overwriter.replace_output_dir(dir.path()).unwrap(); - - if let Some(rust_gpu_version) = maybe_rust_gpu_version { - if rust_gpu_version != "latest" { - overwriter - .replace_spirv_std_version(rust_gpu_version) - .unwrap(); - } + let mut overwriter = ShaderCrateTemplateCargoTomlWriter::default(); + let dir = tempfile::TempDir::with_prefix("test-shader-output")?; + overwriter.replace_output_dir(dir.path())?; + if let Some(rust_gpu_version) = rust_gpu_version.as_ref() { + overwriter.set_spirv_std_version(rust_gpu_version)?; + } + if let Some(glam_version) = glam_version.as_ref() { + overwriter.set_dependency_glam(glam_version)?; } log::info!("building with auto-install"); @@ -174,12 +289,23 @@ fn main() { "--auto-install-rust-toolchain", "--rebuild-codegen", "--force-overwrite-lockfiles-v4-to-v3", - ]) - .unwrap(); + ])?; - cmd(["ls", "-lah", dir.path().to_str().unwrap()]).unwrap(); + cmd(["ls", "-lah", dir.path().to_str().unwrap()])?; //NOTE: manifest.json is the default value here, which should be valid - cmd(["cat", dir.path().join("manifest.json").to_str().unwrap()]).unwrap(); + cmd(["cat", dir.path().join("manifest.json").to_str().unwrap()])?; + } + Cli::SetDependency { + package, + version, + git, + } => { + let mut overwriter = ShaderCrateTemplateCargoTomlWriter::new(true); + overwriter.set_dependency( + package, + &DependencyVersion::parse(version.clone(), git.clone())?, + )?; } } + Ok(()) }