@@ -19,6 +19,9 @@ Here are a few common filter examples which you might use in your configuration.
1919- ` !release.prerelease && !asset.source-code ` - Only include release artifacts which are not marked as pre-releases and are not source code archives.
2020- ` repo.name in ["git-tool", "grey"] ` - Only include repositories with the names "git-tool" or "grey".
2121- ` repo.stargazers >= 5 ` - Only include repositories with at least 5 stars.
22+ - ` repo.name like "*-backup" ` - Only include repositories whose name ends with "-backup" using glob pattern matching.
23+ - ` repo.name matches r"^awesome-\d+$" ` - Only include repositories whose name matches the given regular expression.
24+ - ` repo.pushed_at > now() - 30d ` - Only include repositories which have been pushed to within the last 30 days.
2225
2326## Language Features
2427### Properties - ` repo.<field> `
@@ -46,6 +49,12 @@ If you wish to treat an empty string as a valid value, you can use `repo.<field>
4649evaluation of an empty string.
4750:::
4851
52+ ::: tip
53+ You can also write * raw strings* using an ` r ` prefix (for example ` r"^v\d+$" ` ), within which backslashes are treated literally
54+ rather than as escape sequences. This is particularly convenient when writing [ regular expression] ( #pattern-matching-like-matches )
55+ patterns. Use the hashed form ` r#"..."# ` if your pattern needs to contain a double quote.
56+ :::
57+
4958#### Numbers
5059Numbers are represented internally as a 64-bit floating-point value, which means that they can represent most reasonably sized
5160integers as well as most reasonably precise decimal numbers. For example, ` 5 ` and ` 5.0 ` are equivalent in the filter language.
@@ -61,6 +70,18 @@ example, `repo.fork` will evaluate to `true` if the repository is a fork, and `f
6170The ` null ` value is used to represent the absence of a value, and is considered falsey when evaluated. Accessing a property which
6271does not exist will return ` null ` .
6372
73+ #### Datetimes and Durations
74+ Some fields, such as ` repo.pushed_at ` or ` release.published_at ` , expose native timestamps rather than strings. These can be compared
75+ against one another, and against the current time using the [ ` now() ` ] ( #functions ) function, allowing you to backup only those entities
76+ which have changed recently.
77+
78+ Durations are written as a number immediately followed by a unit (` ms ` , ` s ` , ` m ` for minutes, ` h ` , ` d ` , or ` w ` ), and several segments
79+ can be chained together to form a more precise duration, for example ` 1h30m ` . Datetimes and durations support ` + ` and ` - ` arithmetic,
80+ so ` now() - 7d ` evaluates to the point in time seven days ago.
81+
82+ - ` repo.pushed_at > now() - 30d ` - Only include repositories which have been pushed to within the last 30 days.
83+ - ` release.published_at < now() - 1w ` - Only include releases which were published more than a week ago.
84+
6485## Operators
6586### Unary Negation - ` ! `
6687The unary negation operator converts the following expression into the boolean opposite of its value.
@@ -102,8 +123,9 @@ comparison. These operators **DO NOT** perform type coercion, which means that y
102123type - for example, comparing ` 5 <= "5" || 5 >= "5" ` will always return ` false ` .
103124
104125::: warning
105- String comparisons are performed using a case-insensitive comparison of ASCII characters, which means that ` "Hello" == "hello" ` will return ` true ` ,
106- as will ` "hello👋" == "hello" ` .
126+ String comparisons are performed case-insensitively using the filter language's Unicode case-folding rules, which means that
127+ ` "Hello" == "hello" ` will return ` true ` , as will ` "STRASSE" == "straße" ` . If you need an exact, case-sensitive comparison, use the
128+ [ ` _cs ` variants] ( #case-sensitivity-cs ) of the string operators.
107129:::
108130
109131 - ` == ` - Returns ` true ` if the left and right hand expressions are equal.
@@ -136,6 +158,35 @@ The prefix and suffix matching operators are used to determine whether a string
136158 - ` "hello" startswith "he" ` - Determines whether the string ` hello ` starts with the sequence ` he ` , returning ` true ` in this case.
137159 - ` "goodbye" endswith "bye" ` - Determines whether the string ` goodbye ` ends with the sequence ` bye ` , returning ` true ` in this case.
138160
161+ ### Pattern Matching - ` like ` , ` matches `
162+ The pattern matching operators allow you to match a string against a pattern, which can be useful when you want to match
163+ repositories whose names follow a particular convention without listing each of them explicitly.
164+
165+ - ` like ` performs a case-insensitive [ glob] ( https://en.wikipedia.org/wiki/Glob_(programming) ) match, where ` * ` matches any
166+ sequence of characters (including none), ` ? ` matches exactly one character, and a backslash makes the following character
167+ literal (` \* ` , ` \? ` , ` \\ ` ). For example, ` repo.name like "*-rs" ` matches any repository whose name ends with ` -rs ` .
168+ - ` matches ` performs a [ regular expression] ( https://docs.rs/regex/latest/regex/#syntax ) match. Regular expressions are
169+ case-sensitive (use ` (?i) ` to ignore case) and unanchored (use ` ^ ` and ` $ ` to anchor the match). For example,
170+ ` release.tag matches r"^v\d+(\.\d+){2}$" ` matches tags like ` v1.2.3 ` .
171+
172+ ::: tip
173+ Regular expression patterns are easiest to write using [ raw strings] ( #strings ) (` r"..." ` ), which do not process backslash
174+ escape sequences and so avoid the need to double-escape characters like ` \d ` .
175+ :::
176+
177+ ### Case Sensitivity - ` _cs `
178+ The string operators (` contains ` , ` in ` , ` startswith ` , ` endswith ` , and ` like ` ) compare values case-insensitively by default. Each of
179+ them has a case-sensitive variant with a ` _cs ` suffix (` contains_cs ` , ` in_cs ` , ` startswith_cs ` , ` endswith_cs ` , and ` like_cs ` ) which
180+ compares strings exactly as written. The ` matches ` operator is always case-sensitive unless you opt in with the ` (?i) ` flag.
181+
182+ ## Functions
183+ Filters may call built-in functions using the familiar ` name(args...) ` syntax. Unknown function names and incorrect argument counts
184+ are rejected when the filter is parsed.
185+
186+ - ` now() ` - Returns the current UTC time, evaluated afresh on every evaluation. This is most useful in combination with
187+ [ durations] ( #datetimes-and-durations ) , for example ` repo.pushed_at > now() - 30d ` .
188+ - ` trim(string) ` - Returns the string argument with leading and trailing whitespace removed (` null ` for non-string values).
189+
139190## Nerdy Details
140191The filtering language itself is implemented as a simple recursive descent parser which compiles an expression
141192tree from the input string. This expression tree is then evaluated using an interpreter to determine whether
0 commit comments