Skip to content

Commit c8145e3

Browse files
authored
Merge pull request #9723 from gitbutlerapp/kv-branch-40
Crating or updating a rule now triggers rules to be evaluated
2 parents 7ac5ec5 + 06ff772 commit c8145e3

File tree

5 files changed

+42
-11
lines changed

5 files changed

+42
-11
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/but-rules/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ serde_regex = "1.1.0"
1919
serde_json = "1.0.138"
2020
gitbutler-command-context.workspace = true
2121
but-db.workspace = true
22+
but-core.workspace = true
2223
but-hunk-assignment.workspace = true
2324
but-graph.workspace = true
2425
but-workspace.workspace = true

crates/but-rules/src/handler.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use but_graph::VirtualBranchesTomlMetadata;
2-
use but_hunk_assignment::{HunkAssignment, WorktreeChanges, assign, assignments_to_requests};
2+
use but_hunk_assignment::{HunkAssignment, assign, assignments_to_requests};
33
use but_hunk_dependency::ui::HunkDependencies;
44
use but_workspace::{StackId, StacksFilter, ui::StackEntry};
55
use gitbutler_command_context::CommandContext;
@@ -8,9 +8,10 @@ use std::str::FromStr;
88

99
use crate::{Filter, StackTarget};
1010

11-
pub fn on_filesystem_change(
11+
pub fn process_workspace_rules(
1212
ctx: &mut CommandContext,
13-
worktree_changes: &WorktreeChanges,
13+
assignments: &[HunkAssignment],
14+
dependencies: &Option<HunkDependencies>,
1415
) -> anyhow::Result<usize> {
1516
let mut updates = 0;
1617
let rules = super::list_rules(ctx)?
@@ -43,7 +44,7 @@ pub fn on_filesystem_change(
4344
match rule.action {
4445
super::Action::Explicit(super::Operation::Assign { target }) => {
4546
if let Some(stack_id) = get_or_create_stack_id(ctx, target, &stacks_in_ws) {
46-
let assignments = matching(worktree_changes.clone(), rule.filters.clone())
47+
let assignments = matching(assignments, rule.filters.clone())
4748
.into_iter()
4849
.filter(|e| e.stack_id != Some(stack_id))
4950
.map(|mut e| {
@@ -52,8 +53,7 @@ pub fn on_filesystem_change(
5253
})
5354
.collect_vec();
5455
updates +=
55-
handle_assign(ctx, assignments, worktree_changes.dependencies.as_ref())
56-
.unwrap_or_default();
56+
handle_assign(ctx, assignments, dependencies.as_ref()).unwrap_or_default();
5757
}
5858
}
5959
_ => continue,
@@ -133,22 +133,22 @@ fn handle_assign(
133133
}
134134
}
135135

136-
fn matching(worktree_changes: WorktreeChanges, filters: Vec<Filter>) -> Vec<HunkAssignment> {
136+
fn matching(wt_assignments: &[HunkAssignment], filters: Vec<Filter>) -> Vec<HunkAssignment> {
137137
if filters.is_empty() {
138-
return worktree_changes.assignments;
138+
return wt_assignments.to_vec();
139139
}
140140
let mut assignments = Vec::new();
141141
for filter in filters {
142142
match filter {
143143
Filter::PathMatchesRegex(regex) => {
144-
for change in worktree_changes.assignments.iter() {
144+
for change in wt_assignments.iter() {
145145
if regex.is_match(&change.path) {
146146
assignments.push(change.clone());
147147
}
148148
}
149149
}
150150
Filter::ContentMatchesRegex(regex) => {
151-
for change in worktree_changes.assignments.iter() {
151+
for change in wt_assignments.iter() {
152152
if let Some(diff) = change.diff.clone() {
153153
let diff = diff.to_string();
154154
let matching_lines: Vec<&str> =

crates/but-rules/src/lib.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use but_hunk_dependency::ui::hunk_dependencies_for_workspace_changes_by_worktree_dir;
12
use gitbutler_command_context::CommandContext;
23
use serde::{Deserialize, Serialize};
34

@@ -156,6 +157,7 @@ pub fn create_rule(
156157
.workspace_rules()
157158
.insert(rule.clone().try_into()?)
158159
.map_err(|e| anyhow::anyhow!("Failed to insert workspace rule: {}", e))?;
160+
process_rules(ctx).ok(); // Reevaluate rules after creating
159161
Ok(rule)
160162
}
161163

@@ -213,6 +215,7 @@ pub fn update_rule(
213215
.workspace_rules()
214216
.update(&req.id, rule.clone().try_into()?)
215217
.map_err(|e| anyhow::anyhow!("Failed to update workspace rule: {}", e))?;
218+
process_rules(ctx).ok(); // Reevaluate rules after updating
216219
Ok(rule)
217220
}
218221

@@ -227,3 +230,25 @@ pub fn list_rules(ctx: &mut CommandContext) -> anyhow::Result<Vec<WorkspaceRule>
227230
.collect::<Result<Vec<WorkspaceRule>, _>>()?;
228231
Ok(rules)
229232
}
233+
234+
fn process_rules(ctx: &mut CommandContext) -> anyhow::Result<()> {
235+
let wt_changes = but_core::diff::worktree_changes(&ctx.gix_repo()?)?;
236+
237+
let dependencies = hunk_dependencies_for_workspace_changes_by_worktree_dir(
238+
ctx,
239+
&ctx.project().path,
240+
&ctx.project().gb_dir(),
241+
Some(wt_changes.changes.clone()),
242+
)?;
243+
244+
let (assignments, _) = but_hunk_assignment::assignments_with_fallback(
245+
ctx,
246+
false,
247+
Some(wt_changes.changes),
248+
Some(&dependencies),
249+
)
250+
.map_err(|e| anyhow::anyhow!("Failed to get assignments: {}", e))?;
251+
252+
handler::process_workspace_rules(ctx, &assignments, &Some(dependencies))?;
253+
Ok(())
254+
}

crates/gitbutler-watcher/src/handler.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,11 @@ impl Handler {
103103
.map(|err| serde_error::Error::new(&**err)),
104104
};
105105
if ctx.app_settings().feature_flags.rules {
106-
if let Ok(update_count) = but_rules::handler::on_filesystem_change(ctx, &changes) {
106+
if let Ok(update_count) = but_rules::handler::process_workspace_rules(
107+
ctx,
108+
&assignments,
109+
&dependencies.as_ref().ok().cloned(),
110+
) {
107111
if update_count > 0 {
108112
// Getting these again since they were updated
109113
let (assignments, assignments_error) =

0 commit comments

Comments
 (0)