sawmill-parser 0.3.2__tar.gz → 0.5.0__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.
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/.gitignore +3 -0
- sawmill_parser-0.5.0/CLAUDE.md +83 -0
- sawmill_parser-0.5.0/PKG-INFO +115 -0
- sawmill_parser-0.5.0/README.md +70 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/docs/conf.py +3 -4
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/docs/development/contributing.rst +2 -33
- sawmill_parser-0.5.0/docs/development/manifest-design.rst +373 -0
- sawmill_parser-0.5.0/docs/getting-started/quickstart.rst +82 -0
- sawmill_parser-0.5.0/docs/getting-started/what-is-sawmill.rst +57 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/docs/index.rst +15 -6
- sawmill_parser-0.5.0/docs/performance/overview.rst +103 -0
- sawmill_parser-0.5.0/docs/performance/plugin-api-2.rst +97 -0
- sawmill_parser-0.5.0/docs/performance/store-investigation.rst +127 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/docs/plugin-guide/pre-defined-filters.rst +15 -22
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/docs/plugin-guide/what-is-a-plugin.rst +7 -7
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/docs/plugin-guide/writing-a-plugin.rst +75 -14
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/docs/reference/api.rst +8 -8
- sawmill_parser-0.5.0/docs/reference/cli-reference.rst +222 -0
- sawmill_parser-0.5.0/docs/reference/file-formats.rst +291 -0
- sawmill_parser-0.5.0/docs/user-guide/ci-integration.rst +181 -0
- sawmill_parser-0.5.0/docs/user-guide/cli-usage.rst +131 -0
- sawmill_parser-0.5.0/docs/user-guide/rules.rst +189 -0
- sawmill_parser-0.5.0/docs/user-guide/sawmill-directory.rst +175 -0
- sawmill_parser-0.5.0/docs/user-guide/tui-usage.rst +186 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/pyproject.toml +6 -3
- sawmill_parser-0.5.0/sawmill/cli/check.py +165 -0
- sawmill_parser-0.5.0/sawmill/cli/commands.py +71 -0
- sawmill_parser-0.5.0/sawmill/cli/common.py +123 -0
- sawmill_parser-0.5.0/sawmill/cli/init.py +88 -0
- sawmill_parser-0.5.0/sawmill/cli/plugins.py +120 -0
- sawmill_parser-0.5.0/sawmill/cli/report.py +92 -0
- sawmill_parser-0.5.0/sawmill/cli/rules.py +180 -0
- sawmill_parser-0.5.0/sawmill/cli/view.py +60 -0
- sawmill_parser-0.5.0/sawmill/core/__init__.py +116 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/sawmill/core/aggregation.py +4 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/sawmill/core/config.py +18 -36
- sawmill_parser-0.5.0/sawmill/core/discovery.py +184 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/sawmill/core/filter.py +6 -72
- sawmill_parser-0.5.0/sawmill/core/junit.py +85 -0
- sawmill_parser-0.5.0/sawmill/core/manifest.py +185 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/sawmill/core/plugin.py +22 -3
- sawmill_parser-0.5.0/sawmill/core/report.py +133 -0
- sawmill_parser-0.5.0/sawmill/core/rule_matcher.py +176 -0
- sawmill_parser-0.5.0/sawmill/core/rules.py +283 -0
- sawmill_parser-0.5.0/sawmill/core/runner.py +396 -0
- sawmill_parser-0.5.0/sawmill/core/scaffold.py +102 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/sawmill/core/severity.py +35 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/sawmill/models/__init__.py +6 -3
- sawmill_parser-0.5.0/sawmill/models/manifest.py +122 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/sawmill/models/message.py +24 -9
- sawmill_parser-0.5.0/sawmill/models/rule.py +109 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/sawmill/plugin/__init__.py +27 -9
- sawmill_parser-0.5.0/sawmill/plugin/hookspec.py +198 -0
- sawmill_parser-0.5.0/sawmill/tui/app.py +1286 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/sawmill/tui/filter_parser.py +10 -0
- sawmill_parser-0.5.0/sawmill/tui/state.py +68 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/sawmill/tui/widgets/__init__.py +4 -2
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/sawmill/tui/widgets/footer.py +1 -6
- sawmill_parser-0.5.0/sawmill/tui/widgets/help_modal.py +71 -0
- sawmill_parser-0.5.0/sawmill/tui/widgets/overview.py +137 -0
- sawmill_parser-0.5.0/sawmill/tui/widgets/rules_prompt.py +178 -0
- sawmill_parser-0.5.0/sawmill/tui/widgets/waive_modal.py +352 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/sawmill/utils/author.py +1 -1
- sawmill_parser-0.5.0/sawmill/utils/globs.py +53 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/sawmill/utils/toml.py +2 -2
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/tests/core/test_aggregation.py +37 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/tests/core/test_config.py +31 -63
- sawmill_parser-0.5.0/tests/core/test_discovery.py +218 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/tests/core/test_filter.py +6 -155
- sawmill_parser-0.5.0/tests/core/test_junit.py +171 -0
- sawmill_parser-0.5.0/tests/core/test_manifest.py +185 -0
- sawmill_parser-0.5.0/tests/core/test_plugin_load.py +25 -0
- sawmill_parser-0.5.0/tests/core/test_report.py +246 -0
- sawmill_parser-0.5.0/tests/core/test_rule_matcher.py +258 -0
- sawmill_parser-0.5.0/tests/core/test_rules.py +336 -0
- sawmill_parser-0.5.0/tests/core/test_runner.py +700 -0
- sawmill_parser-0.5.0/tests/core/test_scaffold.py +92 -0
- sawmill_parser-0.5.0/tests/core/test_severity.py +45 -0
- sawmill_parser-0.5.0/tests/models/test_manifest.py +103 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/tests/models/test_message.py +41 -0
- sawmill_parser-0.5.0/tests/models/test_rule.py +35 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/tests/plugin/test_hookspec.py +44 -10
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/tests/plugins/test_vivado.py +11 -11
- sawmill_parser-0.5.0/tests/test_cli.py +89 -0
- sawmill_parser-0.5.0/tests/test_cli_check.py +373 -0
- sawmill_parser-0.5.0/tests/test_cli_common.py +102 -0
- sawmill_parser-0.5.0/tests/test_cli_init.py +199 -0
- sawmill_parser-0.5.0/tests/test_cli_plugin_discovery.py +83 -0
- sawmill_parser-0.5.0/tests/test_cli_report.py +270 -0
- sawmill_parser-0.5.0/tests/test_cli_rules.py +366 -0
- sawmill_parser-0.5.0/tests/test_cli_view.py +179 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/tests/test_plugin_api.py +0 -32
- sawmill_parser-0.5.0/tests/test_removed_modules.py +29 -0
- sawmill_parser-0.5.0/tests/tui/conftest.py +147 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/tests/tui/test_app.py +400 -76
- sawmill_parser-0.5.0/tests/tui/test_base_styles.py +99 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/tests/tui/test_filter_parser.py +16 -0
- sawmill_parser-0.5.0/tests/tui/test_overview.py +226 -0
- sawmill_parser-0.5.0/tests/tui/test_refresh_hide.py +334 -0
- sawmill_parser-0.5.0/tests/tui/test_rules_prompt.py +96 -0
- sawmill_parser-0.5.0/tests/tui/test_single_log_waive.py +183 -0
- sawmill_parser-0.5.0/tests/tui/test_state.py +86 -0
- sawmill_parser-0.5.0/tests/tui/test_waive_action.py +216 -0
- sawmill_parser-0.5.0/tests/tui/test_waive_modal.py +265 -0
- sawmill_parser-0.5.0/tests/tui/test_windowed_table.py +200 -0
- sawmill_parser-0.5.0/tests/utils/test_globs.py +43 -0
- sawmill_parser-0.5.0/tools/bench/bench_message.py +157 -0
- sawmill_parser-0.5.0/tools/bench/gen_xcelium_log.py +146 -0
- sawmill_parser-0.5.0/tools/bench/run_bench.py +246 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/tools/sawmill-plugin-generator/src/sawmill_plugin_generator/generator.py +1 -1
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/tools/sawmill-plugin-generator/src/sawmill_plugin_generator/templates/claude.md.j2 +11 -6
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/tools/sawmill-plugin-generator/src/sawmill_plugin_generator/templates/plugin.py.j2 +17 -13
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/tools/sawmill-plugin-generator/src/sawmill_plugin_generator/templates/test_parsing.py.j2 +13 -11
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/tools/sawmill-plugin-generator/src/sawmill_plugin_generator/templates/test_plugin_contract.py.j2 +6 -4
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/tools/sawmill-plugin-generator/tests/test_generator.py +1 -1
- sawmill_parser-0.3.2/CHANGELOG.md +0 -701
- sawmill_parser-0.3.2/CLAUDE.md +0 -241
- sawmill_parser-0.3.2/Dockerfile +0 -52
- sawmill_parser-0.3.2/PKG-INFO +0 -210
- sawmill_parser-0.3.2/PRD.md +0 -590
- sawmill_parser-0.3.2/PROMPT.md +0 -230
- sawmill_parser-0.3.2/README.md +0 -168
- sawmill_parser-0.3.2/STATUS.md +0 -389
- sawmill_parser-0.3.2/docs/getting-started/quickstart.rst +0 -86
- sawmill_parser-0.3.2/docs/getting-started/what-is-sawmill.rst +0 -64
- sawmill_parser-0.3.2/docs/reference/cli-reference.rst +0 -135
- sawmill_parser-0.3.2/docs/reference/file-formats.rst +0 -148
- sawmill_parser-0.3.2/docs/user-guide/ci-integration.rst +0 -184
- sawmill_parser-0.3.2/docs/user-guide/cli-usage.rst +0 -166
- sawmill_parser-0.3.2/docs/user-guide/sawmill-directory.rst +0 -98
- sawmill_parser-0.3.2/docs/user-guide/tui-usage.rst +0 -180
- sawmill_parser-0.3.2/docs/user-guide/waivers.rst +0 -141
- sawmill_parser-0.3.2/ralph-loop.sh +0 -361
- sawmill_parser-0.3.2/sawmill/cli/commands.py +0 -620
- sawmill_parser-0.3.2/sawmill/cli/formatting.py +0 -250
- sawmill_parser-0.3.2/sawmill/cli/processing.py +0 -236
- sawmill_parser-0.3.2/sawmill/cli/reporting.py +0 -250
- sawmill_parser-0.3.2/sawmill/core/__init__.py +0 -68
- sawmill_parser-0.3.2/sawmill/core/suppress.py +0 -89
- sawmill_parser-0.3.2/sawmill/core/waiver.py +0 -588
- sawmill_parser-0.3.2/sawmill/models/waiver.py +0 -61
- sawmill_parser-0.3.2/sawmill/plugin/hookspec.py +0 -186
- sawmill_parser-0.3.2/sawmill/tui/app.py +0 -1109
- sawmill_parser-0.3.2/sawmill/tui/session.py +0 -135
- sawmill_parser-0.3.2/sawmill/tui/widgets/quit_modal.py +0 -103
- sawmill_parser-0.3.2/sawmill/tui/widgets/waive_modal.py +0 -242
- sawmill_parser-0.3.2/sawmill/utils/dirs.py +0 -66
- sawmill_parser-0.3.2/tests/core/test_suppress.py +0 -163
- sawmill_parser-0.3.2/tests/core/test_waiver.py +0 -680
- sawmill_parser-0.3.2/tests/core/test_waiver_matching.py +0 -693
- sawmill_parser-0.3.2/tests/test_ci_mode.py +0 -534
- sawmill_parser-0.3.2/tests/test_ci_report.py +0 -652
- sawmill_parser-0.3.2/tests/test_ci_waivers.py +0 -609
- sawmill_parser-0.3.2/tests/test_cli.py +0 -399
- sawmill_parser-0.3.2/tests/test_cli_formats.py +0 -331
- sawmill_parser-0.3.2/tests/test_cli_id_filter.py +0 -362
- sawmill_parser-0.3.2/tests/test_cli_integration.py +0 -594
- sawmill_parser-0.3.2/tests/test_cli_plugin_discovery.py +0 -126
- sawmill_parser-0.3.2/tests/test_cli_summary.py +0 -240
- sawmill_parser-0.3.2/tests/test_waiver_generation.py +0 -786
- sawmill_parser-0.3.2/tests/tui/test_base_styles.py +0 -194
- sawmill_parser-0.3.2/tests/tui/test_persistence.py +0 -724
- sawmill_parser-0.3.2/tests/tui/test_suppress.py +0 -287
- sawmill_parser-0.3.2/tests/tui/test_tabs.py +0 -373
- sawmill_parser-0.3.2/tests/tui/test_waive.py +0 -464
- sawmill_parser-0.3.2/tests/utils/test_dirs.py +0 -84
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/.gitattributes +0 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/.github/workflows/docs.yml +0 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/.github/workflows/publish.yml +0 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/.pre-commit-config.yaml +0 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/assets/sawmill.png +0 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/docs/Makefile +0 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/sawmill/__init__.py +0 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/sawmill/__main__.py +0 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/sawmill/cli/__init__.py +0 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/sawmill/models/filter_def.py +0 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/sawmill/models/plugin_api.py +0 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/sawmill/tui/__init__.py +0 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/sawmill/tui/base.tcss +0 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/sawmill/tui/theme.py +0 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/sawmill/utils/__init__.py +0 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/sawmill/utils/git.py +0 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/sourceme +0 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/tests/__init__.py +0 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/tests/conftest.py +0 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/tests/core/__init__.py +0 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/tests/core/test_plugin_autodetect.py +0 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/tests/core/test_plugin_manager.py +0 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/tests/fixtures/vivado.log +0 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/tests/models/__init__.py +0 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/tests/models/test_filter_def.py +0 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/tests/plugin/__init__.py +0 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/tests/plugins/__init__.py +0 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/tests/test_fixtures.py +0 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/tests/test_project_setup.py +0 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/tests/tui/__init__.py +0 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/tests/tui/test_footer.py +0 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/tests/utils/__init__.py +0 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/tests/utils/test_git.py +0 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/tests/utils/test_toml.py +0 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/tools/sawmill-plugin-generator/pyproject.toml +0 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/tools/sawmill-plugin-generator/src/sawmill_plugin_generator/__init__.py +0 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/tools/sawmill-plugin-generator/src/sawmill_plugin_generator/cli.py +0 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/tools/sawmill-plugin-generator/src/sawmill_plugin_generator/names.py +0 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/tools/sawmill-plugin-generator/src/sawmill_plugin_generator/templates/conftest.py.j2 +0 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/tools/sawmill-plugin-generator/src/sawmill_plugin_generator/templates/gitignore.j2 +0 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/tools/sawmill-plugin-generator/src/sawmill_plugin_generator/templates/init.py.j2 +0 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/tools/sawmill-plugin-generator/src/sawmill_plugin_generator/templates/makefile.j2 +0 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/tools/sawmill-plugin-generator/src/sawmill_plugin_generator/templates/patterns.py.j2 +0 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/tools/sawmill-plugin-generator/src/sawmill_plugin_generator/templates/pyproject.toml.j2 +0 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/tools/sawmill-plugin-generator/src/sawmill_plugin_generator/templates/readme.md.j2 +0 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/tools/sawmill-plugin-generator/src/sawmill_plugin_generator/templates/sample_log.j2 +0 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/tools/sawmill-plugin-generator/src/sawmill_plugin_generator/templates/test_detection.py.j2 +0 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/tools/sawmill-plugin-generator/src/sawmill_plugin_generator/templates/test_severity.py.j2 +0 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/tools/sawmill-plugin-generator/tests/test_cli.py +0 -0
- {sawmill_parser-0.3.2 → sawmill_parser-0.5.0}/tools/sawmill-plugin-generator/tests/test_names.py +0 -0
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# Sawmill
|
|
2
|
+
|
|
3
|
+
Terminal log analyser for structured tool logs. Plugins parse tool-specific
|
|
4
|
+
formats (Vivado, Slang, ...); the base app filters, groups, waives
|
|
5
|
+
and reports. Batch CLI for CI, Textual TUI for interactive triage.
|
|
6
|
+
|
|
7
|
+
## Setup
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
source sourceme # creates .venv with uv, installs dev extras, installs pre-commit
|
|
11
|
+
source sourceme --clean # rebuild the venv
|
|
12
|
+
pytest tests/ -v
|
|
13
|
+
python -m sphinx -b html docs docs/_build/html # needs `uv sync --all-extras`
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Always use `uv`, never `pip`. Activate `.venv` before running anything.
|
|
17
|
+
|
|
18
|
+
## Layout
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
sawmill/
|
|
22
|
+
__main__.py CLI entry point
|
|
23
|
+
cli/ rich-click commands, processing, reporting, formatting
|
|
24
|
+
core/ filter, severity, aggregation, config, plugin manager, waivers
|
|
25
|
+
models/ pydantic models: Message, FilterDefinition, Waiver, plugin API
|
|
26
|
+
plugin/ SawmillPlugin base class and pluggy hookspec
|
|
27
|
+
tui/ Textual app, session persistence, widgets
|
|
28
|
+
utils/ dirs, git, toml, author helpers
|
|
29
|
+
tests/ mirrors sawmill/ (sawmill/core/filter.py -> tests/core/test_filter.py)
|
|
30
|
+
tools/bench/ synthetic log generator and benchmark runner
|
|
31
|
+
tools/sawmill-plugin-generator/ scaffolds a new plugin package
|
|
32
|
+
docs/ Sphinx, furo theme; built by .github/workflows/docs.yml
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Plugins live in their own repositories and register through the
|
|
36
|
+
`sawmill.plugins` entry point. There are no built-in plugins.
|
|
37
|
+
|
|
38
|
+
## Architecture rules
|
|
39
|
+
|
|
40
|
+
**The plugin is the sole source of truth for the log format.** The base app
|
|
41
|
+
never parses log content, detects severity, or assumes severity names exist.
|
|
42
|
+
|
|
43
|
+
- Plugins implement `can_handle`, `load_and_parse` (an iterator of `Message`,
|
|
44
|
+
plugin API 2), `get_severity_levels` (required), and optionally
|
|
45
|
+
`get_filters`, `get_grouping_fields`, `extract_file_reference`.
|
|
46
|
+
- Severity comparisons in the base app use `SeverityLevel.level` (an int),
|
|
47
|
+
never the string id. Any severity scheme a plugin defines must work.
|
|
48
|
+
- Large logs are streamed; see `docs/performance/` before touching the
|
|
49
|
+
load path or the TUI table.
|
|
50
|
+
|
|
51
|
+
## In-progress redesign
|
|
52
|
+
|
|
53
|
+
The waiver and suppression system is being replaced by a manifest and rule
|
|
54
|
+
model. The design, decisions and task plan are in
|
|
55
|
+
`docs/development/manifest-design.rst`. Read it before changing anything
|
|
56
|
+
under `core/waiver.py`, `core/suppress.py`, `core/config.py`, the CLI
|
|
57
|
+
options, or TUI session persistence. The user guide pages on waivers and the
|
|
58
|
+
`.sawmill` directory describe the old behaviour until Stage D of that plan.
|
|
59
|
+
|
|
60
|
+
## Coding standards
|
|
61
|
+
|
|
62
|
+
- PEP 8, type hints on every signature, docstrings on public classes and
|
|
63
|
+
functions. Ruff and mypy run in pre-commit.
|
|
64
|
+
- Tests alongside or before implementation. Async Textual tests use
|
|
65
|
+
`app.run_test()` with `pilot`.
|
|
66
|
+
- `tomli` for reading TOML, `tomli_w` for writing. Validate regexes before
|
|
67
|
+
storing them.
|
|
68
|
+
|
|
69
|
+
## Git
|
|
70
|
+
|
|
71
|
+
- Short, conventional commit messages. One logical change per commit.
|
|
72
|
+
- No `Co-Authored-By` or generated-by lines.
|
|
73
|
+
- Never modify git config.
|
|
74
|
+
- Use git worktrees for parallel work.
|
|
75
|
+
|
|
76
|
+
## Testing
|
|
77
|
+
|
|
78
|
+
- testing will require additional plugins; see table below.
|
|
79
|
+
|
|
80
|
+
| Tool | Install Path |
|
|
81
|
+
|---|---|
|
|
82
|
+
| Xilinx Vivado | https://github.com/sjalloq/sawmill-plugin-vivado.git |
|
|
83
|
+
| Slang | https://github.com/sjalloq/sawmill-plugin-slang.git |
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: sawmill-parser
|
|
3
|
+
Version: 0.5.0
|
|
4
|
+
Summary: A configurable TUI for post-processing and filtering structured tool logs
|
|
5
|
+
Project-URL: Homepage, https://github.com/sjalloq/sawmill
|
|
6
|
+
Project-URL: Documentation, https://sjalloq.github.io/sawmill
|
|
7
|
+
Project-URL: Repository, https://github.com/sjalloq/sawmill
|
|
8
|
+
Author: Sawmill Contributors
|
|
9
|
+
License: MIT
|
|
10
|
+
Keywords: eda,filter,log,terminal,tui
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Environment :: Console
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Topic :: Utilities
|
|
21
|
+
Requires-Python: >=3.10
|
|
22
|
+
Requires-Dist: pluggy>=1.3.0
|
|
23
|
+
Requires-Dist: pydantic>=2.0.0
|
|
24
|
+
Requires-Dist: rich-click>=1.7.0
|
|
25
|
+
Requires-Dist: rich>=13.0.0
|
|
26
|
+
Requires-Dist: textual>=0.40.0
|
|
27
|
+
Requires-Dist: tomli-w>=1.0.0
|
|
28
|
+
Requires-Dist: tomli>=2.0.0
|
|
29
|
+
Requires-Dist: tomlkit>=0.12
|
|
30
|
+
Provides-Extra: dev
|
|
31
|
+
Requires-Dist: mypy>=1.0.0; extra == 'dev'
|
|
32
|
+
Requires-Dist: pre-commit>=3.0.0; extra == 'dev'
|
|
33
|
+
Requires-Dist: pytest-asyncio>=0.21.0; extra == 'dev'
|
|
34
|
+
Requires-Dist: pytest-cov>=4.0.0; extra == 'dev'
|
|
35
|
+
Requires-Dist: pytest>=7.0.0; extra == 'dev'
|
|
36
|
+
Requires-Dist: ruff>=0.4.0; extra == 'dev'
|
|
37
|
+
Requires-Dist: sawmill-plugin-slang; extra == 'dev'
|
|
38
|
+
Requires-Dist: sawmill-plugin-vivado; extra == 'dev'
|
|
39
|
+
Provides-Extra: docs
|
|
40
|
+
Requires-Dist: furo; extra == 'docs'
|
|
41
|
+
Requires-Dist: sphinx; extra == 'docs'
|
|
42
|
+
Requires-Dist: sphinx-autodoc-typehints; extra == 'docs'
|
|
43
|
+
Requires-Dist: sphinx-copybutton; extra == 'docs'
|
|
44
|
+
Description-Content-Type: text/markdown
|
|
45
|
+
|
|
46
|
+
<p align="center">
|
|
47
|
+
<img src="assets/sawmill.png" alt="Sawmill - Cutting through the noise" width="600">
|
|
48
|
+
</p>
|
|
49
|
+
|
|
50
|
+
<h1 align="center">Sawmill</h1>
|
|
51
|
+
|
|
52
|
+
<p align="center">
|
|
53
|
+
<strong>A plugin-driven terminal log analyser</strong>
|
|
54
|
+
</p>
|
|
55
|
+
|
|
56
|
+
Sawmill filters, groups and waives messages from structured tool logs such as
|
|
57
|
+
Vivado and Slang output. A batch CLI gates CI pipelines on log
|
|
58
|
+
content; a terminal UI handles interactive triage. Plugins own the parsing,
|
|
59
|
+
so any log format can be supported.
|
|
60
|
+
|
|
61
|
+
## Install
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
uv tool install sawmill-parser sawmill-plugin-vivado
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Or from a clone:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
source sourceme # creates .venv with uv and installs dev extras
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Usage
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
sawmill vivado.log # open one log in the TUI
|
|
77
|
+
sawmill init # create .sawmill/manifest.toml
|
|
78
|
+
sawmill init --target pnr 'build/pnr/*.log' # add a target
|
|
79
|
+
sawmill view # TUI over every target
|
|
80
|
+
sawmill check --report build/report.json # CI gate: exit 1 on unwaived failures
|
|
81
|
+
sawmill report --format junit -o build/sawmill.xml
|
|
82
|
+
sawmill rules unused # rules that matched nothing
|
|
83
|
+
sawmill plugins list
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Targets and rules live in a checked-in `.sawmill/` directory: a
|
|
87
|
+
`manifest.toml` naming the targets (plugin plus log globs) and rule files
|
|
88
|
+
under `.sawmill/rules/` that waive expected messages.
|
|
89
|
+
|
|
90
|
+
Full documentation, including the manifest and rule formats, CLI reference,
|
|
91
|
+
TUI guide, CI integration and plugin authoring, is at
|
|
92
|
+
https://sjalloq.github.io/sawmill.
|
|
93
|
+
|
|
94
|
+
## Plugins
|
|
95
|
+
|
|
96
|
+
| Plugin | Repository |
|
|
97
|
+
|--------|------------|
|
|
98
|
+
| `vivado` | https://github.com/sjalloq/sawmill-plugin-vivado |
|
|
99
|
+
| `slang` | https://github.com/sjalloq/sawmill-plugin-slang |
|
|
100
|
+
|
|
101
|
+
Plugins register through the `sawmill.plugins` entry point and are
|
|
102
|
+
auto-detected from log content. `tools/sawmill-plugin-generator` scaffolds a
|
|
103
|
+
new one.
|
|
104
|
+
|
|
105
|
+
## Development
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
source sourceme
|
|
109
|
+
pytest tests/ -v
|
|
110
|
+
pre-commit run --all-files
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## License
|
|
114
|
+
|
|
115
|
+
MIT
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="assets/sawmill.png" alt="Sawmill - Cutting through the noise" width="600">
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<h1 align="center">Sawmill</h1>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
<strong>A plugin-driven terminal log analyser</strong>
|
|
9
|
+
</p>
|
|
10
|
+
|
|
11
|
+
Sawmill filters, groups and waives messages from structured tool logs such as
|
|
12
|
+
Vivado and Slang output. A batch CLI gates CI pipelines on log
|
|
13
|
+
content; a terminal UI handles interactive triage. Plugins own the parsing,
|
|
14
|
+
so any log format can be supported.
|
|
15
|
+
|
|
16
|
+
## Install
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
uv tool install sawmill-parser sawmill-plugin-vivado
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Or from a clone:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
source sourceme # creates .venv with uv and installs dev extras
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Usage
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
sawmill vivado.log # open one log in the TUI
|
|
32
|
+
sawmill init # create .sawmill/manifest.toml
|
|
33
|
+
sawmill init --target pnr 'build/pnr/*.log' # add a target
|
|
34
|
+
sawmill view # TUI over every target
|
|
35
|
+
sawmill check --report build/report.json # CI gate: exit 1 on unwaived failures
|
|
36
|
+
sawmill report --format junit -o build/sawmill.xml
|
|
37
|
+
sawmill rules unused # rules that matched nothing
|
|
38
|
+
sawmill plugins list
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Targets and rules live in a checked-in `.sawmill/` directory: a
|
|
42
|
+
`manifest.toml` naming the targets (plugin plus log globs) and rule files
|
|
43
|
+
under `.sawmill/rules/` that waive expected messages.
|
|
44
|
+
|
|
45
|
+
Full documentation, including the manifest and rule formats, CLI reference,
|
|
46
|
+
TUI guide, CI integration and plugin authoring, is at
|
|
47
|
+
https://sjalloq.github.io/sawmill.
|
|
48
|
+
|
|
49
|
+
## Plugins
|
|
50
|
+
|
|
51
|
+
| Plugin | Repository |
|
|
52
|
+
|--------|------------|
|
|
53
|
+
| `vivado` | https://github.com/sjalloq/sawmill-plugin-vivado |
|
|
54
|
+
| `slang` | https://github.com/sjalloq/sawmill-plugin-slang |
|
|
55
|
+
|
|
56
|
+
Plugins register through the `sawmill.plugins` entry point and are
|
|
57
|
+
auto-detected from log content. `tools/sawmill-plugin-generator` scaffolds a
|
|
58
|
+
new one.
|
|
59
|
+
|
|
60
|
+
## Development
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
source sourceme
|
|
64
|
+
pytest tests/ -v
|
|
65
|
+
pre-commit run --all-files
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## License
|
|
69
|
+
|
|
70
|
+
MIT
|
|
@@ -18,14 +18,13 @@ templates_path = ["_templates"]
|
|
|
18
18
|
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
|
|
19
19
|
|
|
20
20
|
html_theme = "furo"
|
|
21
|
-
html_static_path = ["_static"]
|
|
22
21
|
|
|
23
22
|
autodoc_member_order = "bysource"
|
|
24
23
|
autodoc_typehints = "description"
|
|
25
24
|
|
|
26
|
-
#
|
|
27
|
-
#
|
|
28
|
-
|
|
25
|
+
# Render Google-style ``Attributes:`` sections as ``:ivar:`` fields so they
|
|
26
|
+
# do not duplicate the attribute entries autodoc already generates.
|
|
27
|
+
napoleon_use_ivar = True
|
|
29
28
|
|
|
30
29
|
intersphinx_mapping = {
|
|
31
30
|
"python": ("https://docs.python.org/3", None),
|
|
@@ -68,37 +68,6 @@ Run manually:
|
|
|
68
68
|
|
|
69
69
|
$ pre-commit run --all-files
|
|
70
70
|
|
|
71
|
-
Docker dev loop
|
|
72
|
-
---------------
|
|
73
|
-
|
|
74
|
-
The ``ralph-loop.sh`` script runs Claude Code in a Docker container for
|
|
75
|
-
autonomous development iterations:
|
|
76
|
-
|
|
77
|
-
.. code-block:: console
|
|
78
|
-
|
|
79
|
-
$ ./ralph-loop.sh --iterations 3
|
|
80
|
-
$ ./ralph-loop.sh --continuous
|
|
81
|
-
|
|
82
|
-
Options:
|
|
83
|
-
|
|
84
|
-
``--iterations N``
|
|
85
|
-
Run N iterations (default: 1).
|
|
86
|
-
|
|
87
|
-
``--continuous``
|
|
88
|
-
Run until all tasks complete or an error occurs.
|
|
89
|
-
|
|
90
|
-
``--dry-run``
|
|
91
|
-
Show what would be done without executing.
|
|
92
|
-
|
|
93
|
-
``--no-docker``
|
|
94
|
-
Run directly on the host instead of in a container.
|
|
95
|
-
|
|
96
|
-
``--interactive``
|
|
97
|
-
Drop into an interactive shell after each iteration.
|
|
98
|
-
|
|
99
|
-
The ``Dockerfile`` builds a container with Python 3.11, Node.js, and
|
|
100
|
-
Claude Code CLI pre-installed.
|
|
101
|
-
|
|
102
71
|
Building docs
|
|
103
72
|
-------------
|
|
104
73
|
|
|
@@ -106,8 +75,8 @@ Install documentation dependencies and build:
|
|
|
106
75
|
|
|
107
76
|
.. code-block:: console
|
|
108
77
|
|
|
109
|
-
$
|
|
110
|
-
$
|
|
78
|
+
$ uv sync --all-extras
|
|
79
|
+
$ python -m sphinx -b html docs docs/_build/html
|
|
111
80
|
|
|
112
81
|
The built documentation is in ``docs/_build/html/``. Open
|
|
113
82
|
``docs/_build/html/index.html`` in a browser to review.
|