Skip to content

Commit cbc4f25

Browse files
committed
Added commitfestfilters to search
1 parent 9078b4d commit cbc4f25

File tree

13 files changed

+239
-6
lines changed

13 files changed

+239
-6
lines changed

app/services/search/query_builder.rb

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,8 @@ def apply_selector(node, relation)
123123
apply_last_date_selector(:>=, value, relation, negated: negated)
124124
when :last_before
125125
apply_last_date_selector(:<, value, relation, negated: negated)
126+
when :commitfest
127+
apply_commitfest_selector(value, relation, negated: negated, conditions: conditions)
126128
else
127129
@warnings << "Unknown selector: #{key}"
128130
relation
@@ -842,6 +844,53 @@ def apply_last_date_selector(operator, value, relation, negated:)
842844
relation.where("topics.last_message_at #{actual_operator} ?", date)
843845
end
844846

847+
def apply_commitfest_selector(value, relation, negated:, conditions:)
848+
relation = relation.left_joins(
849+
commitfest_patch_topics: {
850+
commitfest_patch: [
851+
:commitfest_tags,
852+
{ commitfest_patch_commitfests: :commitfest }
853+
]
854+
}
855+
)
856+
857+
if value.present?
858+
if negated
859+
relation = relation.where.not(commitfest: { name: value })
860+
else
861+
relation = relation.where(commitfest: { name: value })
862+
end
863+
end
864+
865+
apply_commitfest_with_conditions(relation, negated: negated, conditions: conditions || [])
866+
end
867+
868+
def apply_commitfest_with_conditions(relation, negated:, conditions:)
869+
conditions.each do |condition|
870+
value = condition[:value]
871+
872+
relation = case condition[:key]
873+
when :name
874+
column = Commitfest.arel_table[:name]
875+
apply_commitfest_filter(relation, column, value, negated:)
876+
when :status
877+
column = CommitfestPatchCommitfest.arel_table[:status]
878+
apply_commitfest_filter(relation, column, value, negated:)
879+
when :tag
880+
column = CommitfestTag.arel_table[:name]
881+
apply_commitfest_filter(relation, column, value, negated:)
882+
end
883+
end
884+
885+
relation
886+
end
887+
888+
def apply_commitfest_filter(relation, column, value, negated:)
889+
predicate = column.lower.eq(value.downcase)
890+
predicate = predicate.not if negated
891+
relation.where(predicate)
892+
end
893+
845894
# === Helpers ===
846895

847896
def sanitize_like(value)

app/services/search/query_parser.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ class Grammar < Parslet::Parser
4444
str("contributors") | str("participants") | str("messages") |
4545
str("unread") | str("reading") | str("read") | str("new") |
4646
str("starred") | str("notes") | str("tag") |
47-
str("has")
47+
str("has") | str("commitfest")
4848
).as(:selector_key)
4949
end
5050

@@ -60,7 +60,7 @@ class Grammar < Parslet::Parser
6060
str("first_after") | str("first_before") |
6161
str("added_after") | str("added_before") |
6262
str("messages") | str("count") | str("from") |
63-
str("body") | str("name")
63+
str("body") | str("name") | str("status") | str("tag")
6464
).as(:condition_key)
6565
end
6666

app/services/search/query_validator.rb

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,13 @@ class QueryValidator
2222

2323
TAG_SELECTORS = %i[tag].freeze
2424

25+
COMMITFEST_SELECTORS = %i[commitfest]
26+
2527
ALL_SELECTORS = (DATE_SELECTORS + COUNT_SELECTORS + AUTHOR_SELECTORS +
26-
STATE_SELECTORS + CONTENT_SELECTORS + TAG_SELECTORS + [ :has ]).freeze
28+
STATE_SELECTORS + CONTENT_SELECTORS + TAG_SELECTORS +
29+
COMMITFEST_SELECTORS + [ :has ]).freeze
2730

28-
HAS_VALUES = %w[attachment patch contributor committer core_team].freeze
31+
HAS_VALUES = %w[attachment patch contributor committer core_team commitfest].freeze
2932

3033
# Valid sub-conditions for each parent selector
3134
VALID_SUB_CONDITIONS = {
@@ -34,7 +37,8 @@ class QueryValidator
3437
attachment: %i[from count name],
3538
patch: %i[from count]
3639
},
37-
tag: %i[from added_before added_after]
40+
tag: %i[from added_before added_after],
41+
commitfest: %i[name status tag]
3842
}.freeze
3943

