feat: advanced pattern matching support (#1260)
This commit is contained in:
@@ -170,9 +170,25 @@ metadata.plugin = async function({__plugins, __templates, name, logger}) {
|
|||||||
logger(`metrics/inputs > failed to decode uri : ${value}`)
|
logger(`metrics/inputs > failed to decode uri : ${value}`)
|
||||||
value = defaulted
|
value = defaulted
|
||||||
}
|
}
|
||||||
const separators = {"comma-separated": ",", "space-separated": " "}
|
const separators = {"comma-separated": ",", "space-separated": " ", "newline-separated": "\n"}
|
||||||
const separator = separators[[format].flat().filter(s => s in separators)[0]] ?? ","
|
const formats = [format, "comma-separated"].flat(Infinity).filter(s => s in separators)
|
||||||
return value.split(separator).map(v => replacer(v).toLocaleLowerCase()).filter(v => Array.isArray(values) ? values.includes(v) : true).filter(v => v)
|
let parsed = [], used = "comma-separated"
|
||||||
|
for (const separation of formats) {
|
||||||
|
parsed = value
|
||||||
|
.split(separators[separation])
|
||||||
|
.map(v => replacer(v).toLocaleLowerCase())
|
||||||
|
.filter(v => Array.isArray(values) ? values.includes(v) : true)
|
||||||
|
.filter(v => v)
|
||||||
|
//Conditional below serves as auto-detection when multiple formats are provided
|
||||||
|
//To force a specific format one should use the separator as the first character
|
||||||
|
//so that the parsed.length is greater than 1 (empty values are filtered anyways)
|
||||||
|
if (parsed.length > 1) {
|
||||||
|
used = separation
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
logger(`metrics/inputs > used ${used} format to decode ${value}`)
|
||||||
|
return parsed
|
||||||
}
|
}
|
||||||
//String
|
//String
|
||||||
case "string": {
|
case "string": {
|
||||||
@@ -625,7 +641,7 @@ metadata.to = {
|
|||||||
yaml(key, {name = ""} = {}) {
|
yaml(key, {name = ""} = {}) {
|
||||||
const parts = []
|
const parts = []
|
||||||
if (key !== "enabled")
|
if (key !== "enabled")
|
||||||
parts.unshift(key.replaceAll(".", "_"))
|
parts.unshift(key.replace(/\./g, "_"))
|
||||||
if (name)
|
if (name)
|
||||||
parts.unshift((name === "base") ? name : `plugin_${name}`)
|
parts.unshift((name === "base") ? name : `plugin_${name}`)
|
||||||
return parts.join("_")
|
return parts.join("_")
|
||||||
|
|||||||
@@ -391,9 +391,36 @@ export const filters = {
|
|||||||
}
|
}
|
||||||
user = (user ?? repository.split("/")[0]).toLocaleLowerCase()
|
user = (user ?? repository.split("/")[0]).toLocaleLowerCase()
|
||||||
repo = (repo ?? repository.split("/")[1]).toLocaleLowerCase()
|
repo = (repo ?? repository.split("/")[1]).toLocaleLowerCase()
|
||||||
|
const handle = `${user}/${repo}`
|
||||||
|
|
||||||
|
let include = true
|
||||||
|
//Advanced pattern matching
|
||||||
|
if (patterns[0] === "@use.patterns") {
|
||||||
|
if (debug)
|
||||||
|
console.debug(`metrics/filters/repo > ${repo} > using advanced pattern matching`)
|
||||||
|
const options = {nocase:true}
|
||||||
|
for (let pattern of patterns) {
|
||||||
|
if (pattern.startsWith("#"))
|
||||||
|
continue
|
||||||
|
let action = false
|
||||||
|
if ((pattern.startsWith("+"))||(pattern.startsWith("-"))) {
|
||||||
|
action = pattern.charAt(0) === "+"
|
||||||
|
pattern = pattern.substring(1)
|
||||||
|
}
|
||||||
|
if (minimatch(handle, pattern, options)) {
|
||||||
|
if (debug)
|
||||||
|
console.debug(`metrics/filters/repo > ${repo} matches ${action ? "including" : "excluding"} pattern ${pattern}`)
|
||||||
|
include = action
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
//Basic pattern matching
|
//Basic pattern matching
|
||||||
const include = (!patterns.includes(repo)) && (!patterns.includes(`${user}/${repo}`))
|
else {
|
||||||
|
if (debug)
|
||||||
|
console.debug(`metrics/filters/repo > ${repo} > using basic pattern matching`)
|
||||||
|
include = (!patterns.includes(repo)) && (!patterns.includes(handle))
|
||||||
|
}
|
||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
console.debug(`metrics/filters/repo > filter ${repo} (${include ? "included" : "excluded"})`)
|
console.debug(`metrics/filters/repo > filter ${repo} (${include ? "included" : "excluded"})`)
|
||||||
return include
|
return include
|
||||||
|
|||||||
@@ -65,7 +65,9 @@ inputs:
|
|||||||
description: |
|
description: |
|
||||||
Skipped repositories
|
Skipped repositories
|
||||||
type: array
|
type: array
|
||||||
format: comma-separated
|
format:
|
||||||
|
- newline-separated
|
||||||
|
- comma-separated
|
||||||
default: ""
|
default: ""
|
||||||
example: my-repo-1, my-repo-2, owner/repo-3, ...
|
example: my-repo-1, my-repo-2, owner/repo-3, ...
|
||||||
inherits: repositories_skipped
|
inherits: repositories_skipped
|
||||||
|
|||||||
@@ -115,7 +115,9 @@ inputs:
|
|||||||
description: |
|
description: |
|
||||||
Default skipped repositories
|
Default skipped repositories
|
||||||
type: array
|
type: array
|
||||||
format: comma-separated
|
format:
|
||||||
|
- newline-separated
|
||||||
|
- comma-separated
|
||||||
default: ""
|
default: ""
|
||||||
example: my-repo-1, my-repo-2, owner/repo-3, ...
|
example: my-repo-1, my-repo-2, owner/repo-3, ...
|
||||||
global: yes
|
global: yes
|
||||||
|
|||||||
@@ -62,7 +62,9 @@ inputs:
|
|||||||
description: |
|
description: |
|
||||||
Skipped repositories
|
Skipped repositories
|
||||||
type: array
|
type: array
|
||||||
format: comma-separated
|
format:
|
||||||
|
- newline-separated
|
||||||
|
- comma-separated
|
||||||
default: ""
|
default: ""
|
||||||
example: my-repo-1, my-repo-2, owner/repo-3, ...
|
example: my-repo-1, my-repo-2, owner/repo-3, ...
|
||||||
inherits: repositories_skipped
|
inherits: repositories_skipped
|
||||||
|
|||||||
@@ -57,6 +57,60 @@ Content can be manually ordered using `config_order` option.
|
|||||||
> ℹ️ The handles to use for each plugin and sections is based on the [`partials/_.json`](/source/templates/classic/partials/_.json) of the template.
|
> ℹ️ The handles to use for each plugin and sections is based on the [`partials/_.json`](/source/templates/classic/partials/_.json) of the template.
|
||||||
> It may not necessarily be the plugin id (e.g. `base.header`, `base.activity+community`, `base.repositories`, etc.).
|
> It may not necessarily be the plugin id (e.g. `base.header`, `base.activity+community`, `base.repositories`, etc.).
|
||||||
|
|
||||||
|
## 🔕 Skipping repositories in plugins
|
||||||
|
|
||||||
|
Some plugins support a `plugin_*_skipped` option which is used to skipped repositories from result. It inherits the global option [`repositories_skipped`](/source/plugins/base/README.md#repositories_skipped) which makes it easier to ignore repositories from all plugins at once.
|
||||||
|
|
||||||
|
These options support two different syntaxes:
|
||||||
|
|
||||||
|
### Basic pattern matching
|
||||||
|
|
||||||
|
Skip repositories by:
|
||||||
|
- using their full handle (e.g. `user/repo`)
|
||||||
|
- using only their name (e.g. `repo`)
|
||||||
|
- *in this case, the owner may be implicitly set to current `user` option*
|
||||||
|
|
||||||
|
*Example: skipping repositories with basic pattern matching*
|
||||||
|
```yml
|
||||||
|
repositories_skipped: my-repo, user/my-repo
|
||||||
|
```
|
||||||
|
|
||||||
|
> 💡 Either comma or newlines can be used to separate basic patterns
|
||||||
|
|
||||||
|
### Advanced pattern matching
|
||||||
|
|
||||||
|
To enable advanced pattern matching to skip repositories, include `@use.patterns` at the beginning of the option value.
|
||||||
|
|
||||||
|
Skip repositories by writing file-glob patterns, with any of the supported operation:
|
||||||
|
- `#` to write comments
|
||||||
|
- `-` to exclude repositories
|
||||||
|
- *the `-` is implicit and may be omitted from excluding patterns*
|
||||||
|
- `+` to include back repositories
|
||||||
|
|
||||||
|
> ℹ️ *metrics* use [isaacs/minimatch](https://github.com/isaacs/minimatch) as its file-glob matcher
|
||||||
|
|
||||||
|
*Example: skipping repositories with basic advanced matching*
|
||||||
|
```yml
|
||||||
|
repositories_skipped: |
|
||||||
|
@use.patterns
|
||||||
|
|
||||||
|
# Skip a specific repository (both patterns are equivalent)
|
||||||
|
user/repo
|
||||||
|
-user/repo
|
||||||
|
|
||||||
|
# Skip repositories matching a given pattern
|
||||||
|
user/repo-*
|
||||||
|
{user1, user2, user3}/*
|
||||||
|
|
||||||
|
# Include back a previously skipped repository
|
||||||
|
org/repo
|
||||||
|
+org/include-this-repo
|
||||||
|
```
|
||||||
|
|
||||||
|
> ℹ️ Unlike basic pattern matching, patterns are always tested against the full repository handle (the user will not be implicitly added)
|
||||||
|
|
||||||
|
> ⚠️ As patterns may contain commas, be sure to use newlines rather than commas as separator to ensure patterns are correctly parsed
|
||||||
|
|
||||||
## 🪛 Using presets
|
## 🪛 Using presets
|
||||||
|
|
||||||
It is possible to reuse the same configuration across different repositories and workflows using configuration presets.
|
It is possible to reuse the same configuration across different repositories and workflows using configuration presets.
|
||||||
|
|||||||
@@ -138,8 +138,7 @@ inputs:
|
|||||||
Some templates may not support all options
|
Some templates may not support all options
|
||||||
type: array
|
type: array
|
||||||
default: css, xml
|
default: css, xml
|
||||||
format:
|
format: comma-separated
|
||||||
- comma-separated
|
|
||||||
values:
|
values:
|
||||||
- css
|
- css
|
||||||
- xml
|
- xml
|
||||||
|
|||||||
@@ -33,7 +33,9 @@ inputs:
|
|||||||
description: |
|
description: |
|
||||||
Skipped repositories
|
Skipped repositories
|
||||||
type: array
|
type: array
|
||||||
format: comma-separated
|
format:
|
||||||
|
- newline-separated
|
||||||
|
- comma-separated
|
||||||
default: ""
|
default: ""
|
||||||
example: my-repo-1, my-repo-2, owner/repo-3, ...
|
example: my-repo-1, my-repo-2, owner/repo-3, ...
|
||||||
inherits: repositories_skipped
|
inherits: repositories_skipped
|
||||||
|
|||||||
@@ -34,7 +34,9 @@ inputs:
|
|||||||
description: |
|
description: |
|
||||||
Skipped repositories
|
Skipped repositories
|
||||||
type: array
|
type: array
|
||||||
format: comma-separated
|
format:
|
||||||
|
- newline-separated
|
||||||
|
- comma-separated
|
||||||
default: ""
|
default: ""
|
||||||
example: my-repo-1, my-repo-2, owner/repo-3, ...
|
example: my-repo-1, my-repo-2, owner/repo-3, ...
|
||||||
inherits: repositories_skipped
|
inherits: repositories_skipped
|
||||||
|
|||||||
@@ -24,7 +24,9 @@ inputs:
|
|||||||
description: |
|
description: |
|
||||||
Skipped repositories
|
Skipped repositories
|
||||||
type: array
|
type: array
|
||||||
format: comma-separated
|
format:
|
||||||
|
- newline-separated
|
||||||
|
- comma-separated
|
||||||
default: ""
|
default: ""
|
||||||
example: my-repo-1, my-repo-2, owner/repo-3, ...
|
example: my-repo-1, my-repo-2, owner/repo-3, ...
|
||||||
inherits: repositories_skipped
|
inherits: repositories_skipped
|
||||||
|
|||||||
@@ -35,7 +35,9 @@ inputs:
|
|||||||
description: |
|
description: |
|
||||||
Skipped repositories
|
Skipped repositories
|
||||||
type: array
|
type: array
|
||||||
format: comma-separated
|
format:
|
||||||
|
- newline-separated
|
||||||
|
- comma-separated
|
||||||
default: ""
|
default: ""
|
||||||
example: my-repo-1, my-repo-2, owner/repo-3, ...
|
example: my-repo-1, my-repo-2, owner/repo-3, ...
|
||||||
inherits: repositories_skipped
|
inherits: repositories_skipped
|
||||||
|
|||||||
@@ -23,7 +23,9 @@ inputs:
|
|||||||
description: |
|
description: |
|
||||||
Skipped repositories
|
Skipped repositories
|
||||||
type: array
|
type: array
|
||||||
format: comma-separated
|
format:
|
||||||
|
- newline-separated
|
||||||
|
- comma-separated
|
||||||
default: ""
|
default: ""
|
||||||
example: my-repo-1, my-repo-2, owner/repo-3, ...
|
example: my-repo-1, my-repo-2, owner/repo-3, ...
|
||||||
inherits: repositories_skipped
|
inherits: repositories_skipped
|
||||||
|
|||||||
Reference in New Issue
Block a user