@@ -194,36 +194,22 @@ def reset(self) -> None:
194
194
self ._project_class .targets_reset ()
195
195
196
196
# noinspection PyProtectedMember
197
- def __lt__ (self , other : "Target" ):
198
- # print(self, "__lt__", other)
197
+ def should_run_before (self , other : "Target" ):
199
198
# if this target is one of the dependencies order it before
200
199
other_deps = other .project_class .cached_full_dependencies ()
201
200
# print("other deps:", other_deps)
202
201
if self in other_deps :
203
202
# print(self, "is in", other, "deps -> is less")
204
203
return True
205
204
# and if it is the other way around we are not less
206
- if other in self .project_class .cached_full_dependencies ():
205
+ self_deps = self .project_class .cached_full_dependencies ()
206
+ if other in self_deps :
207
207
# print(other, "is in", self, "deps -> is greater")
208
208
return False
209
- if other .name .startswith ("run" ) and not self .name .startswith ("run" ):
210
- return True # run must be executed last
211
- elif self .name .startswith ("run" ):
212
- return False
213
- if other .name .startswith ("disk-image" ) and not self .name .startswith ("disk-image" ):
214
- return True # disk-image should be done just before run
215
- elif self .name .startswith ("disk-image" ):
216
- return False
217
- # print(self, "is not in", other, "deps -> is not less")
218
- # otherwise just keep everything in order
219
- return False
220
- # This was previously done
221
- # ownDeps = self.project_class.all_dependency_names()
222
- # if len(ownDeps) < len(other_deps):
223
- # return True
224
- # if len(ownDeps) > len(other_deps):
225
- # return False
226
- # return self.name < other.name # not a dep and number of deps is the same -> compare name
209
+ # Run targets come last, preceded by disk-image targets. Otherwise the order is unspecified
210
+ self_order = (self .name .startswith ("run" ), self .name .startswith ("disk-image" ))
211
+ other_order = (other .name .startswith ("run" ), other .name .startswith ("disk-image" ))
212
+ return self_order < other_order
227
213
228
214
def __repr__ (self ) -> str :
229
215
return "<Target " + self .name + ">"
@@ -492,10 +478,20 @@ def get_target(
492
478
493
479
@staticmethod
494
480
def sort_in_dependency_order (targets : "typing.Iterable[Target]" ) -> "list[Target]" :
495
- # pythons sorted() is guaranteed to be stable:
496
- sorted_targets = list (sorted (targets ))
497
- # remove duplicates (insert into an orderdict to keep order
498
- return list (OrderedDict ((x , True ) for x in sorted_targets ).keys ())
481
+ # remove duplicates (insert into an orderdict to keep order)
482
+ result = list (OrderedDict ((x , True ) for x in targets ).keys ())
483
+ n = len (result )
484
+ if n <= 1 :
485
+ return result
486
+ for i in range (0 , n ):
487
+ tgt_i = result [i ]
488
+ for j in range (i + 1 , n ):
489
+ tgt_j = result [j ]
490
+ if tgt_j .should_run_before (tgt_i ):
491
+ assert not tgt_i .should_run_before (tgt_j ), "circular dependency found"
492
+ tgt_i = result .pop (j )
493
+ result .insert (i , tgt_i )
494
+ return result
499
495
500
496
def get_all_targets (self , explicit_targets : "list[Target]" , config : CheriConfig ) -> "list[Target]" :
501
497
chosen_targets : "list[Target]" = []
0 commit comments