fls


Namefls JSON
Version 0.0.1.241224 PyPI version JSON
download
home_pagehttps://github.com/codyverse/fls
SummaryFLS: A module for matching file system paths against patterns.
upload_time2024-12-24 13:40:51
maintainerNone
docs_urlNone
authorAndrii Burkatskyi aka andr11b
requires_python>=3.8
licenseMIT
keywords file matching file filter file patterns pattern matching ignore files file list path filtering file selection gitignore dockerignore
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # File List Sieve

## What is it?

**File List Sieve** or simply **FLS** is a Python module for matching file system paths against patterns.

This functionality closely resembles the behavior of `.gitignore` and `.dockerignore`, making it intuitive for developers familiar with those systems. But unlike the mentioned systems, it allows you to choose what exactly you match files for - to ignore or to process.

**FLS** provides a flexible way to configure match rules for any project structure by using a custom rule file (e.g., `.fls`) to determine which files and directories should be processed. The system supports features like:
* Nested directories with inherited rules.
* Pattern negation using `!`.
* Wildcard matching for patterns (`*`, `?`, `**`, `[abc]`, etc.).


## Possible Use Cases

- **Ignoring Temporary Files**: In projects where temporary files or directories are created (e.g., during compilation or testing), FLS can be used to ignore these files when creating archives or versions.
- **Selective File Processing**: If a project contains files that need to be processed but not all files, FLS allows you to precisely define which files to include and which to ignore based on patterns.
- **Release Optimization**: When preparing a project for release, unnecessary files (e.g., logs, temporary files, or other auxiliary data) can be automatically excluded.
- **Working with Large Codebases**: In large projects with many subdirectories and files, FLS allows you to easily create and maintain rules for selective file handling.

## Syntax

As mentioned above the `.fls` rule files are similar to the well-known `.dockerignore` or `.gitignore` files, with some minore differences. Like these systems, rules are defined by specifying paths to files and directories in `.fls` files, which can be placed at any nesting level.

### Key differences and behavior

* **Context awareness**:

    In `.gitignore`, patterns like an asterisk `*` or a simple one such as `foo` match every file and directory, regardless of how deeply they are nested. However, in `.fls`, the same rules only match files and directories located in the current directory. In `.fls`, all patterns are **relative to the location of the `.fls` file**, and this location is referred to as the context of a rule (or pattern). 
    Patterns can also explicitly define deeper levels; for example, `foo/bar` will match `bar` inside a directory named `foo` within the current context.

* **No leading slash (`/`) anchoring**:

    Unlike `.gitignore`, `.fls` does not use leading slashes to anchor patterns to the root. Patterns like `/foo` or `/bar/` are treated identically to `foo` or `bar/`.

* **Trailing slash (`/`) for directories**:

    A trailing slash (`/`) specifically matches directories only. For example:

    - `foo/` matches a directory named `foo` but does not match `foo/bar`.
    - `foo` matches both a file or directory named `foo`.

* **Non-greedy directory matching**:

    Directory matches are *non-greedy*, meaning they do not extend to the content of the directory unless explicitly specified. For instance:

    - `foo/` matches only the foo directory.
    - `foo/**` matches `foo` and all its contents.

### Wildcards (globbing patterns)

Standard wildcards, also known as globbing patterns, are used for working with multiple files. Globbing is the process of expanding a wildcard pattern into a list of pathnames that match it. A string qualifies as a wildcard pattern if it includes any of the characters `?`, `*`, or `[`.

- A hash (`#`) signifies a comment. Lines starting with `#` are ignored.
    ```
    # This is just a comment.
    ```
