woolly 0.1.0__tar.gz → 0.3.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.
Files changed (59) hide show
  1. woolly-0.3.0/.coverage +0 -0
  2. woolly-0.3.0/.github/workflows/lint.yml +68 -0
  3. woolly-0.3.0/.github/workflows/tests.yml +111 -0
  4. woolly-0.3.0/PKG-INFO +322 -0
  5. woolly-0.3.0/README.md +292 -0
  6. {woolly-0.1.0 → woolly-0.3.0}/pyproject.toml +43 -3
  7. woolly-0.3.0/tests/__init__.py +1 -0
  8. woolly-0.3.0/tests/conftest.py +293 -0
  9. woolly-0.3.0/tests/functional/__init__.py +1 -0
  10. woolly-0.3.0/tests/functional/test_cli.py +323 -0
  11. woolly-0.3.0/tests/functional/test_optional_flag.py +277 -0
  12. woolly-0.3.0/tests/unit/__init__.py +1 -0
  13. woolly-0.3.0/tests/unit/test_cache.py +236 -0
  14. woolly-0.3.0/tests/unit/test_commands/__init__.py +1 -0
  15. woolly-0.3.0/tests/unit/test_commands/test_check.py +285 -0
  16. woolly-0.3.0/tests/unit/test_commands/test_other_commands.py +98 -0
  17. woolly-0.3.0/tests/unit/test_debug.py +317 -0
  18. woolly-0.3.0/tests/unit/test_languages/__init__.py +1 -0
  19. woolly-0.3.0/tests/unit/test_languages/test_base.py +365 -0
  20. woolly-0.3.0/tests/unit/test_languages/test_python.py +294 -0
  21. woolly-0.3.0/tests/unit/test_languages/test_registry.py +162 -0
  22. woolly-0.3.0/tests/unit/test_languages/test_rust.py +220 -0
  23. woolly-0.3.0/tests/unit/test_optional_dependencies.py +383 -0
  24. woolly-0.3.0/tests/unit/test_progress.py +102 -0
  25. woolly-0.3.0/tests/unit/test_reporters/__init__.py +1 -0
  26. woolly-0.3.0/tests/unit/test_reporters/test_base.py +288 -0
  27. woolly-0.3.0/tests/unit/test_reporters/test_json.py +181 -0
  28. woolly-0.3.0/tests/unit/test_reporters/test_markdown.py +135 -0
  29. woolly-0.3.0/tests/unit/test_reporters/test_registry.py +177 -0
  30. woolly-0.3.0/tests/unit/test_reporters/test_stdout.py +104 -0
  31. woolly-0.3.0/uv.lock +668 -0
  32. woolly-0.3.0/woolly/__main__.py +21 -0
  33. woolly-0.3.0/woolly/cache.py +88 -0
  34. woolly-0.3.0/woolly/commands/__init__.py +27 -0
  35. woolly-0.3.0/woolly/commands/check.py +422 -0
  36. woolly-0.3.0/woolly/commands/clear_cache.py +42 -0
  37. woolly-0.3.0/woolly/commands/list_formats.py +24 -0
  38. woolly-0.3.0/woolly/commands/list_languages.py +26 -0
  39. woolly-0.3.0/woolly/debug.py +195 -0
  40. woolly-0.3.0/woolly/http.py +34 -0
  41. woolly-0.3.0/woolly/languages/__init__.py +102 -0
  42. woolly-0.3.0/woolly/languages/base.py +374 -0
  43. woolly-0.3.0/woolly/languages/python.py +200 -0
  44. woolly-0.3.0/woolly/languages/rust.py +130 -0
  45. woolly-0.3.0/woolly/progress.py +69 -0
  46. woolly-0.3.0/woolly/reporters/__init__.py +111 -0
  47. woolly-0.3.0/woolly/reporters/base.py +213 -0
  48. woolly-0.3.0/woolly/reporters/json.py +175 -0
  49. woolly-0.3.0/woolly/reporters/markdown.py +117 -0
  50. woolly-0.3.0/woolly/reporters/stdout.py +75 -0
  51. woolly-0.1.0/PKG-INFO +0 -101
  52. woolly-0.1.0/README.md +0 -73
  53. woolly-0.1.0/uv.lock +0 -127
  54. woolly-0.1.0/woolly/__main__.py +0 -482
  55. {woolly-0.1.0 → woolly-0.3.0}/.github/workflows/publish.yml +0 -0
  56. {woolly-0.1.0 → woolly-0.3.0}/.gitignore +0 -0
  57. {woolly-0.1.0 → woolly-0.3.0}/.python-version +0 -0
  58. {woolly-0.1.0 → woolly-0.3.0}/LICENSE +0 -0
  59. {woolly-0.1.0 → woolly-0.3.0}/woolly/__init__.py +0 -0
