@@ -39,9 +39,9 @@ pub type UnitKey = (PackageId, TargetKind);
39
39
/// Holds the information how exactly the build will be performed for a given
40
40
/// workspace with given, specified features.
41
41
pub struct Plan {
42
- // Stores a full Cargo `Unit` data for a first processed unit with a given key.
42
+ /// Stores a full Cargo `Unit` data for a first processed unit with a given key.
43
43
pub units : HashMap < UnitKey , OwnedUnit > ,
44
- // Main dependency graph between the simplified units.
44
+ /// Main dependency graph between the simplified units.
45
45
pub dep_graph : HashMap < UnitKey , HashSet < UnitKey > > ,
46
46
/// Reverse dependency graph that's used to construct a dirty compiler call queue.
47
47
pub rev_dep_graph : HashMap < UnitKey , HashSet < UnitKey > > ,
@@ -156,13 +156,17 @@ impl Plan {
156
156
if let Some ( unit) = build_scripts. get ( modified. as_ref ( ) ) {
157
157
result. insert ( unit. clone ( ) ) ;
158
158
} else {
159
- // It's not a build script, so we can check for path prefix now
160
- for ( unit, src_dir) in & other_targets {
161
- if modified. as_ref ( ) . starts_with ( src_dir) {
162
- trace ! ( "Adding {:?}, as a modified file {:?} starts with {:?}" , & unit, modified, src_dir) ;
163
- result. insert ( unit. clone ( ) ) ;
164
- }
165
- }
159
+ // Not a build script, so we associate a dirty package with a
160
+ // dirty file by finding longest (most specified) path prefix
161
+ let unit = other_targets. iter ( ) . max_by_key ( |& ( _, src_dir) | {
162
+ modified. as_ref ( ) . components ( ) . zip ( src_dir. components ( ) )
163
+ . take_while ( |& ( a, b) | a == b)
164
+ . count ( )
165
+ } ) ;
166
+ match unit {
167
+ None => trace ! ( "Modified file {:?} doesn't correspond to any package!" , modified) ,
168
+ Some ( unit) => { result. insert ( unit. 0 . clone ( ) ) ; } ,
169
+ } ;
166
170
}
167
171
}
168
172
result
0 commit comments