This commit is contained in:
@@ -1,21 +0,0 @@
|
|||||||
name: Gitea Actions Demo
|
|
||||||
run-name: ${{ gitea.actor }} is testing out Gitea Actions 🚀
|
|
||||||
on: [push]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
Explore-Gitea-Actions:
|
|
||||||
runs-on: self-hosted
|
|
||||||
steps:
|
|
||||||
- run: echo "🎉 The job was automatically triggered by a ${{ gitea.event_name }} event."
|
|
||||||
- run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by Gitea!"
|
|
||||||
- run: echo "🔎 The name of your branch is ${{ gitea.ref }} and your repository is ${{ gitea.repository }}."
|
|
||||||
- run: echo "$PATH"
|
|
||||||
- run: node --version
|
|
||||||
- name: Check out repository code
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
- run: echo "💡 The ${{ gitea.repository }} repository has been cloned to the runner."
|
|
||||||
- run: echo "🖥️ The workflow is now ready to test your code on the runner."
|
|
||||||
- name: List files in the repository
|
|
||||||
run: |
|
|
||||||
ls ${{ gitea.workspace }}
|
|
||||||
- run: echo "🍏 This job's status is ${{ job.status }}."
|
|
||||||
10
.gitea/workflows/test.yaml
Normal file
10
.gitea/workflows/test.yaml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
name: Run tests
|
||||||
|
on: [push]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: self-hosted
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Run unit tests
|
||||||
|
run: poetry run python3 -m unittest
|
||||||
13
README.md
13
README.md
@@ -1,6 +1,8 @@
|
|||||||
# kpmatch - Path patterns
|
# kpmatch
|
||||||
|
|
||||||
## Features and limitations
|
A path matching library.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
* **Bash-style pathname patterns**
|
* **Bash-style pathname patterns**
|
||||||
* **Curly braces syntax:** `a{/b/c,bc}` expands into `a/b/c` and `abc`
|
* **Curly braces syntax:** `a{/b/c,bc}` expands into `a/b/c` and `abc`
|
||||||
@@ -8,12 +10,17 @@
|
|||||||
a path against the more specific patterns first
|
a path against the more specific patterns first
|
||||||
* **Pure paths:** This library does not access the filesystem. It does
|
* **Pure paths:** This library does not access the filesystem. It does
|
||||||
not check if a path exists and does not differentiate between files
|
not check if a path exists and does not differentiate between files
|
||||||
and directories.
|
and directories. If you need to search files, use Python's built-in
|
||||||
|
glob module or a library like [wcmatch](https://github.com/facelessuser/wcmatch).
|
||||||
* Ranges `[0-9]`, character classes `[:space:]` are
|
* Ranges `[0-9]`, character classes `[:space:]` are
|
||||||
not supported.
|
not supported.
|
||||||
* The extended operators `?(...)`, `*(...)`, `+(...)`, `@(...)`
|
* The extended operators `?(...)`, `*(...)`, `+(...)`, `@(...)`
|
||||||
and `!(...)` are not supported.
|
and `!(...)` are not supported.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Pattern Syntax
|
## Pattern Syntax
|
||||||
|
|
||||||
Braced sections `{ , }` are expanded.
|
Braced sections `{ , }` are expanded.
|
||||||
|
|||||||
@@ -73,8 +73,7 @@ class ParseTests(TestCase):
|
|||||||
m.EndOfSegment(),
|
m.EndOfSegment(),
|
||||||
m.AnySegments(),
|
m.AnySegments(),
|
||||||
m.AnyName(),
|
m.AnyName(),
|
||||||
m.FixedName("."),
|
m.FixedName(".def"),
|
||||||
m.FixedName("def"),
|
|
||||||
m.EndOfSegment(),
|
m.EndOfSegment(),
|
||||||
m.EndOfPath(),
|
m.EndOfPath(),
|
||||||
),
|
),
|
||||||
@@ -113,25 +112,19 @@ class ParseTests(TestCase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def test_parse_name_part(self):
|
def test_parse_name_part(self):
|
||||||
# name_part <- any_name / one_of / simple_name_part / ","
|
# name_part <- any_name / simple_name_part
|
||||||
self.assertTupleEqual(
|
self.assertTupleEqual(
|
||||||
p._parse_name_part("?a[bc],*{def,ghi}", 0), (m.AnyCharacter(), 1)
|
p._parse_name_part("?a[bc]*def", 0), (m.AnyCharacter(), 1)
|
||||||
)
|
)
|
||||||
self.assertTupleEqual(
|
self.assertTupleEqual(
|
||||||
p._parse_name_part("?a[bc],*{def,ghi}", 1), (m.FixedName("a"), 2)
|
p._parse_name_part("?a[bc]*def", 1), (m.FixedName("a"), 2)
|
||||||
)
|
)
|
||||||
self.assertTupleEqual(
|
self.assertTupleEqual(
|
||||||
p._parse_name_part("?a[bc],*{def,ghi}", 2), (m.CharacterSet("bc", False), 6)
|
p._parse_name_part("?a[bc]*def", 2), (m.CharacterSet("bc", False), 6)
|
||||||
)
|
)
|
||||||
|
self.assertTupleEqual(p._parse_name_part("?a[bc]*def", 6), (m.AnyName(), 7))
|
||||||
self.assertTupleEqual(
|
self.assertTupleEqual(
|
||||||
p._parse_name_part("?a[bc],*{def,ghi}", 6), (m.FixedName(","), 7)
|
p._parse_name_part("?a[bc]*def", 7), (m.FixedName("def"), 10)
|
||||||
)
|
|
||||||
self.assertTupleEqual(
|
|
||||||
p._parse_name_part("?a[bc],*{def,ghi}", 7), (m.AnyName(), 8)
|
|
||||||
)
|
|
||||||
self.assertTupleEqual(
|
|
||||||
p._parse_name_part("?a[bc],*def", 8),
|
|
||||||
(m.FixedName("def"), 17),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_parse_any_name(self):
|
def test_parse_any_name(self):
|
||||||
|
|||||||
Reference in New Issue
Block a user