4044
# Sub-condition keywords that require date values
@@ -104,6 +108,8 @@ def validate_selector(node)
104108
validate_content_selector(node)
105109
when *TAG_SELECTORS
106110
validate_tag_selector(node)
111+
when *COMMITFEST_SELECTORS
112+
validate_commitfest_selector(node)
107113
when :has
108114
validate_has_selector(node)
109115
else
@@ -124,7 +130,7 @@ def validate_selector(node)
124130

125131
def supports_empty_value_with_conditions?(key, conditions)
126132
# tag: can have empty value with conditions (e.g., tag:[from:me])
127-
key == :tag && conditions.present?
133+
key.in?([ :tag, :commitfest ]) && conditions.present?
128134
end
129135

130136
def validate_conditions(parent_key, parent_value, conditions)
@@ -182,6 +188,8 @@ def get_valid_sub_conditions(parent_key, parent_value)
182188
has_conditions[normalized_value] || []
183189
when :tag
184190
VALID_SUB_CONDITIONS[:tag] || []
191+
when :commitfest
192+
VALID_SUB_CONDITIONS[:commitfest] || []
185193
else
186194
[]
187195
end
@@ -252,6 +260,10 @@ def validate_tag_selector(node)
252260
node
253261
end
254262

263+
def validate_commitfest_selector(node)
264+
node
265+
end
266+
255267
def validate_has_selector(node)
256268
value = node[:value].to_s.downcase
257269

app/views/help/pages/search.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,19 @@ last_after:1w # Topics with activity in the last week
105105
messages_before:yesterday # Messages sent before yesterday
106106
```
107107

108+
### Commitfest Selectors
109+
110+
Search for topics by commitfest.
111+
112+
113+
| Selector | Description | Example |
114+
|----------|-------------|---------|
115+
| `commitfest:name` | Topics from commitfest with this name | `commitfest:PG19-Final` |
116+
| `commitfest:[name:name]` | Topics from commitfest with this name | `commitfest:[name:PG19-Draft]` |
117+
| `commitfest:[status:status]` | Topics from commitfest with this status | `commitfest:[status:commited]` |
118+
| `commitfest:[tag:tag]` | Topics from commitfest with this tag | `commitfest:[tag:bugfix]` |
119+
120+
108121
### Count Selectors
109122

110123
| Selector | Description | Example |
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
FactoryBot.define do
2+
factory :commitfest_patch_commitfest do
3+
commitfest
4+
commitfest_patch
5+
6+
status { "Open" }
7+
end
8+
end
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
FactoryBot.define do
2+
factory :commitfest_patch_tag do
3+
end
4+
end
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
FactoryBot.define do
2+
factory :commitfest_patch_topic do
3+
commitfest_patch
4+
topic
5+
end
6+
end
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
FactoryBot.define do
2+
factory :commitfest_patch do
3+
sequence(:external_id)
4+
sequence(:title) { |n| "Patch Title ##{n}" }
5+
6+
trait :with_topic do
7+
transient { topic { create(:topic) } }
8+
after(:create) do |cp, ctx|
9+
create(:commitfest_patch_topic, commitfest_patch: cp, topic: ctx.topic)
10+
end
11+
end
12+
13+
trait :with_commitfest do
14+
transient { commitfest { create(:commitfest) } }
15+
after(:create) do |cp, ctx|
16+
create(:commitfest_patch_commitfest, commitfest_patch: cp, commitfest: ctx.commitfest)
17+
end
18+
end
19+
20+
trait :with_tag do
21+
transient { commitfest_tag { create(:commitfest_tag) } }
22+
after(:create) do |cp, ctx|
23+
create(:commitfest_patch_tag, commitfest_patch: cp, commitfest_tag: ctx.commitfest_tag)
24+
end
25+
end
26+
end
27+
end

spec/factories/commitfest_tags.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
FactoryBot.define do
2+
factory :commitfest_tag do
3+
name { "Bugfix" }
4+
end
5+
end

spec/factories/commitfests.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
FactoryBot.define do
2+
factory :commitfest do
3+
sequence(:external_id)
4+
sequence(:name) { |n| "PG#{n}-Final" }
5+
status { "Open" }
6+
start_date { 1.month.ago }
7+
end_date { 1.month.from_now }
8+
end
9+
end

0 commit comments

Comments
 (0)