@@ -7,7 +7,7 @@ use std::{
77 fs:: { File , FileType } ,
88 io:: { Read , Write } ,
99 path:: { Path , PathBuf } ,
10- process:: ExitStatus ,
10+ process:: { Command , ExitStatus } ,
1111 str:: FromStr ,
1212 sync:: {
1313 atomic:: { AtomicBool , Ordering } ,
@@ -20,7 +20,6 @@ use std::{
2020use anyhow:: Context ;
2121#[ cfg( target_os = "linux" ) ]
2222use heck:: ToKebabCase ;
23- use log:: warn;
2423use log:: { debug, info} ;
2524use notify:: { watcher, DebouncedEvent , RecursiveMode , Watcher } ;
2625use serde:: Deserialize ;
@@ -287,7 +286,7 @@ impl Rust {
287286 let process = Arc :: new ( Mutex :: new ( child) ) ;
288287 let ( tx, rx) = channel ( ) ;
289288 let tauri_path = tauri_dir ( ) ;
290- let workspace_path = get_workspace_dir ( & tauri_path ) ;
289+ let workspace_path = get_workspace_dir ( ) ? ;
291290
292291 let watch_folders = if tauri_path == workspace_path {
293292 vec ! [ tauri_path]
@@ -423,17 +422,6 @@ impl CargoSettings {
423422 }
424423}
425424
426- #[ derive( Deserialize ) ]
427- struct CargoBuildConfig {
428- #[ serde( rename = "target-dir" ) ]
429- target_dir : Option < String > ,
430- }
431-
432- #[ derive( Deserialize ) ]
433- struct CargoConfig {
434- build : Option < CargoBuildConfig > ,
435- }
436-
437425pub struct RustAppSettings {
438426 manifest : Manifest ,
439427 cargo_settings : CargoSettings ,
@@ -639,100 +627,55 @@ impl RustAppSettings {
639627 }
640628
641629 pub fn out_dir ( & self , target : Option < String > , debug : bool ) -> crate :: Result < PathBuf > {
642- let tauri_dir = tauri_dir ( ) ;
643- let workspace_dir = get_workspace_dir ( & tauri_dir) ;
644- get_target_dir ( & workspace_dir, target, !debug)
630+ get_target_dir ( target, !debug)
631+ }
632+ }
633+
634+ #[ derive( Deserialize ) ]
635+ struct CargoMetadata {
636+ target_directory : PathBuf ,
637+ workspace_root : PathBuf ,
638+ }
639+
640+ fn get_cargo_metadata ( ) -> crate :: Result < CargoMetadata > {
641+ let output = Command :: new ( "cargo" )
642+ . args ( [ "metadata" , "--no-deps" , "--format-version" , "1" ] )
643+ . current_dir ( tauri_dir ( ) )
644+ . output ( ) ?;
645+
646+ if !output. status . success ( ) {
647+ return Err ( anyhow:: anyhow!(
648+ "cargo metadata command exited with a non zero exit code: {}" ,
649+ String :: from_utf8( output. stderr) ?
650+ ) ) ;
645651 }
652+
653+ Ok ( serde_json:: from_slice ( & output. stdout ) ?)
646654}
647655
648- /// This function determines where 'target' dir is and suffixes it with 'release' or 'debug'
656+ /// This function determines the 'target' directory and suffixes it with 'release' or 'debug'
649657/// to determine where the compiled binary will be located.
650- fn get_target_dir (
651- project_root_dir : & Path ,
652- target : Option < String > ,
653- is_release : bool ,
654- ) -> crate :: Result < PathBuf > {
655- let mut path: PathBuf = match std:: env:: var_os ( "CARGO_TARGET_DIR" ) {
656- Some ( target_dir) => target_dir. into ( ) ,
657- None => {
658- let mut root_dir = project_root_dir. to_path_buf ( ) ;
659- let target_path: Option < PathBuf > = loop {
660- // cargo reads configs under .cargo/config.toml or .cargo/config
661- let mut cargo_config_path = root_dir. join ( ".cargo/config" ) ;
662- if !cargo_config_path. exists ( ) {
663- cargo_config_path = root_dir. join ( ".cargo/config.toml" ) ;
664- }
665- // if the path exists, parse it
666- if cargo_config_path. exists ( ) {
667- let mut config_str = String :: new ( ) ;
668- let mut config_file = File :: open ( & cargo_config_path)
669- . with_context ( || format ! ( "failed to open {:?}" , cargo_config_path) ) ?;
670- config_file
671- . read_to_string ( & mut config_str)
672- . with_context ( || "failed to read cargo config file" ) ?;
673- let config: CargoConfig =
674- toml:: from_str ( & config_str) . with_context ( || "failed to parse cargo config file" ) ?;
675- if let Some ( build) = config. build {
676- if let Some ( target_dir) = build. target_dir {
677- break Some ( target_dir. into ( ) ) ;
678- }
679- }
680- }
681- if !root_dir. pop ( ) {
682- break None ;
683- }
684- } ;
685- target_path. unwrap_or_else ( || project_root_dir. join ( "target" ) )
686- }
687- } ;
658+ fn get_target_dir ( target : Option < String > , is_release : bool ) -> crate :: Result < PathBuf > {
659+ let mut path = get_cargo_metadata ( )
660+ . with_context ( || "failed to get cargo metadata" ) ?
661+ . target_directory ;
688662
689663 if let Some ( ref triple) = target {
690664 path. push ( triple) ;
691665 }
666+
692667 path. push ( if is_release { "release" } else { "debug" } ) ;
668+
693669 Ok ( path)
694670}
695671
696- /// Walks up the file system, looking for a Cargo.toml file
697- /// If one is found before reaching the root, then the current_dir's package belongs to that parent workspace if it's listed on [workspace.members].
698- ///
699- /// If this package is part of a workspace, returns the path to the workspace directory
700- /// Otherwise returns the current directory.
701- pub fn get_workspace_dir ( current_dir : & Path ) -> PathBuf {
702- let mut dir = current_dir. to_path_buf ( ) ;
703- let project_path = dir. clone ( ) ;
704-
705- while dir. pop ( ) {
706- if dir. join ( "Cargo.toml" ) . exists ( ) {
707- match CargoSettings :: load ( & dir) {
708- Ok ( cargo_settings) => {
709- if let Some ( workspace_settings) = cargo_settings. workspace {
710- if let Some ( members) = workspace_settings. members {
711- if members. iter ( ) . any ( |member| {
712- glob:: glob ( & dir. join ( member) . to_string_lossy ( ) )
713- . unwrap ( )
714- . any ( |p| p. unwrap ( ) == project_path)
715- } ) {
716- return dir;
717- }
718- }
719- }
720- }
721- Err ( e) => {
722- warn ! (
723- "Found `{}`, which may define a parent workspace, but \
724- failed to parse it. If this is indeed a parent workspace, undefined behavior may occur: \
725- \n {:#}",
726- dir. display( ) ,
727- e
728- ) ;
729- }
730- }
731- }
732- }
733-
734- // Nothing found walking up the file system, return the starting directory
735- current_dir. to_path_buf ( )
672+ /// Executes `cargo metadata` to get the workspace directory.
673+ pub fn get_workspace_dir ( ) -> crate :: Result < PathBuf > {
674+ Ok (
675+ get_cargo_metadata ( )
676+ . with_context ( || "failed to get cargo metadata" ) ?
677+ . workspace_root ,
678+ )
736679}
737680
738681#[ allow( unused_variables) ]
0 commit comments