about summary refs log tree commit diff
diff options
context:
space:
mode:
authoronur-ozkan <work@onurozkan.dev>2024-07-16 18:42:19 +0300
committeronur-ozkan <work@onurozkan.dev>2024-07-17 12:37:36 +0300
commit4ad753af915840ca9de07dd2df80419b57136872 (patch)
tree7473aedcf2027a07b8ccb1b083cc6f1f9b209220
parente1f45a1442bb373429b6b0838e8ef806ddddfeef (diff)
maintain the given order on step execution
Previously step execution disregarded the CLI order and this change executes the given
steps in the order specified on CLI.

For example, running `x $kind a b c` will execute `$kind` step for `a`, then `b`, then `c` crates
in the specified order.

Signed-off-by: onur-ozkan <work@onurozkan.dev>
-rw-r--r--src/bootstrap/src/core/builder.rs34
1 files changed, 33 insertions, 1 deletions
diff --git a/src/bootstrap/src/core/builder.rs b/src/bootstrap/src/core/builder.rs
index 65cc1fa7478..6a1399f8116 100644
--- a/src/bootstrap/src/core/builder.rs
+++ b/src/bootstrap/src/core/builder.rs
@@ -473,9 +473,41 @@ impl StepDescription {
             return;
         }
 
-        // Handle all PathSets.
+        let mut path_lookup: Vec<(PathBuf, bool)> =
+            paths.clone().into_iter().map(|p| (p, false)).collect();
+
+        // List of `(usize, &StepDescription, Vec<PathSet>)` where `usize` is the closest index of a path
+        // compared to the given CLI paths. So we can respect to the CLI order by using this value to sort
+        // the steps.
+        let mut steps_to_run = vec![];
+
         for (desc, should_run) in v.iter().zip(&should_runs) {
             let pathsets = should_run.pathset_for_paths_removing_matches(&mut paths, desc.kind);
+
+            // This value is used for sorting the step execution order.
+            // By default, `usize::MAX` is used as the index for steps to assign them the lowest priority.
+            //
+            // If we resolve the step's path from the given CLI input, this value will be updated with
+            // the step's actual index.
+            let mut closest_index = usize::MAX;
+
+            // Find the closest index from the original list of paths given by the CLI input.
+            for (index, (path, is_used)) in path_lookup.iter_mut().enumerate() {
+                if !*is_used && !paths.contains(path) {
+                    closest_index = index;
+                    *is_used = true;
+                    break;
+                }
+            }
+
+            steps_to_run.push((closest_index, desc, pathsets));
+        }
+
+        // Sort the steps before running them to respect the CLI order.
+        steps_to_run.sort_by_key(|(index, _, _)| *index);
+
+        // Handle all PathSets.
+        for (_index, desc, pathsets) in steps_to_run {
             if !pathsets.is_empty() {
                 desc.maybe_run(builder, pathsets);
             }