trs-file-backup 2.0.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. trs_file_backup-2.0.1/.editorconfig +21 -0
  2. trs_file_backup-2.0.1/.github/workflows/ci.yml +91 -0
  3. trs_file_backup-2.0.1/.gitignore +147 -0
  4. trs_file_backup-2.0.1/.pre-commit-config.yaml +43 -0
  5. trs_file_backup-2.0.1/.vscode/extensions.json +10 -0
  6. trs_file_backup-2.0.1/.vscode/launch.json +19 -0
  7. trs_file_backup-2.0.1/.vscode/settings.json +36 -0
  8. trs_file_backup-2.0.1/.vscode/tasks.json +65 -0
  9. trs_file_backup-2.0.1/AGENTS.md +97 -0
  10. trs_file_backup-2.0.1/CHANGELOG.md +187 -0
  11. trs_file_backup-2.0.1/CONTRIBUTING.md +141 -0
  12. trs_file_backup-2.0.1/LICENSE +21 -0
  13. trs_file_backup-2.0.1/PKG-INFO +98 -0
  14. trs_file_backup-2.0.1/README.md +84 -0
  15. trs_file_backup-2.0.1/commitlint.config.js +8 -0
  16. trs_file_backup-2.0.1/docs/_static/.gitkeep +0 -0
  17. trs_file_backup-2.0.1/docs/_static/empty_favicon.ico +0 -0
  18. trs_file_backup-2.0.1/docs/_static/python-logo-only.svg +265 -0
  19. trs_file_backup-2.0.1/docs/conf.py +106 -0
  20. trs_file_backup-2.0.1/docs/features/file_backup.md +613 -0
  21. trs_file_backup-2.0.1/docs/features/index.md +22 -0
  22. trs_file_backup-2.0.1/docs/index.md +22 -0
  23. trs_file_backup-2.0.1/docs/intro.md +3 -0
  24. trs_file_backup-2.0.1/pyproject.toml +155 -0
  25. trs_file_backup-2.0.1/src/trs_file_backup/__init__.py +1 -0
  26. trs_file_backup-2.0.1/src/trs_file_backup/backup.py +131 -0
  27. trs_file_backup-2.0.1/src/trs_file_backup/logger.py +163 -0
  28. trs_file_backup-2.0.1/src/trs_file_backup/main.py +583 -0
  29. trs_file_backup-2.0.1/src/trs_file_backup/py.typed +0 -0
  30. trs_file_backup-2.0.1/src/trs_file_backup/state.py +122 -0
  31. trs_file_backup-2.0.1/tests/conftest.py +11 -0
  32. trs_file_backup-2.0.1/tests/test_backup.py +277 -0
  33. trs_file_backup-2.0.1/tests/test_cli.py +756 -0
  34. trs_file_backup-2.0.1/tests/test_logger.py +274 -0
  35. trs_file_backup-2.0.1/tests/test_state.py +209 -0
  36. trs_file_backup-2.0.1/uv.lock +2535 -0
