Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 46 additions & 6 deletions .github/workflows/push.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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 }}

Expand All @@ -77,15 +117,15 @@ 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:
# Another hack is to actually check the status of the dependencies or else it'll fall through
- 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:
Expand Down
1 change: 1 addition & 0 deletions crates/shader-crate-template/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/shader-crate-template/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
180 changes: 153 additions & 27 deletions crates/xtask/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,19 @@ enum Cli {
/// Build using the specified version of `spirv-std`.
#[clap(long)]
rust_gpu_version: Option<String>,
/// The version of glam to use
#[clap(long)]
glam_version: Option<String>,
},
/// 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<String>,
},
}

Expand Down Expand Up @@ -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"),
Expand All @@ -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::<toml::Table>(&original_shader_crate_template_str).unwrap();
Expand All @@ -79,6 +104,7 @@ impl ShaderCrateTemplateCargoTomlWriter {
original_shader_crate_template_str,
original_shader_crate_lock_file,
table,
persistent,
}
}

Expand Down Expand Up @@ -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<String>) -> anyhow::Result<Self> {
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<toml::Table> {
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");
Expand All @@ -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(())
}
Loading