Metadata-Version: 2.4
Name: bugyo-fs
Version: 1.0.1
Summary: Filesystem plugin for Daimyo - provides filesystem and system context for templates
Project-URL: Homepage, https://gitlab.com/Kencho1/daimyo
Project-URL: Documentation, https://gitlab.com/Kencho1/daimyo/-/blob/main/plugins/bugyo-fs/README.md
Project-URL: Repository, https://gitlab.com/Kencho1/daimyo
Project-URL: Issues, https://gitlab.com/Kencho1/daimyo/-/issues
Author: Jesús Alonso Abad
License: MIT License
        
        Copyright (c) 2025 Jesús Alonso Abad
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
License-File: LICENSE
Keywords: daimyo,filesystem,jinja2,plugin,templates
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: System :: Filesystems
Classifier: Typing :: Typed
Requires-Python: >=3.11
Requires-Dist: daimyo>=1.4.0
Description-Content-Type: text/markdown

# bugyo-fs

Filesystem plugin for Daimyo - provides filesystem and system context, filters, and tests for Jinja2 templates.

## Installation

```bash
pip install bugyo-fs
```

## Features

### Context Variables

The `fs.context` plugin provides the following template variables:

| Variable | Type | Description |
|----------|------|-------------|
| `cwd` | str | Current working directory (absolute path) |
| `project_root` | str | Project root directory (same as cwd) |
| `path_separator` | str | OS-specific path separator (`/` or `\`) |
| `is_windows` | bool | True if running on Windows |
| `is_linux` | bool | True if running on Linux |
| `is_macos` | bool | True if running on macOS |
| `hostname` | str | System hostname |

### Filters

The `fs.filters` plugin provides the following Jinja2 filters:

| Filter | Description | Example |
|--------|-------------|---------|
| `basename` | Get filename from path | `"path/file.txt" \| basename` → `"file.txt"` |
| `dirname` | Get directory from path | `"path/file.txt" \| dirname` → `"path"` |
| `relpath` | Get relative path | `"/abs/path" \| relpath("/abs")` → `"path"` |
| `joinpath` | Join path components | `"dir" \| joinpath("file.txt")` → `"dir/file.txt"` |
| `normpath` | Normalize path | `"./path//file.txt" \| normpath` → `"path/file.txt"` |

### Tests

The `fs.filters` plugin provides the following Jinja2 tests:

| Test | Description | Example |
|------|-------------|---------|
| `file_exists` | Check if file exists | `"file.txt" is file_exists` |
| `path_exists` | Check if path exists | `"dir" is path_exists` |
| `is_directory` | Check if path is directory | `"dir" is is_directory` |
| `is_file` | Check if path is file | `"file.txt" is is_file` |
| `is_relative` | Check if path is relative | `"./file.txt" is is_relative` |

## Usage

### Configuration

Enable the plugin in your `.daimyo/config/settings.toml`:

```toml
# Enable all filesystem plugins
enabled_plugins = ["fs.*"]

# Or enable specific plugins
enabled_plugins = ["fs.context", "fs.filters"]
```

### Template Examples

#### Platform-Specific Rules

In your YAML rule files:

```yaml
python.general:
  when: Python development guidelines
  ruleset:
    - "{% if is_linux %}Use forward slashes in paths{% endif %}"
    - "{% if is_linux %}Package manager: apt/dnf{% endif %}"
    - "{% if is_windows %}Use backslashes in paths{% endif %}"
    - "{% if is_windows %}Package manager: winget/choco{% endif %}"
    - "{% if is_macos %}Use forward slashes in paths{% endif %}"
    - "{% if is_macos %}Package manager: brew{% endif %}"
```

#### Conditional Rules Based on File Existence

```yaml
project.setup:
  when: Project setup guidelines
  ruleset:
    - "{% if 'pyproject.toml' is file_exists %}This is a Python project using pyproject.toml{% endif %}"
    - "{% if 'pyproject.toml' is file_exists %}Use uv or pip for dependency management{% endif %}"
    - "{% if 'package.json' is file_exists %}This is a Node.js project{% endif %}"
    - "{% if 'package.json' is file_exists %}Use npm or yarn for dependency management{% endif %}"
    - "{% if '.git' is is_directory %}This project uses Git for version control{% endif %}"
    - "{% if '.git' is is_directory %}Remember to commit your changes regularly{% endif %}"
```

#### Path Manipulation

```yaml
project.info:
  when: Project information
  ruleset:
    - "Working directory: {{ cwd }}"
    - "Project: {{ cwd | basename }}"
    - "{% set config_file = 'config' | joinpath('settings.toml') %}Configuration file: {{ config_file }}"
    - "{% set config_file = 'config' | joinpath('settings.toml') %}{% if config_file is file_exists %}Config file found at {{ config_file }}{% else %}Config file not found - using defaults{% endif %}"
```

#### System Information

```yaml
system.info:
  when: System information
  ruleset:
    - "Hostname: {{ hostname }}"
    - "Path separator: {{ path_separator }}"
    - "{% if is_linux %}Platform: Linux{% endif %}"
```

## Security

**Important**: This plugin implements strict path validation to prevent security vulnerabilities.

### Path Traversal Protection

All path operations are validated to ensure they stay within the **current working directory**. This prevents malicious templates from accessing sensitive system files.

#### Blocked Operations

The following path operations will raise `ValueError`:

```python
# Parent directory traversal
"../../../etc/passwd"           # Blocked

# Absolute paths outside cwd
"/etc/passwd"                   # Blocked
"/home/user/.ssh/id_rsa"       # Blocked

# Symlinks pointing outside cwd
"escape_link" → "/etc/passwd"   # Blocked
```

#### Allowed Operations

Only paths within the current working directory are allowed:

```python
# Relative paths within cwd
"file.txt"                      # Allowed
"./file.txt"                    # Allowed
"subdir/file.txt"              # Allowed

# Absolute paths within cwd
"/path/to/project/file.txt"     # Allowed (if cwd is /path/to/project)
```

### Security Features

- **No home directory access**: `home_dir` and `temp_dir` are not exposed
- **No `abspath` filter**: Prevents revealing system paths
- **No `expanduser` filter**: Prevents accessing home directory
- **No `is_readable`/`is_writable` tests**: Reduces attack surface
- **Safe error handling**: Tests return `False` instead of raising errors for invalid paths

### Error Messages

Path traversal attempts will raise descriptive errors:

```text
ValueError: Path traversal attempt detected: '../../../etc/passwd' resolves
outside current working directory. Only paths within /path/to/project are allowed.
```

## Limitations

- **Scope**: Only the current working directory and its subdirectories are accessible
- **Symlinks**: Symlinks pointing outside cwd are rejected
- **Absolute paths**: Only absolute paths within cwd are allowed
- **Parent directories**: Cannot access parent directories of cwd

These limitations are **intentional security features** to prevent malicious template code from accessing sensitive files.

## Requirements

- Python >= 3.11
- daimyo >= 1.4.0

Standard library only (no additional dependencies).

## License

MIT License - see LICENSE file for details.

## Contributing

Contributions are welcome! Please ensure:

1. All tests pass
2. Security constraints are maintained
3. Code passes `mypy` and `ruff` checks
4. Documentation is updated

## Support

For issues and questions, please visit the [Daimyo issue tracker](https://gitlab.com/Kencho1/daimyo/-/issues).