@@ -0,0 +1,21 @@
1
+ # http://editorconfig.org
2
+
3
+ root = true
4
+
5
+ [*]
6
+ indent_style = space
7
+ indent_size = 4
8
+ trim_trailing_whitespace = true
9
+ insert_final_newline = true
10
+ charset = utf-8
11
+ end_of_line = lf
12
+
13
+ [*.bat]
14
+ indent_style = tab
15
+ end_of_line = crlf
16
+
17
+ [LICENSE]
18
+ insert_final_newline = false
19
+
20
+ [Makefile]
21
+ indent_style = tab
@@ -0,0 +1,91 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [develop]
6
+ pull_request:
7
+ branches: [develop]
8
+
9
+ jobs:
10
+ lint:
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - uses: actions/checkout@v4
14
+ - uses: astral-sh/setup-uv@v5
15
+ - run: uv run pre-commit run --all-files
16
+
17
+ test:
18
+ runs-on: ubuntu-latest
19
+ permissions:
20
+ checks: write
21
+ steps:
22
+ - uses: actions/checkout@v4
23
+ - uses: astral-sh/setup-uv@v5
24
+ - run: uv sync --group dev
25
+ - run: uv run pytest --cov-report=xml:coverage.xml --junitxml=junit.xml
26
+
27
+ - name: Upload coverage to Codecov
28
+ if: always()
29
+ uses: codecov/codecov-action@v5
30
+ with:
31
+ files: coverage.xml
32
+ fail_ci_if_error: true
33
+ token: ${{ secrets.CODECOV_TOKEN }}
34
+
35
+ - name: Upload test results to Codecov
36
+ if: always()
37
+ uses: codecov/codecov-action@v5
38
+ with:
39
+ files: junit.xml
40
+ report_type: test_results
41
+ fail_ci_if_error: true
42
+ token: ${{ secrets.CODECOV_TOKEN }}
43
+
44
+ - name: Publish JUnit test results
45
+ if: always()
46
+ uses: mikepenz/action-junit-report@v6
47
+ with:
48
+ report_paths: junit.xml
49
+ check_name: Test Results
50
+ fail_on_failure: true
51
+ require_tests: true
52
+ detailed_summary: true
53
+ include_passed: false
54
+
55
+ release:
56
+ needs: [lint, test]
57
+ if: github.event_name == 'push' && github.ref == 'refs/heads/develop'
58
+ runs-on: ubuntu-latest
59
+ environment: release
60
+ concurrency: release
61
+ permissions:
62
+ contents: write
63
+ id-token: write
64
+ steps:
65
+ - name: Generate App Token
66
+ id: app-token
67
+ uses: actions/create-github-app-token@v1
68
+ with:
69
+ app-id: ${{ secrets.RELEASE_APP_ID }}
70
+ private-key: ${{ secrets.RELEASE_APP_PRIVATE_KEY }}
71
+
72
+ - uses: actions/checkout@v4
73
+ with:
74
+ fetch-depth: 0
75
+ token: ${{ steps.app-token.outputs.token }}
76
+
77
+ - name: Release
78
+ uses: python-semantic-release/python-semantic-release@v9
79
+ id: release
80
+ with:
81
+ github_token: ${{ steps.app-token.outputs.token }}
82
+
83
+ - name: Publish GitHub Release
84
+ uses: python-semantic-release/publish-action@v9
85
+ if: steps.release.outputs.released == 'true'
86
+ with:
87
+ github_token: ${{ steps.app-token.outputs.token }}
88
+
89
+ - name: Publish to PyPI
90
+ uses: pypa/gh-action-pypi-publish@release/v1
91
+ if: steps.release.outputs.released == 'true'
@@ -0,0 +1,147 @@
1
+ # Created by .ignore support plugin (hsz.mobi)
2
+ ### Python template
3
+ # Byte-compiled / optimized / DLL files
4
+ __pycache__/
5
+ *.py[cod]
6
+ *$py.class
7
+
8
+ # C extensions
9
+ *.so
10
+
11
+ # Distribution / packaging
12
+ .Python
13
+ build/
14
+ develop-eggs/
15
+ dist/
16
+ downloads/
17
+ eggs/
18
+ .eggs/
19
+ lib/
20
+ lib64/
21
+ parts/
22
+ sdist/
23
+ var/
24
+ wheels/
25
+ share/python-wheels/
26
+ *.egg-info/
27
+ .installed.cfg
28
+ *.egg
29
+ MANIFEST
30
+
31
+ # PyInstaller
32
+ # Usually these files are written by a python script from a template
33
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
34
+ *.manifest
35
+ *.spec
36
+
37
+ # Installer logs
38
+ pip-log.txt
39
+ pip-delete-this-directory.txt
40
+
41
+ # Unit test / coverage reports
42
+ htmlcov/
43
+ .tox/
44
+ .nox/
45
+ .coverage
46
+ .coverage.*
47
+ .cache
48
+ nosetests.xml
49
+ coverage.xml
50
+ *.cover
51
+ *.py,cover
52
+ .hypothesis/
53
+ .pytest_cache/
54
+ cover/
55
+
56
+ # Translations
57
+ *.mo
58
+ *.pot
59
+
60
+ # Django stuff:
61
+ *.log
62
+ local_settings.py
63
+ db.sqlite3
64
+ db.sqlite3-journal
65
+
66
+ # Flask stuff:
67
+ instance/
68
+ .webassets-cache
69
+
70
+ # Scrapy stuff:
71
+ .scrapy
72
+
73
+ # PyBuilder
74
+ .pybuilder/
75
+ target/
76
+
77
+ # Jupyter Notebook
78
+ .ipynb_checkpoints
79
+
80
+ # IPython
81
+ profile_default/
82
+ ipython_config.py
83
+
84
+ # pyenv
85
+ # For a library or package, you might want to ignore these files since the code is
86
+ # intended to run in multiple environments; otherwise, check them in:
87
+ # .python-version
88
+
89
+ # pipenv
90
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
91
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
92
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
93
+ # install all needed dependencies.
94
+ #Pipfile.lock
95
+
96
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow
97
+ __pypackages__/
98
+
99
+ # Celery stuff
100
+ celerybeat-schedule
101
+ celerybeat.pid
102
+
103
+ # SageMath parsed files
104
+ *.sage.py
105
+
106
+ # Environments
107
+ .env
108
+ .venv
109
+ env/
110
+ venv/
111
+ ENV/
112
+ env.bak/
113
+ venv.bak/
114
+
115
+ # Spyder {{package_name}} settings
116
+ .spyderproject
117
+ .spyproject
118
+
119
+ # Rope {{package_name}} settings
120
+ .ropeproject
121
+
122
+ # mkdocs documentation
123
+ /site
124
+
125
+ # mypy
126
+ .mypy_cache/
127
+ .dmypy.json
128
+ dmypy.json
129
+
130
+ # ruff
131
+ .ruff_cache/
132
+
133
+ # Pyre type checker
134
+ .pyre/
135
+
136
+ # pytype static type analyzer
137
+ .pytype/
138
+
139
+ # Cython debug symbols
140
+ cython_debug/
141
+
142
+ # bootstrap files are downloaded during installation
143
+ /.bootstrap
144
+
145
+ # Local development planning files - kept for temporary use during development
146
+ ROADMAP.md
147
+ REVIEW.md
@@ -0,0 +1,43 @@
1
+ # See https://pre-commit.com for more information
2
+ # See https://pre-commit.com/hooks.html for more hooks
3
+ exclude: "CHANGELOG\\.md|\\.all-contributorsrc|\\.vscode/.*|tests/__init__\\.py|\\.github/.*"
4
+ default_stages: [pre-commit]
5
+
6
+ ci:
7
+ autofix_commit_msg: "chore(pre-commit.ci): auto fixes"
8
+ autoupdate_commit_msg: "chore(pre-commit.ci): pre-commit autoupdate"
9
+
10
+ repos:
11
+ - repo: https://github.com/commitizen-tools/commitizen
12
+ rev: v3.16.0
13
+ hooks:
14
+ - id: commitizen
15
+ stages: [commit-msg]
16
+ - repo: https://github.com/pre-commit/pre-commit-hooks
17
+ rev: v4.5.0
18
+ hooks:
19
+ - id: debug-statements
20
+ - id: check-builtin-literals
21
+ - id: check-case-conflict
22
+ - id: check-docstring-first
23
+ - id: check-json
24
+ - id: check-toml
25
+ - id: check-xml
26
+ - id: check-yaml
27
+ - id: detect-private-key
28
+ - id: end-of-file-fixer
29
+ - id: trailing-whitespace
30
+ - repo: https://github.com/astral-sh/ruff-pre-commit
31
+ rev: v0.3.0
32
+ hooks:
33
+ - id: ruff
34
+ args: [--fix, --exit-non-zero-on-fix]
35
+ - repo: https://github.com/codespell-project/codespell
36
+ rev: v2.2.6
37
+ hooks:
38
+ - id: codespell
39
+ - repo: https://github.com/pre-commit/mirrors-mypy
40
+ rev: v1.8.0
41
+ hooks:
42
+ - id: mypy
43
+ additional_dependencies: []
@@ -0,0 +1,10 @@
1
+ {
2
+ "recommendations": [
3
+ "charliermarsh.ruff",
4
+ "ms-python.python",
5
+ "ms-python.vscode-pylance",
6
+ "mystExecutableBookProject.myst-highlight",
7
+ "chrisjsewell.myst-tml-syntax",
8
+ "chrisjsewell.myst-lsp"
9
+ ]
10
+ }
@@ -0,0 +1,19 @@
1
+ {
2
+ "version": "0.2.0",
3
+ "configurations": [
4
+ {
5
+ "name": "Python: Debug Tests",
6
+ "type": "debugpy",
7
+ "request": "launch",
8
+ "program": "${file}",
9
+ "purpose": [
10
+ "debug-test"
11
+ ],
12
+ "console": "integratedTerminal",
13
+ "env": {
14
+ "PYTEST_ADDOPTS": "--no-cov"
15
+ },
16
+ "justMyCode": false
17
+ }
18
+ ]
19
+ }
@@ -0,0 +1,36 @@
1
+ {
2
+ "python.testing.pytestArgs": [
3
+ "tests"
4
+ ],
5
+ "python.testing.unittestEnabled": false,
6
+ "python.testing.pytestEnabled": true,
7
+ "editor.formatOnSave": true,
8
+ "[python]": {
9
+ "editor.defaultFormatter": "charliermarsh.ruff"
10
+ },
11
+ "python.analysis.typeCheckingMode": "basic",
12
+ "workbench.colorCustomizations": {
13
+ "activityBar.activeBackground": "#c4f3fd",
14
+ "activityBar.background": "#c4f3fd",
15
+ "activityBar.foreground": "#15202b",
16
+ "activityBar.inactiveForeground": "#15202b99",
17
+ "activityBarBadge.background": "#fa65e0",
18
+ "activityBarBadge.foreground": "#15202b",
19
+ "commandCenter.border": "#15202b99",
20
+ "sash.hoverBorder": "#c4f3fd",
21
+ "statusBar.background": "#93e9fb",
22
+ "statusBar.foreground": "#15202b",
23
+ "statusBarItem.hoverBackground": "#62dff9",
24
+ "statusBarItem.remoteBackground": "#93e9fb",
25
+ "statusBarItem.remoteForeground": "#15202b",
26
+ "titleBar.activeBackground": "#93e9fb",
27
+ "titleBar.activeForeground": "#15202b",
28
+ "titleBar.inactiveBackground": "#93e9fb99",
29
+ "titleBar.inactiveForeground": "#15202b99"
30
+ },
31
+ "peacock.color": "#93e9fb",
32
+ "chat.tools.terminal.autoApprove": {
33
+ "/.*/": true
34
+ },
35
+ "chat.tools.terminal.ignoreDefaultAutoApproveRules": true
36
+ }
@@ -0,0 +1,65 @@
1
+ {
2
+ "version": "2.0.0",
3
+ "tasks": [
4
+ {
5
+ "label": "Install",
6
+ "command": "uv sync --all-groups",
7
+ "type": "shell",
8
+ "presentation": {
9
+ "reveal": "always"
10
+ },
11
+ "group": {
12
+ "kind": "build",
13
+ "isDefault": false
14
+ }
15
+ },
16
+ {
17
+ "label": "static analysis",
18
+ "command": "uv run pre-commit run --all-files",
19
+ "type": "shell",
20
+ "presentation": {
21
+ "reveal": "always"
22
+ },
23
+ "group": {
24
+ "kind": "build",
25
+ "isDefault": false
26
+ }
27
+ },
28
+ {
29
+ "label": "run tests",
30
+ "command": "uv run pytest",
31
+ "type": "shell",
32
+ "presentation": {
33
+ "reveal": "always"
34
+ },
35
+ "group": {
36
+ "kind": "build",
37
+ "isDefault": false
38
+ }
39
+ },
40
+ {
41
+ "label": "generate docs",
42
+ "command": "uv run sphinx-build -b html docs build/docs/html",
43
+ "type": "shell",
44
+ "presentation": {
45
+ "reveal": "always"
46
+ },
47
+ "group": {
48
+ "kind": "build",
49
+ "isDefault": false
50
+ }
51
+ },
52
+ {
53
+ "label": "open docs index.html",
54
+ "command": "${workspaceFolder}/build/docs/html/index.html",
55
+ "type": "shell",
56
+ "presentation": {
57
+ "reveal": "always"
58
+ },
59
+ "group": {
60
+ "kind": "build",
61
+ "isDefault": false
62
+ }
63
+ }
64
+ ]
65
+ }
@@ -0,0 +1,97 @@
1
+ # trs-file-backup - Agent Instructions
2
+
3
+ ## Project Overview
4
+
5
+ This is a Python CLI tool for monitoring directories and creating timestamped backups of modified files. The project uses uv for dependency management and follows strict conventional commit standards.
6
+
7
+ ## Key Technologies
8
+
9
+ - **Language**: Python 3.10+
10
+ - **CLI Framework**: Typer + Rich (for terminal UI)
11
+ - **File Watching**: Watchdog
12
+ - **Build Tool**: uv + hatchling
13
+ - **Testing**: Pytest + Pester (PowerShell tests)
14
+ - **Linting**: Ruff
15
+ - **CI/CD**: GitHub Actions with semantic-release
16
+ - **Versioning**: Semantic Release (automatic based on conventional commits)
17
+
18
+ ## Project Structure
19
+
20
+ - `src/trs_file_backup/` - Main source code
21
+ - `tests/` - Python and PowerShell tests
22
+ - `docs/` - Sphinx documentation
23
+ - `build.ps1` - Development setup script
24
+ - `pyproject.toml` - PEP 621 project configuration and dependencies
25
+
26
+ ## Important Context
27
+
28
+ ### CLI Commands
29
+
30
+ The tool provides three main commands:
31
+
32
+ - `trs-file-backup init` - Initialize backup tracking
33
+ - `trs-file-backup run` - One-time backup
34
+ - `trs-file-backup watch` - Continuous monitoring mode
35
+
36
+ ### Backup Behavior
37
+
38
+ - Only monitors **top-level files** in source directory (no subdirectories)
39
+ - Stores all backups in a **flat structure** in destination directory
40
+ - Backup filename format: `original_YYYY_MM_DD__HH_MM_SS.ext`
41
+ - Tracks state in `.backup_state.json` (stored in backup directory)
42
+ - Logs to `backup.log`
43
+
44
+ ### Development Workflow
45
+
46
+ 1. **Setup**: Run `uv sync --all-groups` to install dependencies
47
+ 2. **Testing**: Run `uv run pytest` for all tests
48
+ 3. **Pre-commit**: Run `uv run pre-commit run --all-files` before committing
49
+ 4. **Commits**: MUST follow conventional commit format (enforced by commitlint)
50
+
51
+ ### Commit Standards
52
+
53
+ This project uses **strict conventional commits**. Every commit message must follow:
54
+
55
+ ```text
56
+ <type>(<scope>): <subject>
57
+ ```
58
+
59
+ **Version Impact**:
60
+
61
+ - `feat:` → Minor version bump (1.0.0 → 1.1.0)
62
+ - `fix:` → Patch version bump (1.0.0 → 1.0.1)
63
+ - `feat!:` or `fix!:` → Major version bump (breaking change)
64
+ - `docs:`, `style:`, `refactor:`, `test:`, `chore:` → No version bump
65
+
66
+ ### Release Process
67
+
68
+ - **Automatic**: GitHub Actions on `develop` branch
69
+ - **Semantic Release**: Analyzes commits and auto-bumps version
70
+ - **Version Files**: Synchronized in `pyproject.toml`, `src/trs_file_backup/__init__.py`, `docs/conf.py`
71
+ - **Changelog**: Auto-generated in `CHANGELOG.md`
72
+ - **Publishing**: Tag builds publish to PyPI
73
+
74
+ ## Code Guidelines
75
+
76
+ - **Ruff Configuration**: Line length 180, specific ignores for docstrings
77
+ - **Type Hints**: Required (mypy strict mode)
78
+ - **Test Coverage**: Required with pytest-cov
79
+ - **Python Version**: Minimum 3.10
80
+
81
+ ## When Making Changes
82
+
83
+ 1. **Code Changes**: Keep modifications minimal and surgical
84
+ 2. **Tests**: Update or add tests as needed
85
+ 3. **Documentation**: Update README.md if user-facing features change
86
+ 4. **Version**: Never manually change version numbers (automatic via semantic-release)
87
+ 5. **Commits**: Use correct conventional commit type for version bumping
88
+
89
+ ## Package Distribution
90
+
91
+ - **Registry**: Published to PyPI (public)
92
+ - **License**: MIT
93
+ - **Installation**: `pip install trs-file-backup`
94
+
95
+ ## PowerShell Integration
96
+
97
+ The project includes PowerShell scripts and Pester tests. Pester 5.x is required for development.