@@ -24,7 +24,8 @@ use objdiff_core::{
2424 watcher:: { Watcher , create_watcher} ,
2525 } ,
2626 config:: {
27- ProjectConfig , ProjectObject , ProjectObjectMetadata , apply_project_options, build_globset,
27+ ProjectConfig , ProjectObject , ProjectObjectMetadata , ProjectOptions , apply_project_options,
28+ build_globset,
2829 path:: { check_path_buf, platform_path, platform_path_serde_option} ,
2930 } ,
3031 diff:: { DiffObjConfig , MappingConfig , ObjectDiff } ,
@@ -77,11 +78,11 @@ pub struct Args {
7778}
7879
7980pub fn run ( args : Args ) -> Result < ( ) > {
80- let ( target_path, base_path, project_config) =
81+ let ( target_path, base_path, project_config, unit_options ) =
8182 match ( & args. target , & args. base , & args. project , & args. unit ) {
8283 ( Some ( _) , Some ( _) , None , None )
8384 | ( Some ( _) , None , None , None )
84- | ( None , Some ( _) , None , None ) => ( args. target . clone ( ) , args. base . clone ( ) , None ) ,
85+ | ( None , Some ( _) , None , None ) => ( args. target . clone ( ) , args. base . clone ( ) , None , None ) ,
8586 ( None , None , p, u) => {
8687 let project = match p {
8788 Some ( project) => project. clone ( ) ,
@@ -106,36 +107,40 @@ pub fn run(args: Args) -> Result<()> {
106107 . base_dir
107108 . as_ref ( )
108109 . map ( |p| project. join ( p. with_platform_encoding ( ) ) ) ;
109- let objects = project_config
110- . units
110+ let units = project_config. units . as_deref ( ) . unwrap_or_default ( ) ;
111+ let objects = units
111112 . iter ( )
112- . flatten ( )
113- . map ( |o| {
114- ObjectConfig :: new (
115- o,
116- & project,
117- target_obj_dir. as_deref ( ) ,
118- base_obj_dir. as_deref ( ) ,
113+ . enumerate ( )
114+ . map ( |( idx, o) | {
115+ (
116+ ObjectConfig :: new (
117+ o,
118+ & project,
119+ target_obj_dir. as_deref ( ) ,
120+ base_obj_dir. as_deref ( ) ,
121+ ) ,
122+ idx,
119123 )
120124 } )
121125 . collect :: < Vec < _ > > ( ) ;
122- let object = if let Some ( u) = u {
126+ let ( object, unit_idx ) = if let Some ( u) = u {
123127 objects
124128 . iter ( )
125- . find ( |obj| obj. name == * u)
129+ . find ( |( obj, _) | obj. name == * u)
130+ . map ( |( obj, idx) | ( obj, * idx) )
126131 . ok_or_else ( || anyhow ! ( "Unit not found: {}" , u) ) ?
127132 } else if let Some ( symbol_name) = & args. symbol {
128133 let mut idx = None ;
129134 let mut count = 0usize ;
130- for ( i, obj) in objects. iter ( ) . enumerate ( ) {
135+ for ( i, ( obj, unit_idx ) ) in objects. iter ( ) . enumerate ( ) {
131136 if obj
132137 . target_path
133138 . as_deref ( )
134139 . map ( |o| obj:: read:: has_function ( o. as_ref ( ) , symbol_name) )
135140 . transpose ( ) ?
136141 . unwrap_or ( false )
137142 {
138- idx = Some ( i ) ;
143+ idx = Some ( ( i , * unit_idx ) ) ;
139144 count += 1 ;
140145 if count > 1 {
141146 break ;
@@ -144,7 +149,7 @@ pub fn run(args: Args) -> Result<()> {
144149 }
145150 match ( count, idx) {
146151 ( 0 , None ) => bail ! ( "Symbol not found: {}" , symbol_name) ,
147- ( 1 , Some ( i ) ) => & objects[ i] ,
152+ ( 1 , Some ( ( i , unit_idx ) ) ) => ( & objects[ i] . 0 , unit_idx ) ,
148153 ( 2 .., Some ( _) ) => bail ! (
149154 "Multiple instances of {} were found, try specifying a unit" ,
150155 symbol_name
@@ -154,24 +159,29 @@ pub fn run(args: Args) -> Result<()> {
154159 } else {
155160 bail ! ( "Must specify one of: symbol, project and unit, target and base objects" )
156161 } ;
162+ let unit_options = units. get ( unit_idx) . and_then ( |u| u. options ( ) . cloned ( ) ) ;
157163 let target_path = object. target_path . clone ( ) ;
158164 let base_path = object. base_path . clone ( ) ;
159- ( target_path, base_path, Some ( project_config) )
165+ ( target_path, base_path, Some ( project_config) , unit_options )
160166 }
161167 _ => bail ! ( "Either target and base or project and unit must be specified" ) ,
162168 } ;
163169
164- run_interactive ( args, target_path, base_path, project_config)
170+ run_interactive ( args, target_path, base_path, project_config, unit_options )
165171}
166172
167173fn build_config_from_args (
168174 args : & Args ,
169175 project_config : Option < & ProjectConfig > ,
176+ unit_options : Option < & ProjectOptions > ,
170177) -> Result < ( DiffObjConfig , MappingConfig ) > {
171178 let mut diff_config = DiffObjConfig :: default ( ) ;
172179 if let Some ( options) = project_config. and_then ( |config| config. options . as_ref ( ) ) {
173180 apply_project_options ( & mut diff_config, options) ?;
174181 }
182+ if let Some ( options) = unit_options {
183+ apply_project_options ( & mut diff_config, options) ?;
184+ }
175185 apply_config_args ( & mut diff_config, & args. config ) ?;
176186 let mut mapping_config = MappingConfig {
177187 mappings : Default :: default ( ) ,
@@ -322,11 +332,13 @@ fn run_interactive(
322332 target_path : Option < Utf8PlatformPathBuf > ,
323333 base_path : Option < Utf8PlatformPathBuf > ,
324334 project_config : Option < ProjectConfig > ,
335+ unit_options : Option < ProjectOptions > ,
325336) -> Result < ( ) > {
326337 let Some ( symbol_name) = & args. symbol else { bail ! ( "Interactive mode requires a symbol name" ) } ;
327338 let time_format = time:: format_description:: parse_borrowed :: < 2 > ( "[hour]:[minute]:[second]" )
328339 . context ( "Failed to parse time format" ) ?;
329- let ( diff_obj_config, mapping_config) = build_config_from_args ( & args, project_config. as_ref ( ) ) ?;
340+ let ( diff_obj_config, mapping_config) =
341+ build_config_from_args ( & args, project_config. as_ref ( ) , unit_options. as_ref ( ) ) ?;
330342 let mut state = AppState {
331343 jobs : Default :: default ( ) ,
332344 waker : Default :: default ( ) ,
0 commit comments