woolly-0.3.0/.coverage ADDED
Binary file
@@ -0,0 +1,68 @@
1
+ name: Lint
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ concurrency:
10
+ group: ${{ github.workflow }}-${{ github.ref }}
11
+ cancel-in-progress: true
12
+
13
+ jobs:
14
+ ruff:
15
+ name: Ruff (Python ${{ matrix.python-version }})
16
+ runs-on: ubuntu-latest
17
+ strategy:
18
+ fail-fast: false
19
+ matrix:
20
+ python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
21
+
22
+ steps:
23
+ - name: Checkout repository
24
+ uses: actions/checkout@v4
25
+
26
+ - name: Install uv
27
+ uses: astral-sh/setup-uv@v4
28
+ with:
29
+ enable-cache: true
30
+
31
+ - name: Set up Python ${{ matrix.python-version }}
32
+ run: uv python install ${{ matrix.python-version }}
33
+
34
+ - name: Install dependencies
35
+ run: uv sync --group dev --python ${{ matrix.python-version }}
36
+
37
+ - name: Run ruff check
38
+ run: uv run ruff check woolly tests
39
+
40
+ - name: Run ruff format check
41
+ run: uv run ruff format --check woolly tests
42
+
43
+ pyright:
44
+ name: Pyright (Python ${{ matrix.python-version }})
45
+ runs-on: ubuntu-latest
46
+ strategy:
47
+ fail-fast: false
48
+ matrix:
49
+ python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
50
+
51
+ steps:
52
+ - name: Checkout repository
53
+ uses: actions/checkout@v4
54
+
55
+ - name: Install uv
56
+ uses: astral-sh/setup-uv@v4
57
+ with:
58
+ enable-cache: true
59
+
60
+ - name: Set up Python ${{ matrix.python-version }}
61
+ run: uv python install ${{ matrix.python-version }}
62
+
63
+ - name: Install dependencies
64
+ run: uv sync --group dev --group test --python ${{ matrix.python-version }}
65
+
66
+ - name: Run pyright
67
+ run: uv run pyright woolly --pythonversion ${{ matrix.python-version }}
68
+
@@ -0,0 +1,111 @@
1
+ name: Tests
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ concurrency:
10
+ group: ${{ github.workflow }}-${{ github.ref }}
11
+ cancel-in-progress: true
12
+
13
+ jobs:
14
+ unit-tests:
15
+ name: Unit Tests (Python ${{ matrix.python-version }})
16
+ runs-on: ubuntu-latest
17
+ strategy:
18
+ fail-fast: false
19
+ matrix:
20
+ python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
21
+
22
+ steps:
23
+ - name: Checkout repository
24
+ uses: actions/checkout@v4
25
+
26
+ - name: Install uv
27
+ uses: astral-sh/setup-uv@v4
28
+ with:
29
+ enable-cache: true
30
+
31
+ - name: Install dependencies
32
+ run: uv sync --group test
33
+
34
+ - name: Run unit tests with coverage
35
+ run: uv run pytest tests/unit --cov=woolly --cov-report=xml --cov-report=term-missing
36
+
37
+ - name: Upload coverage reports
38
+ uses: codecov/codecov-action@v4
39
+ with:
40
+ files: ./coverage.xml
41
+ fail_ci_if_error: false
42
+ env_vars: OS,PYTHON
43
+ disable_search: true
44
+ flags: unit
45
+ token: ${{ secrets.CODECOV_TOKEN }}
46
+
47
+ functional-tests:
48
+ name: Functional Tests (Fedora)
49
+ runs-on: ubuntu-latest
50
+ container:
51
+ image: fedora:latest
52
+
53
+ steps:
54
+ - name: Install system dependencies
55
+ run: |
56
+ dnf install -y \
57
+ git \
58
+ python3 \
59
+ python3-pip \
60
+ dnf-plugins-core \
61
+ findutils
62
+
63
+ - name: Checkout repository
64
+ uses: actions/checkout@v4
65
+
66
+ - name: Install uv
67
+ run: |
68
+ curl -LsSf https://astral.sh/uv/install.sh | sh
69
+ echo "$HOME/.local/bin" >> $GITHUB_PATH
70
+
71
+ - name: Install dependencies
72
+ run: |
73
+ export PATH="$HOME/.local/bin:$PATH"
74
+ uv sync --group test
75
+
76
+ - name: Run fast functional tests
77
+ run: |
78
+ export PATH="$HOME/.local/bin:$PATH"
79
+ uv run pytest tests/functional --cov=woolly --cov-report=xml --cov-report=term-missing -v --tb=short -m "not slow"
80
+
81
+ - name: Run slow functional tests (API + Fedora integration)
82
+ run: |
83
+ export PATH="$HOME/.local/bin:$PATH"
84
+ uv run pytest tests/functional --cov=woolly --cov-report=xml --cov-report=term-missing -v --tb=short -m "slow"
85
+
86
+ - name: Upload coverage reports
87
+ uses: codecov/codecov-action@v4
88
+ with:
89
+ files: ./coverage.xml
90
+ fail_ci_if_error: false
91
+ env_vars: OS,PYTHON
92
+ disable_search: true
93
+ flags: functional
94
+ token: ${{ secrets.CODECOV_TOKEN }}
95
+
96
+ all-tests-pass:
97
+ name: All Tests Pass
98
+ runs-on: ubuntu-latest
99
+ needs: [unit-tests, functional-tests]
100
+ if: always()
101
+ steps:
102
+ - name: Check all jobs passed
103
+ run: |
104
+ if [[ "${{ needs.unit-tests.result }}" != "success" ]] || \
105
+ [[ "${{ needs.functional-tests.result }}" != "success" ]]; then
106
+ echo "Some tests failed"
107
+ echo " unit-tests: ${{ needs.unit-tests.result }}"
108
+ echo " functional-tests: ${{ needs.functional-tests.result }}"
109
+ exit 1
110
+ fi
111
+ echo "All tests passed!"
woolly-0.3.0/PKG-INFO ADDED
@@ -0,0 +1,322 @@
1
+ Metadata-Version: 2.4
2
+ Name: woolly
3
+ Version: 0.3.0
4
+ Summary: Check if package dependencies are available in Fedora. Supports Rust, Python, and more.
5
+ Author-email: Rodolfo Olivieri <rodolfo.olivieri3@gmail.com>
6
+ License-File: LICENSE
7
+ Classifier: Development Status :: 2 - Pre-Alpha
8
+ Classifier: Environment :: Console
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: Intended Audience :: Information Technology
11
+ Classifier: Intended Audience :: System Administrators
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Natural Language :: English
14
+ Classifier: Operating System :: POSIX :: Linux
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3 :: Only
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Programming Language :: Python :: 3.14
22
+ Classifier: Topic :: System :: Systems Administration
23
+ Classifier: Topic :: Utilities
24
+ Requires-Python: >=3.10
25
+ Requires-Dist: cyclopts>=4.3.0
26
+ Requires-Dist: httpx>=0.28.0
27
+ Requires-Dist: pydantic>=2.10.0
28
+ Requires-Dist: rich>=14.2.0
29
+ Description-Content-Type: text/markdown
30
+
31
+ # 🐑 Woolly
32
+
33
+ **Check if package dependencies are available in Fedora.**
34
+
35
+ Woolly analyzes package dependencies from various language ecosystems and checks their availability in Fedora repositories, helping packagers estimate the effort needed to bring a package to Fedora.
36
+
37
+ > ⚠️ **Experimental Software**
38
+ >
39
+ > This project is still experimental and may not get things right all the time.
40
+ > Results should be verified manually, especially for complex dependency trees.
41
+ > Platform-specific dependencies (like `windows-*` crates) may be flagged as missing
42
+ > even though they're not needed on Linux.
43
+
44
+ ## What does "woolly" mean?
45
+
46
+ Nothing. I just liked the name. 🐑
47
+
48
+ ## Features
49
+
50
+ - **Multi-language support** — Analyze dependencies from Rust (crates.io) and Python (PyPI)
51
+ - **Multiple output formats** — Console output, JSON, and Markdown reports
52
+ - **Optional dependency tracking** — Optionally include and separately track optional dependencies
53
+ - **Smart caching** — Caches API responses and dnf queries to speed up repeated analyses
54
+ - **Progress tracking** — Real-time progress bar showing analysis status
55
+ - **Debug logging** — Verbose logging mode for troubleshooting
56
+ - **Extensible architecture** — Easy to add new languages and report formats
57
+
58
+ ## Supported Languages
59
+
60
+ | Language | Registry | CLI Flag | Aliases |
61
+ |----------|-----------|-----------------------|-------------------------|
62
+ | Rust | crates.io | `--lang rust` | `-l rs`, `-l crate` |
63
+ | Python | PyPI | `--lang python` | `-l py`, `-l pypi` |
64
+
65
+ ## Output Formats
66
+
67
+ | Format | Description | CLI Flag | Aliases |
68
+ |----------|----------------------------------|----------------------|----------------------|
69
+ | stdout | Rich console output (default) | `--report stdout` | `-r console` |
70
+ | json | JSON file for programmatic use | `--report json` | |
71
+ | markdown | Markdown file for documentation | `--report markdown` | `-r md` |
72
+
73
+ ## Installation
74
+
75
+ ```bash
76
+ # Using uv (recommended)
77
+ uv pip install .
78
+
79
+ # Or run directly without installing
80
+ uv run woolly --help
81
+
82
+ # Using pip
83
+ pip install .
84
+ ```
85
+
86
+ ### Requirements
87
+
88
+ - Python 3.10+
89
+ - `dnf` available on the system (for Fedora package queries)
90
+
91
+ ## Usage
92
+
93
+ ### Basic Usage
94
+
95
+ ```bash
96
+ # Check a Rust crate (default language)
97
+ woolly check ripgrep
98
+
99
+ # Check a Python package
100
+ woolly check --lang python requests
101
+
102
+ # Use language aliases
103
+ woolly check -l py flask
104
+ woolly check -l rs tokio
105
+ ```
106
+
107
+ ### Options
108
+
109
+ ```bash
110
+ # Check a specific version
111
+ woolly check serde --version 1.0.200
112
+
113
+ # Include optional dependencies in the analysis
114
+ woolly check --optional requests -l python
115
+
116
+ # Limit recursion depth
117
+ woolly check --max-depth 10 tokio
118
+
119
+ # Disable progress bar
120
+ woolly check --no-progress serde
121
+
122
+ # Enable debug logging
123
+ woolly check --debug flask -l py
124
+
125
+ # Output as JSON
126
+ woolly check --report json serde
127
+
128
+ # Output as Markdown
129
+ woolly check -r md requests -l py
130
+ ```
131
+
132
+ ### Other Commands
133
+
134
+ ```bash
135
+ # List available languages
136
+ woolly list-languages
137
+
138
+ # List available output formats
139
+ woolly list-formats
140
+
141
+ # Clear the cache
142
+ woolly clear-cache
143
+ ```
144
+
145
+ ## Example Output
146
+
147
+ ### Rust
148
+
149
+ ```bash
150
+ $ woolly check cliclack
151
+
152
+ Analyzing Rust package: cliclack
153
+ Registry: crates.io
154
+ Cache directory: /home/user/.cache/woolly
155
+
156
+ Analyzing Rust dependencies ━━━━━━━━━━━━━━━━━ 100% • 0:00:15 complete!
157
+
158
+ Dependency Summary for 'cliclack' (Rust)
159
+ ╭────────────────────────────┬───────╮
160
+ │ Metric │ Value │
161
+ ├────────────────────────────┼───────┤
162
+ │ Total dependencies checked │ 7 │
163
+ │ Packaged in Fedora │ 0 │
164
+ │ Missing from Fedora │ 1 │
165
+ ╰────────────────────────────┴───────╯
166
+
167
+ Missing packages that need packaging:
168
+ • cliclack
169
+
170
+ Dependency Tree:
171
+ cliclack v0.3.6 • ✗ not packaged
172
+ ├── console v0.16.1 • ✓ packaged (0.16.1)
173
+ │ ├── encode_unicode v1.0.0 • ✓ packaged (1.0.0)
174
+ │ └── windows-sys v0.61.2 • ✗ not packaged
175
+ ...
176
+ ```
177
+
178
+ ### Python
179
+
180
+ ```bash
181
+ $ woolly check --lang python requests
182
+
183
+ Analyzing Python package: requests
184
+ Registry: PyPI
185
+ Cache directory: /home/user/.cache/woolly
186
+
187
+ Analyzing Python dependencies ━━━━━━━━━━━━━━ 100% • 0:00:05 complete!
188
+
189
+ Dependency Summary for 'requests' (Python)
190
+ ╭────────────────────────────┬───────╮
191
+ │ Metric │ Value │
192
+ ├────────────────────────────┼───────┤
193
+ │ Total dependencies checked │ 5 │
194
+ │ Packaged in Fedora │ 5 │
195
+ │ Missing from Fedora │ 0 │
196
+ ╰────────────────────────────┴───────╯
197
+
198
+ Dependency Tree:
199
+ requests v2.32.3 • ✓ packaged (2.32.3) [python3-requests]
200
+ ├── charset-normalizer v3.4.0 • ✓ packaged (3.4.0) [python3-charset-normalizer]
201
+ ├── idna v3.10 • ✓ packaged (3.10) [python3-idna]
202
+ ├── urllib3 v2.2.3 • ✓ packaged (2.2.3) [python3-urllib3]
203
+ └── certifi v2024.8.30 • ✓ packaged (2024.8.30) [python3-certifi]
204
+ ```
205
+
206
+ ### With Optional Dependencies
207
+
208
+ ```bash
209
+ $ woolly check --lang python --optional flask
210
+
211
+ Dependency Summary for 'flask' (Python)
212
+ ╭────────────────────────────┬───────╮
213
+ │ Metric │ Value │
214
+ ├────────────────────────────┼───────┤
215
+ │ Total dependencies checked │ 15 │
216
+ │ Packaged in Fedora │ 12 │
217
+ │ Missing from Fedora │ 3 │
218
+ │ │ │
219
+ │ Optional dependencies │ 4 │
220
+ │ ├─ Packaged │ 2 │
221
+ │ └─ Missing │ 2 │
222
+ ╰────────────────────────────┴───────╯
223
+ ```
224
+
225
+ ## Adding a New Language
226
+
227
+ To add support for a new language, create a new provider in `woolly/languages/`:
228
+
229
+ ```python
230
+ # woolly/languages/go.py
231
+ from typing import Optional
232
+
233
+ from woolly.languages.base import Dependency, LanguageProvider, PackageInfo
234
+
235
+
236
+ class GoProvider(LanguageProvider):
237
+ """Provider for Go modules."""
238
+
239
+ # Required class attributes
240
+ name = "go"
241
+ display_name = "Go"
242
+ registry_name = "Go Modules"
243
+ fedora_provides_prefix = "golang"
244
+ cache_namespace = "go"
245
+
246
+ # Required methods to implement:
247
+
248
+ def fetch_package_info(self, package_name: str) -> Optional[PackageInfo]:
249
+ """Fetch package info from proxy.golang.org."""
250
+ ...
251
+
252
+ def fetch_dependencies(self, package_name: str, version: str) -> list[Dependency]:
253
+ """Fetch dependencies from go.mod."""
254
+ ...
255
+
256
+ # Optional: Override these if your language has special naming conventions
257
+
258
+ def normalize_package_name(self, package_name: str) -> str:
259
+ """Normalize package name for Fedora lookup."""
260
+ return package_name
261
+
262
+ def get_alternative_names(self, package_name: str) -> list[str]:
263
+ """Alternative names to try if package not found."""
264
+ return []
265
+ ```
266
+
267
+ Then register it in `woolly/languages/__init__.py`:
268
+
269
+ ```python
270
+ from woolly.languages.go import GoProvider
271
+
272
+ PROVIDERS: dict[str, type[LanguageProvider]] = {
273
+ "rust": RustProvider,
274
+ "python": PythonProvider,
275
+ "go": GoProvider, # Add new provider
276
+ }
277
+
278
+ ALIASES: dict[str, str] = {
279
+ # ... existing aliases
280
+ "golang": "go",
281
+ }
282
+ ```
283
+
284
+ ## Adding a New Output Format
285
+
286
+ To add a new output format, create a reporter in `woolly/reporters/`:
287
+
288
+ ```python
289
+ # woolly/reporters/html.py
290
+ from woolly.reporters.base import Reporter, ReportData
291
+
292
+
293
+ class HtmlReporter(Reporter):
294
+ """HTML report with interactive tree."""
295
+
296
+ name = "html"
297
+ description = "HTML report with interactive dependency tree"
298
+ file_extension = "html"
299
+ writes_to_file = True
300
+
301
+ def generate(self, data: ReportData) -> str:
302
+ """Generate HTML content."""
303
+ ...
304
+ ```
305
+
306
+ Then register it in `woolly/reporters/__init__.py`.
307
+
308
+ ## Notes
309
+
310
+ - Results should be verified manually — some packages may have different names in Fedora
311
+ - Platform-specific dependencies (like `windows-*` crates) are shown as missing but aren't needed on Linux
312
+ - The tool uses `dnf repoquery` to check Fedora packages, so it must run on a Fedora system or have access to Fedora repos
313
+ - Cache is stored in `~/.cache/woolly` and can be cleared with `woolly clear-cache`
314
+
315
+ ## License
316
+
317
+ MIT License — see [LICENSE](LICENSE) for details.
318
+
319
+ ## Credits
320
+
321
+ - **[Rodolfo Olivieri (@r0x0d)](https://github.com/r0x0d)** — Creator and maintainer
322
+ - **[Claude](https://claude.ai)** — AI pair programmer by [Anthropic](https://anthropic.com)