- A backslash (`\`) is used as an escape character to treat a special character literally.
    ```
    # The pattern below will match a file named "#.txt"
    \#.txt
    ```
- An asterisk (`*`) matches zero or more characters of any kind, excluding a slash (`/`).
    ```
    # This pattern would match "`foobar`", "`foooobar`", and anything that
    # starts with `foo` also including "`foo`" itself.
    foo*
    ```
- An exclamation mark (`!`) indicates an exception. It is used to exclude specific files or directories from being matched by previous patterns.
    ```
    # This ruleset matches all files ending with `.txt` but excludes
    # `important.txt` from the match.
    *.txt
    !important.txt
    ```
- A question mark (`?`) matches exactly one character, excluding a slash (`/`).
    ```
    # This pattern matches `hda`, `hdb`, `hdc`, and any other one-character
    # variation, excluding slashes (`/`).
    hd?
    ```
- A double asterisk (`**`) matches zero or more files and directories, including their contents, recursively.
    ```
    # This will match all `.txt` files in any directory or subdirectory.
    **/*.txt
    ```
- Square brackets (`[]`) specify a set or range of characters with an logical `OR` relationship, where any character within the brackets can match. Standard ranges include [0-9], [a-z], and [A-Z]. You can define subsets like `[0-4]` or `[a-d]`, combine ranges (e.g., `[0-9a-f]`), or mix ranges and individual characters (e.g., `[024abcXYZ]`).
    ```
    # The next pattern matches `mam`, `mum`, or `mom`.
    m[aou]m

    # The next pattern matches `mam`, `mbm`, `mcm`, or `mdm`.
    m[a-d]m
    ```
- `[!]` works as a logical `NOT`, inverting the character set specified in square brackets (`[]`). Unlike `[]`, which matches any character listed inside, `[!]` matches any character not listed between the brackets.
    ```
    # The following pattern will match files starting with `file` that are
    # followed by characters other than digits (e.g., `files`, `fileA`), but
    # it will exclude files like `file0`, `file4` (those with digits `0-9`).
    file[!0-9]
    ```

### Rule explanation

|           Pattern           |             Example matches             | Explanation |
| ---- | --------------- | ----------- |
| `file0.txt` | ~~`dirA/file0.txt`~~<br />~~`dirA/dirA/file0.txt`~~<br />`file0.txt` | The simplest pattern to match files and directories located at the top level of the context. |
| `dirA/` | `dirA/`<br />~~`dirA/file0.txt`~~<br />~~`dirB/dirA/`~~ | A trailing slash (`/`) indicates that patterns match directories only. Note that directories are matched in a *non-greedy* manner, excluding their contents. |
| `dirA/file0.txt`<br /> | `dirA/file0.txt`<br />~~`dirA/dirA/file0.txt`~~<br />~~`dirB/dirA/file0.txt`~~ | All patterns are anchored to the context level, matching the specified file path relative to it. |
| `*` | `dirA/`<br />~~`dirA/file0.txt`~~<br />`file0.txt` | A positive match for any file or directory located at the root level of the context. |
| `*/` | `dirA/`<br />~~`dirA/file0.txt`~~<br />~~`file0.txt`~~ | A positive match for any directory located at the root level of the context, without including its contents. |
| `*`<br>`!*/` | ~~`dirA/`~~<br />`file0.txt` | A trick to positively match all files at the root level of the context while excluding directories. |
| `*/*` | `dirA/dirA`<br />`dirA/file0.txt` | A positive match for any second-level objects. |
| `*/file0.txt` | `dirA/file0.txt`<br />~~`dirA/dirB/file0.txt`~~<br />`dirB/file0.txt`<br />~~`file0.txt`~~ | A more material case of the previous pattern. |
| `*/*/` | `dirA/dirA/`<br />`dirA/dirB/`<br />~~`dirA/file0.txt`~~ | A positive match for any second-level directory. |
| `foo/*` | ~~`foo/`~~<br />`foo/foo/`<br />`foo/bar` | A pattern to positively match any object located directly inside the `foo` directory, excluding the `foo` directory itself. |
| `*/dirA/` | ~~`dirA/`~~<br />`dirA/dirB/`<br />~~`dirA/file0.txt`~~<br />~~`dirB/`~~<br />`dirB/dirA/` | A more material case of the previous pattern. |
| `foo*` | `foo`<br />`foobar`<br />`foooobar`<br />`foo.bar` | A positive match for any file or directory started with `foo` (at the related context level, of course). |
| `*bar` | `foobar`<br />`foooobar`<br />`foo.bar`<br />`bar` | A positive match for any file or directory ending with `bar` (again, at the related context level). |
| `**` | `dirA/`<br />`dirA/dirA/`<br />`dirA/dirA/file0.log`<br />`dirA/file0.txt`<br />`file0.txt` | A positive match for all files and directories, including their contents, recursively.|
| `**/` | `dirA/`<br />`dirA/dirA/`<br />~~`dirA/dirA/file0.log`~~<br />~~`dirA/file0.txt`~~<br />~~`file0.txt`~~ | A positive match for all directories and their subdirectories, recursively. |
| `**`<br />`!**/` | ~~`dirA/`~~<br />~~`dirA/dirA/`~~<br />`dirA/dirA/file0.log`<br />`dirA/file0.txt`<br />`file0.txt` | A trick to positively match all files, recursively while excluding directories. |
| `**/**` | ~~`dirA/`~~<br />`dirA/dirA/`<br />`dirA/dirA/file0.log`<br />`dirA/file0.txt`<br />~~`file0.txt`~~ | A recursive match for all objects located at the second level and deeper. |
| `**/**/` | ~~`dirA/`~~<br />`dirA/dirA/`<br />~~`dirA/dirA/file0.log`~~<br />~~`dirA/file0.txt`~~<br />~~`file0.txt`~~ | A recursive match for all directories located at the second level and deeper. |
| `dirA/**` | ~~`dirA/`~~<br />`dirA/dirB/`<br />`dirA/dirB/.../file0.txt` | A pattern to positively match any object inside the `dirA` directory, at any nesting level, recursively, excluding the `dirA` directory itself. |
| `dirA/**/file0.txt` | `dirA/dirA/file0.txt`<br />`dirA/dirA/dirA/file0.txt`<br />~~`dirA/file0.txt`~~ | The pattern will not match `dirA/file0.txt` because `/**/` requires at least one additional level of nesting between `dirA` and `file0.txt`. |
| `dirA/**file0.txt` | `dirA/dirA/file0.txt`<br />`dirA/dirA/dirA/file0.txt`<br />`dirA/file0.txt` | In contrast, the pattern matches `dirA/file0.txt` here, as `/**` allows matching files at any depth within `dirA`, including directly inside it. The slashes make the difference! |
| `foo**bar` | `foo/foo/bar`<br />`foo/bar/`<br />`foobar`<br /><br />`foo/foobar/`<br />`foo.bar` |  A pattern to recursively match any path starting with `foo` and ending with `bar`, regardless of nesting. |
| `foo?.bar` | `foo0.bar`<br />`foo1.bar`<br />`fooA.bar`<br />`foo..bar` | A positive match for filename where the `?` represents exactly one character other than a slash (`/`). |
| `foo?.bar` | ~~`foo.bar`~~ | Because *the `?` represents exactly one character*. |
| `foo?bar` | `foo_bar`<br />`foo.bar`<br />~~`foo/bar`~~ |  Because *other than a slash `/`*. |
| `file[0-9].txt` | `file0.txt`<br />`file1.txt`<br />...<br />`file9.txt`<br />~~`files.txt`~~ | Matches any file with the name pattern `file?.txt` where the `?` is a digit from `0` to `9`. |
| `file[!9a].txt` | `file0.txt`<br />`file1.txt`<br />...<br />~~`file9.txt`~~<br />~~`filea.txt`~~<br />`files.txt` | Matches any file with the name pattern `file?.txt` where the `?` is any character except `9`. |
| `file\*\*.txt` | `file**.txt`<br />~~`file1.txt`~~<br /> | Backslashes `\` escape the asterisks `*`, so it will handle them literally as any other characters. This means it will match a file named `file**.txt`, not any file pattern. |
| `\!file.txt`<br />`\#file.txt` | `!file.txt`<br />`\#file.txt` | Escaped exclamation mark `!` and hash sign `#` will also be handled literally as any other characters, meaning the pattern will match files named `!file.txt` and `#file.txt` without treating them as special symbols. |

## Installation

### From GitHub

```bash
git clone https://github.com/codyverse/fls.git
cd fls
```
No additional dependencies are required.

### Via PIP
- Main package:
```bash
pip install fls
```
- A package with additional test dependencies:
```bash
pip install fls[dev]
```


## Usage

### Basic Setup
1. Create a `.fls` file in your project root or specific directories.
2. Add rule patterns to the `.fls` file (one per line).

Example `.fls` file:
```
# Match all `.log` files
*.log

# Match `temp/` directory
temp/

# Do not match `temp/keep.txt`
!temp/keep.txt
```

3. Use the FLS class to scan and check matched files.
```python
from fls import FLS

# Initialize FLS with the root directory and protocol file
fls = FLS(root='path_to_your_project', protocol='.fls')

# Check if a specific file or directory matches the given rules
print(fls.is_matched('path_to_your_project/temp/some_file.log'))  # Output: True if matched, False if ignored
print(fls.is_matched('path_to_your_project/temp/keep.txt'))  # Output: True if matched, False if ignored

# Retrieve and print all rules for a specific directory
for rule in fls.get_rules('path_to_your_project/temp'):
    print(rule.get_pattern)  # Prints the pattern of each rule for the specified directory

# Retrieve and print all rules for each directory in the project
for path, rules in fls.get_all_rules():
    print(f"{os.path.relpath(path, test_path)}")  # Prints the relative path of the directory
    for rule in rules:
        _r = ', '.join(f"'{key}': '{value}'" for key, value in rule.rule.items())  # Prints the rule details
        print(f"    {_r}")

# Retrieve a list of matched and unmatched files and directories and print their status
for path, is_matched in fls.matched():
    status = f"Matched" if is_matched else "Ignored"  # Sets the status based on whether the path is matched
    print(f"{path}: {status}")
```
**Note**: Replace `path_to_your_project` with the actual path to your project directory.

## Contributing

Feel free to contribute by submitting issues or pull requests!

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/codyverse/fls",
    "name": "fls",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.8",
    "maintainer_email": null,
    "keywords": "file matching, file filter, file patterns, pattern matching, ignore files, file list, path filtering, file selection, gitignore, dockerignore",
    "author": "Andrii Burkatskyi aka andr11b",
    "author_email": "4ndr116@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/31/4b/e1089a328fc10f97ce20f1e6ccc0fba6416b9f32b1e8cd1a0dd96ddefa33/fls-0.0.1.241224.tar.gz",
    "platform": null,
    "description": "# File List Sieve\n\n## What is it?\n\n**File List Sieve** or simply **FLS** is a Python module for matching file system paths against patterns.\n\nThis functionality closely resembles the behavior of `.gitignore` and `.dockerignore`, making it intuitive for developers familiar with those systems. But unlike the mentioned systems, it allows you to choose what exactly you match files for - to ignore or to process.\n\n**FLS** provides a flexible way to configure match rules for any project structure by using a custom rule file (e.g., `.fls`) to determine which files and directories should be processed. The system supports features like:\n* Nested directories with inherited rules.\n* Pattern negation using `!`.\n* Wildcard matching for patterns (`*`, `?`, `**`, `[abc]`, etc.).\n\n\n## Possible Use Cases\n\n- **Ignoring Temporary Files**: In projects where temporary files or directories are created (e.g., during compilation or testing), FLS can be used to ignore these files when creating archives or versions.\n- **Selective File Processing**: If a project contains files that need to be processed but not all files, FLS allows you to precisely define which files to include and which to ignore based on patterns.\n- **Release Optimization**: When preparing a project for release, unnecessary files (e.g., logs, temporary files, or other auxiliary data) can be automatically excluded.\n- **Working with Large Codebases**: In large projects with many subdirectories and files, FLS allows you to easily create and maintain rules for selective file handling.\n\n## Syntax\n\nAs mentioned above the `.fls` rule files are similar to the well-known `.dockerignore` or `.gitignore` files, with some minore differences. Like these systems, rules are defined by specifying paths to files and directories in `.fls` files, which can be placed at any nesting level.\n\n### Key differences and behavior\n\n* **Context awareness**:\n\n    In `.gitignore`, patterns like an asterisk `*` or a simple one such as `foo` match every file and directory, regardless of how deeply they are nested. However, in `.fls`, the same rules only match files and directories located in the current directory. In `.fls`, all patterns are **relative to the location of the `.fls` file**, and this location is referred to as the context of a rule (or pattern). \n    Patterns can also explicitly define deeper levels; for example, `foo/bar` will match `bar` inside a directory named `foo` within the current context.\n\n* **No leading slash (`/`) anchoring**:\n\n    Unlike `.gitignore`, `.fls` does not use leading slashes to anchor patterns to the root. Patterns like `/foo` or `/bar/` are treated identically to `foo` or `bar/`.\n\n* **Trailing slash (`/`) for directories**:\n\n    A trailing slash (`/`) specifically matches directories only. For example:\n\n    - `foo/` matches a directory named `foo` but does not match `foo/bar`.\n    - `foo` matches both a file or directory named `foo`.\n\n* **Non-greedy directory matching**:\n\n    Directory matches are *non-greedy*, meaning they do not extend to the content of the directory unless explicitly specified. For instance:\n\n    - `foo/` matches only the foo directory.\n    - `foo/**` matches `foo` and all its contents.\n\n### Wildcards (globbing patterns)\n\nStandard wildcards, also known as globbing patterns, are used for working with multiple files. Globbing is the process of expanding a wildcard pattern into a list of pathnames that match it. A string qualifies as a wildcard pattern if it includes any of the characters `?`, `*`, or `[`.\n\n- A hash (`#`) signifies a comment. Lines starting with `#` are ignored.\n    ```\n    # This is just a comment.\n    ```\n- A backslash (`\\`) is used as an escape character to treat a special character literally.\n    ```\n    # The pattern below will match a file named \"#.txt\"\n    \\#.txt\n    ```\n- An asterisk (`*`) matches zero or more characters of any kind, excluding a slash (`/`).\n    ```\n    # This pattern would match \"`foobar`\", \"`foooobar`\", and anything that\n    # starts with `foo` also including \"`foo`\" itself.\n    foo*\n    ```\n- An exclamation mark (`!`) indicates an exception. It is used to exclude specific files or directories from being matched by previous patterns.\n    ```\n    # This ruleset matches all files ending with `.txt` but excludes\n    # `important.txt` from the match.\n    *.txt\n    !important.txt\n    ```\n- A question mark (`?`) matches exactly one character, excluding a slash (`/`).\n    ```\n    # This pattern matches `hda`, `hdb`, `hdc`, and any other one-character\n    # variation, excluding slashes (`/`).\n    hd?\n    ```\n- A double asterisk (`**`) matches zero or more files and directories, including their contents, recursively.\n    ```\n    # This will match all `.txt` files in any directory or subdirectory.\n    **/*.txt\n    ```\n- Square brackets (`[]`) specify a set or range of characters with an logical `OR` relationship, where any character within the brackets can match. Standard ranges include [0-9], [a-z], and [A-Z]. You can define subsets like `[0-4]` or `[a-d]`, combine ranges (e.g., `[0-9a-f]`), or mix ranges and individual characters (e.g., `[024abcXYZ]`).\n    ```\n    # The next pattern matches `mam`, `mum`, or `mom`.\n    m[aou]m\n\n    # The next pattern matches `mam`, `mbm`, `mcm`, or `mdm`.\n    m[a-d]m\n    ```\n- `[!]` works as a logical `NOT`, inverting the character set specified in square brackets (`[]`). Unlike `[]`, which matches any character listed inside, `[!]` matches any character not listed between the brackets.\n    ```\n    # The following pattern will match files starting with `file` that are\n    # followed by characters other than digits (e.g., `files`, `fileA`), but\n    # it will exclude files like `file0`, `file4` (those with digits `0-9`).\n    file[!0-9]\n    ```\n\n### Rule explanation\n\n| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Pattern&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Example&nbsp;matches&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | Explanation |\n| ---- | --------------- | ----------- |\n| `file0.txt` | ~~`dirA/file0.txt`~~<br />~~`dirA/dirA/file0.txt`~~<br />`file0.txt` | The simplest pattern to match files and directories located at the top level of the context. |\n| `dirA/` | `dirA/`<br />~~`dirA/file0.txt`~~<br />~~`dirB/dirA/`~~ | A trailing slash (`/`) indicates that patterns match directories only. Note that directories are matched in a *non-greedy* manner, excluding their contents. |\n| `dirA/file0.txt`<br /> | `dirA/file0.txt`<br />~~`dirA/dirA/file0.txt`~~<br />~~`dirB/dirA/file0.txt`~~ | All patterns are anchored to the context level, matching the specified file path relative to it. |\n| `*` | `dirA/`<br />~~`dirA/file0.txt`~~<br />`file0.txt` | A positive match for any file or directory located at the root level of the context. |\n| `*/` | `dirA/`<br />~~`dirA/file0.txt`~~<br />~~`file0.txt`~~ | A positive match for any directory located at the root level of the context, without including its contents. |\n| `*`<br>`!*/` | ~~`dirA/`~~<br />`file0.txt` | A trick to positively match all files at the root level of the context while excluding directories. |\n| `*/*` | `dirA/dirA`<br />`dirA/file0.txt` | A positive match for any second-level objects. |\n| `*/file0.txt` | `dirA/file0.txt`<br />~~`dirA/dirB/file0.txt`~~<br />`dirB/file0.txt`<br />~~`file0.txt`~~ | A more material case of the previous pattern. |\n| `*/*/` | `dirA/dirA/`<br />`dirA/dirB/`<br />~~`dirA/file0.txt`~~ | A positive match for any second-level directory. |\n| `foo/*` | ~~`foo/`~~<br />`foo/foo/`<br />`foo/bar` | A pattern to positively match any object located directly inside the `foo` directory, excluding the `foo` directory itself. |\n| `*/dirA/` | ~~`dirA/`~~<br />`dirA/dirB/`<br />~~`dirA/file0.txt`~~<br />~~`dirB/`~~<br />`dirB/dirA/` | A more material case of the previous pattern. |\n| `foo*` | `foo`<br />`foobar`<br />`foooobar`<br />`foo.bar` | A positive match for any file or directory started with `foo` (at the related context level, of course). |\n| `*bar` | `foobar`<br />`foooobar`<br />`foo.bar`<br />`bar` | A positive match for any file or directory ending with `bar` (again, at the related context level). |\n| `**` | `dirA/`<br />`dirA/dirA/`<br />`dirA/dirA/file0.log`<br />`dirA/file0.txt`<br />`file0.txt` | A positive match for all files and directories, including their contents, recursively.|\n| `**/` | `dirA/`<br />`dirA/dirA/`<br />~~`dirA/dirA/file0.log`~~<br />~~`dirA/file0.txt`~~<br />~~`file0.txt`~~ | A positive match for all directories and their subdirectories, recursively. |\n| `**`<br />`!**/` | ~~`dirA/`~~<br />~~`dirA/dirA/`~~<br />`dirA/dirA/file0.log`<br />`dirA/file0.txt`<br />`file0.txt` | A trick to positively match all files, recursively while excluding directories. |\n| `**/**` | ~~`dirA/`~~<br />`dirA/dirA/`<br />`dirA/dirA/file0.log`<br />`dirA/file0.txt`<br />~~`file0.txt`~~ | A recursive match for all objects located at the second level and deeper. |\n| `**/**/` | ~~`dirA/`~~<br />`dirA/dirA/`<br />~~`dirA/dirA/file0.log`~~<br />~~`dirA/file0.txt`~~<br />~~`file0.txt`~~ | A recursive match for all directories located at the second level and deeper. |\n| `dirA/**` | ~~`dirA/`~~<br />`dirA/dirB/`<br />`dirA/dirB/.../file0.txt` | A pattern to positively match any object inside the `dirA` directory, at any nesting level, recursively, excluding the `dirA` directory itself. |\n| `dirA/**/file0.txt` | `dirA/dirA/file0.txt`<br />`dirA/dirA/dirA/file0.txt`<br />~~`dirA/file0.txt`~~ | The pattern will not match `dirA/file0.txt` because `/**/` requires at least one additional level of nesting between `dirA` and `file0.txt`. |\n| `dirA/**file0.txt` | `dirA/dirA/file0.txt`<br />`dirA/dirA/dirA/file0.txt`<br />`dirA/file0.txt` | In contrast, the pattern matches `dirA/file0.txt` here, as `/**` allows matching files at any depth within `dirA`, including directly inside it. The slashes make the difference! |\n| `foo**bar` | `foo/foo/bar`<br />`foo/bar/`<br />`foobar`<br /><br />`foo/foobar/`<br />`foo.bar` |  A pattern to recursively match any path starting with `foo` and ending with `bar`, regardless of nesting. |\n| `foo?.bar` | `foo0.bar`<br />`foo1.bar`<br />`fooA.bar`<br />`foo..bar` | A positive match for filename where the `?` represents exactly one character other than a slash (`/`). |\n| `foo?.bar` | ~~`foo.bar`~~ | Because *the `?` represents exactly one character*. |\n| `foo?bar` | `foo_bar`<br />`foo.bar`<br />~~`foo/bar`~~ |  Because *other than a slash `/`*. |\n| `file[0-9].txt` | `file0.txt`<br />`file1.txt`<br />...<br />`file9.txt`<br />~~`files.txt`~~ | Matches any file with the name pattern `file?.txt` where the `?` is a digit from `0` to `9`. |\n| `file[!9a].txt` | `file0.txt`<br />`file1.txt`<br />...<br />~~`file9.txt`~~<br />~~`filea.txt`~~<br />`files.txt` | Matches any file with the name pattern `file?.txt` where the `?` is any character except `9`. |\n| `file\\*\\*.txt` | `file**.txt`<br />~~`file1.txt`~~<br /> | Backslashes `\\` escape the asterisks `*`, so it will handle them literally as any other characters. This means it will match a file named `file**.txt`, not any file pattern. |\n| `\\!file.txt`<br />`\\#file.txt` | `!file.txt`<br />`\\#file.txt` | Escaped exclamation mark `!` and hash sign `#` will also be handled literally as any other characters, meaning the pattern will match files named `!file.txt` and `#file.txt` without treating them as special symbols. |\n\n## Installation\n\n### From GitHub\n\n```bash\ngit clone https://github.com/codyverse/fls.git\ncd fls\n```\nNo additional dependencies are required.\n\n### Via PIP\n- Main package:\n```bash\npip install fls\n```\n- A package with additional test dependencies:\n```bash\npip install fls[dev]\n```\n\n\n## Usage\n\n### Basic Setup\n1. Create a `.fls` file in your project root or specific directories.\n2. Add rule patterns to the `.fls` file (one per line).\n\nExample `.fls` file:\n```\n# Match all `.log` files\n*.log\n\n# Match `temp/` directory\ntemp/\n\n# Do not match `temp/keep.txt`\n!temp/keep.txt\n```\n\n3. Use the FLS class to scan and check matched files.\n```python\nfrom fls import FLS\n\n# Initialize FLS with the root directory and protocol file\nfls = FLS(root='path_to_your_project', protocol='.fls')\n\n# Check if a specific file or directory matches the given rules\nprint(fls.is_matched('path_to_your_project/temp/some_file.log'))  # Output: True if matched, False if ignored\nprint(fls.is_matched('path_to_your_project/temp/keep.txt'))  # Output: True if matched, False if ignored\n\n# Retrieve and print all rules for a specific directory\nfor rule in fls.get_rules('path_to_your_project/temp'):\n    print(rule.get_pattern)  # Prints the pattern of each rule for the specified directory\n\n# Retrieve and print all rules for each directory in the project\nfor path, rules in fls.get_all_rules():\n    print(f\"{os.path.relpath(path, test_path)}\")  # Prints the relative path of the directory\n    for rule in rules:\n        _r = ', '.join(f\"'{key}': '{value}'\" for key, value in rule.rule.items())  # Prints the rule details\n        print(f\"    {_r}\")\n\n# Retrieve a list of matched and unmatched files and directories and print their status\nfor path, is_matched in fls.matched():\n    status = f\"Matched\" if is_matched else \"Ignored\"  # Sets the status based on whether the path is matched\n    print(f\"{path}: {status}\")\n```\n**Note**: Replace `path_to_your_project` with the actual path to your project directory.\n\n## Contributing\n\nFeel free to contribute by submitting issues or pull requests!\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "FLS: A module for matching file system paths against patterns.",
    "version": "0.0.1.241224",
    "project_urls": {
        "Homepage": "https://github.com/codyverse/fls"
    },
    "split_keywords": [
        "file matching",
        " file filter",
        " file patterns",
        " pattern matching",
        " ignore files",
        " file list",
        " path filtering",
        " file selection",
        " gitignore",
        " dockerignore"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "ee3aa7511279d3a74906ee565a3804b229cbc7a73c07d4d7ec755e5c0279c5b8",
                "md5": "87a73bf359318173d3d77899fa6b661a",
                "sha256": "977e80e18d03f96e01d17c17096ccce0fdb34ff4b91d15973b1d31a9734c574e"
            },
            "downloads": -1,
            "filename": "fls-0.0.1.241224-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "87a73bf359318173d3d77899fa6b661a",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8",
            "size": 10280,
            "upload_time": "2024-12-24T13:40:49",
            "upload_time_iso_8601": "2024-12-24T13:40:49.701989Z",
            "url": "https://files.pythonhosted.org/packages/ee/3a/a7511279d3a74906ee565a3804b229cbc7a73c07d4d7ec755e5c0279c5b8/fls-0.0.1.241224-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "314be1089a328fc10f97ce20f1e6ccc0fba6416b9f32b1e8cd1a0dd96ddefa33",
                "md5": "69565d5241b9f3ebb4afdb6fd8049619",
                "sha256": "ee47323048359ac2ca40ce5f7952bb3abe48e14492075373bb9226b50c27dc13"
            },
            "downloads": -1,
            "filename": "fls-0.0.1.241224.tar.gz",
            "has_sig": false,
            "md5_digest": "69565d5241b9f3ebb4afdb6fd8049619",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8",
            "size": 19946,
            "upload_time": "2024-12-24T13:40:51",
            "upload_time_iso_8601": "2024-12-24T13:40:51.896841Z",
            "url": "https://files.pythonhosted.org/packages/31/4b/e1089a328fc10f97ce20f1e6ccc0fba6416b9f32b1e8cd1a0dd96ddefa33/fls-0.0.1.241224.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-12-24 13:40:51",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "codyverse",
    "github_project": "fls",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "fls"
}
        
Elapsed time: 0.45918s