55//! From there we can look at the source code to get the required Rust toolchain.
66
77use anyhow:: { anyhow, Context as _} ;
8- use cargo_metadata:: camino:: Utf8PathBuf ;
8+ use cargo_metadata:: camino:: { Utf8Path , Utf8PathBuf } ;
99use cargo_metadata:: semver:: Version ;
1010use cargo_metadata:: { MetadataCommand , Package } ;
1111use std:: fs;
@@ -63,20 +63,15 @@ impl SpirvSource {
6363 /// Look into the shader crate to get the version of `rust-gpu` it's using.
6464 pub fn get_rust_gpu_deps_from_shader < F : AsRef < Path > > (
6565 shader_crate_path : F ,
66- ) -> anyhow:: Result < ( Self , chrono:: NaiveDate , String ) > {
67- let rust_gpu_source = Self :: get_spirv_std_dep_definition ( shader_crate_path. as_ref ( ) ) ?;
68- rust_gpu_source. ensure_repo_is_installed ( ) ?;
69- rust_gpu_source. checkout ( ) ?;
70-
71- let date = rust_gpu_source. get_version_date ( ) ?;
72- let channel = Self :: get_channel_from_toolchain_toml ( & rust_gpu_source. to_dirname ( ) ?) ?;
73-
66+ ) -> anyhow:: Result < ( Self , String ) > {
67+ let spirv_std_package = Self :: get_spirv_std_package ( shader_crate_path. as_ref ( ) ) ?;
68+ let spirv_source = Self :: parse_spirv_std_source_and_version ( & spirv_std_package) ?;
69+ let channel = Self :: get_channel_from_toolchain_toml ( & spirv_std_package) ?;
7470 log:: debug!(
75- "Parsed version, date and toolchain channel from shader-defined `rust-gpu`: \
76- {rust_gpu_source:?}, {date }, {channel}"
71+ "Parsed version and toolchain channel from shader-defined `rust-gpu`: \
72+ {spirv_source:? }, {channel}"
7773 ) ;
78-
79- Ok ( ( rust_gpu_source, date, channel) )
74+ Ok ( ( spirv_source, channel) )
8075 }
8176
8277 /// Convert the source to just its version.
@@ -124,78 +119,16 @@ impl SpirvSource {
124119 Ok ( canonical_path)
125120 }
126121
127- /// Checkout the `rust-gpu` repo to the requested version.
128- fn checkout ( & self ) -> anyhow:: Result < ( ) > {
129- let Self :: Git { rev, .. } = self else {
130- log:: trace!( "Skipping checking out rust-gpu" , ) ;
131- return Ok ( ( ) ) ;
132- } ;
133-
134- log:: debug!(
135- "Checking out `rust-gpu` repo at {} to {}" ,
136- self . to_dirname( ) ?. display( ) ,
137- self . to_version( )
138- ) ;
139- let mut command_checkout = std:: process:: Command :: new ( "git" ) ;
140- command_checkout
141- . current_dir ( self . to_dirname ( ) ?)
142- . args ( [ "checkout" , rev] ) ;
143- log:: debug!( "Running command {:?}" , command_checkout) ;
144- let output_checkout = command_checkout. output ( ) ?;
145- anyhow:: ensure!(
146- output_checkout. status. success( ) ,
147- "couldn't checkout revision '{}' of `rust-gpu` at {}. \n Error Output: {}" ,
148- self . to_version( ) ,
149- self . to_dirname( ) ?. to_string_lossy( ) ,
150- String :: from_utf8( output_checkout. stderr) . unwrap( )
151- ) ;
152-
153- Ok ( ( ) )
154- }
155-
156- /// Get the date of the version of `rust-gpu` used by the shader. This allows us to know what
157- /// features we can use in the `spirv-builder` crate.
158- fn get_version_date ( & self ) -> anyhow:: Result < chrono:: NaiveDate > {
159- let date_format = "%Y-%m-%d" ;
160-
161- log:: debug!(
162- "Getting `rust-gpu` version date from {}" ,
163- self . to_dirname( ) ?. display( ) ,
164- ) ;
165- let output_date = std:: process:: Command :: new ( "git" )
166- . current_dir ( self . to_dirname ( ) ?)
167- . args ( [
168- "show" ,
169- "--no-patch" ,
170- "--format=%cd" ,
171- format ! ( "--date=format:'{date_format}'" ) . as_ref ( ) ,
172- "HEAD" ,
173- ] )
174- . output ( ) ?;
175- anyhow:: ensure!(
176- output_date. status. success( ) ,
177- "couldn't get `rust-gpu` version date at for {} at {}" ,
178- self . to_version( ) ,
179- self . to_dirname( ) ?. to_string_lossy( )
180- ) ;
181- let date_string = String :: from_utf8_lossy ( & output_date. stdout )
182- . to_string ( )
183- . trim ( )
184- . replace ( '\'' , "" ) ;
185-
186- log:: debug!(
187- "Parsed date for version {}: {date_string}" ,
188- self . to_version( )
189- ) ;
190-
191- Ok ( chrono:: NaiveDate :: parse_from_str (
192- & date_string,
193- date_format,
194- ) ?)
195- }
196-
197122 /// Parse the `rust-toolchain.toml` in the working tree of the checked-out version of the `rust-gpu` repo.
198- fn get_channel_from_toolchain_toml ( path : & PathBuf ) -> anyhow:: Result < String > {
123+ fn get_channel_from_toolchain_toml ( spirv_std_package : & Package ) -> anyhow:: Result < String > {
124+ // TODO can we query the toolchain toml from spirv_std, or should we rather do that from rustc_codegen_spirv within our build dir?
125+ let path = spirv_std_package
126+ . manifest_path
127+ . parent ( )
128+ . and_then ( Utf8Path :: parent)
129+ . and_then ( Utf8Path :: parent)
130+ . context ( "parent of spirv_std" ) ?;
131+
199132 log:: debug!( "Parsing `rust-toolchain.toml` at {path:?} for the used toolchain" ) ;
200133
201134 let contents = fs:: read_to_string ( path. join ( "rust-toolchain.toml" ) ) ?;
@@ -213,7 +146,7 @@ impl SpirvSource {
213146 }
214147
215148 /// Get the shader crate's resolved `spirv_std = ...` definition in its `Cargo.toml`/`Cargo.lock`
216- pub fn get_spirv_std_dep_definition ( shader_crate_path : & Path ) -> anyhow:: Result < Self > {
149+ pub fn get_spirv_std_package ( shader_crate_path : & Path ) -> anyhow:: Result < Package > {
217150 let canonical_shader_path = Self :: shader_crate_path_canonical ( shader_crate_path) ?;
218151
219152 log:: debug!(
@@ -226,16 +159,15 @@ impl SpirvSource {
226159
227160 let Some ( spirv_std_package) = metadata
228161 . packages
229- . iter ( )
162+ . into_iter ( )
230163 . find ( |package| package. name . eq ( "spirv-std" ) )
231164 else {
232165 anyhow:: bail!(
233166 "`spirv-std` not found in shader's `Cargo.toml` at {canonical_shader_path:?}"
234167 ) ;
235168 } ;
236169 log:: trace!( " found {spirv_std_package:?}" ) ;
237-
238- Ok ( Self :: parse_spirv_std_source_and_version ( spirv_std_package) ?)
170+ Ok ( spirv_std_package)
239171 }
240172
241173 /// Parse a string like:
@@ -295,46 +227,6 @@ impl SpirvSource {
295227
296228 Ok ( result)
297229 }
298-
299- /// `git clone` the `rust-gpu` repo. We use it to get the required Rust toolchain to compile
300- /// the shader.
301- fn ensure_repo_is_installed ( & self ) -> anyhow:: Result < ( ) > {
302- if self . to_dirname ( ) ?. exists ( ) {
303- log:: debug!(
304- "Not cloning `rust-gpu` repo ({}) as it already exists at {}" ,
305- self . to_repo( ) ,
306- self . to_dirname( ) ?. to_string_lossy( ) . as_ref( ) ,
307- ) ;
308- return Ok ( ( ) ) ;
309- }
310-
311- log:: debug!(
312- "Cloning `rust-gpu` repo {} to {}" ,
313- self . to_repo( ) ,
314- self . to_dirname( ) ?. to_string_lossy( ) . as_ref( ) ,
315- ) ;
316-
317- crate :: user_output!( "Cloning `rust-gpu` repo...\n " ) ;
318-
319- // TODO: do something else when testing, to help speed things up.
320- let output_clone = std:: process:: Command :: new ( "git" )
321- . args ( [
322- "clone" ,
323- self . to_repo ( ) . as_ref ( ) ,
324- self . to_dirname ( ) ?. to_string_lossy ( ) . as_ref ( ) ,
325- ] )
326- . output ( ) ?;
327-
328- anyhow:: ensure!(
329- output_clone. status. success( ) ,
330- "couldn't clone `rust-gpu` {} to {}\n {}" ,
331- self . to_repo( ) ,
332- self . to_dirname( ) ?. to_string_lossy( ) ,
333- String :: from_utf8_lossy( & output_clone. stderr)
334- ) ;
335-
336- Ok ( ( ) )
337- }
338230}
339231
340232#[ cfg( test) ]
@@ -344,7 +236,8 @@ mod test {
344236 #[ test_log:: test]
345237 fn parsing_spirv_std_dep_for_shader_template ( ) {
346238 let shader_template_path = crate :: test:: shader_crate_template_path ( ) ;
347- let source = SpirvSource :: get_spirv_std_dep_definition ( & shader_template_path) . unwrap ( ) ;
239+ let ( source, _) =
240+ SpirvSource :: get_rust_gpu_deps_from_shader ( & shader_template_path) . unwrap ( ) ;
348241 assert_eq ! (
349242 source,
350243 SpirvSource :: Git {
0 commit comments