woolly 0.1.0__tar.gz → 0.2.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.
- woolly-0.2.0/.coverage +0 -0
- woolly-0.2.0/.github/workflows/lint.yml +68 -0
- woolly-0.2.0/.github/workflows/tests.yml +111 -0
- woolly-0.2.0/PKG-INFO +213 -0
- woolly-0.2.0/README.md +183 -0
- {woolly-0.1.0 → woolly-0.2.0}/pyproject.toml +43 -3
- woolly-0.2.0/tests/__init__.py +1 -0
- woolly-0.2.0/tests/conftest.py +293 -0
- woolly-0.2.0/tests/functional/__init__.py +1 -0
- woolly-0.2.0/tests/functional/test_cli.py +323 -0
- woolly-0.2.0/tests/unit/__init__.py +1 -0
- woolly-0.2.0/tests/unit/test_cache.py +236 -0
- woolly-0.2.0/tests/unit/test_commands/__init__.py +1 -0
- woolly-0.2.0/tests/unit/test_commands/test_check.py +258 -0
- woolly-0.2.0/tests/unit/test_commands/test_other_commands.py +98 -0
- woolly-0.2.0/tests/unit/test_debug.py +317 -0
- woolly-0.2.0/tests/unit/test_languages/__init__.py +1 -0
- woolly-0.2.0/tests/unit/test_languages/test_base.py +365 -0
- woolly-0.2.0/tests/unit/test_languages/test_python.py +292 -0
- woolly-0.2.0/tests/unit/test_languages/test_registry.py +162 -0
- woolly-0.2.0/tests/unit/test_languages/test_rust.py +220 -0
- woolly-0.2.0/tests/unit/test_progress.py +102 -0
- woolly-0.2.0/tests/unit/test_reporters/__init__.py +1 -0
- woolly-0.2.0/tests/unit/test_reporters/test_base.py +213 -0
- woolly-0.2.0/tests/unit/test_reporters/test_json.py +172 -0
- woolly-0.2.0/tests/unit/test_reporters/test_markdown.py +181 -0
- woolly-0.2.0/tests/unit/test_reporters/test_registry.py +177 -0
- woolly-0.2.0/tests/unit/test_reporters/test_stdout.py +104 -0
- woolly-0.2.0/uv.lock +668 -0
- woolly-0.2.0/woolly/__main__.py +21 -0
- woolly-0.2.0/woolly/cache.py +78 -0
- woolly-0.2.0/woolly/commands/__init__.py +27 -0
- woolly-0.2.0/woolly/commands/check.py +358 -0
- woolly-0.2.0/woolly/commands/clear_cache.py +42 -0
- woolly-0.2.0/woolly/commands/list_formats.py +24 -0
- woolly-0.2.0/woolly/commands/list_languages.py +26 -0
- woolly-0.2.0/woolly/debug.py +195 -0
- woolly-0.2.0/woolly/languages/__init__.py +72 -0
- woolly-0.2.0/woolly/languages/base.py +370 -0
- woolly-0.2.0/woolly/languages/python.py +201 -0
- woolly-0.2.0/woolly/languages/rust.py +132 -0
- woolly-0.2.0/woolly/progress.py +69 -0
- woolly-0.2.0/woolly/reporters/__init__.py +90 -0
- woolly-0.2.0/woolly/reporters/base.py +131 -0
- woolly-0.2.0/woolly/reporters/json.py +145 -0
- woolly-0.2.0/woolly/reporters/markdown.py +140 -0
- woolly-0.2.0/woolly/reporters/stdout.py +54 -0
- woolly-0.1.0/PKG-INFO +0 -101
- woolly-0.1.0/README.md +0 -73
- woolly-0.1.0/uv.lock +0 -127
- woolly-0.1.0/woolly/__main__.py +0 -482
- {woolly-0.1.0 → woolly-0.2.0}/.github/workflows/publish.yml +0 -0
- {woolly-0.1.0 → woolly-0.2.0}/.gitignore +0 -0
- {woolly-0.1.0 → woolly-0.2.0}/.python-version +0 -0
- {woolly-0.1.0 → woolly-0.2.0}/LICENSE +0 -0
- {woolly-0.1.0 → woolly-0.2.0}/woolly/__init__.py +0 -0
woolly-0.2.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.2.0/PKG-INFO
ADDED
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: woolly
|
|
3
|
+
Version: 0.2.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. Supports multiple languages including Rust and Python.
|
|
34
|
+
|
|
35
|
+
> This tool is merely a starting point for figuring out how much packaging
|
|
36
|
+
> effort you will need to bring a package over to Fedora.
|
|
37
|
+
|
|
38
|
+
## What does "woolly" means?
|
|
39
|
+
|
|
40
|
+
Nothing. I just liked the name.
|
|
41
|
+
|
|
42
|
+
## Supported Languages
|
|
43
|
+
|
|
44
|
+
| Language | Registry | CLI Flag |
|
|
45
|
+
|----------|----------|----------|
|
|
46
|
+
| Rust | crates.io | `--lang rust` (default) |
|
|
47
|
+
| Python | PyPI | `--lang python` |
|
|
48
|
+
|
|
49
|
+
More languages can be easily added by implementing the `LanguageProvider` interface.
|
|
50
|
+
|
|
51
|
+
## Installation
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
# Using uv
|
|
55
|
+
uv pip install .
|
|
56
|
+
|
|
57
|
+
# Or run directly
|
|
58
|
+
uv run woolly --help
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Usage
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
# Check a Rust crate (default)
|
|
65
|
+
woolly ripgrep
|
|
66
|
+
|
|
67
|
+
# Check a Rust crate explicitly
|
|
68
|
+
woolly --lang rust serde
|
|
69
|
+
|
|
70
|
+
# Check a Python package
|
|
71
|
+
woolly --lang python requests
|
|
72
|
+
|
|
73
|
+
# Use language aliases
|
|
74
|
+
woolly -l py flask
|
|
75
|
+
woolly -l rs tokio
|
|
76
|
+
|
|
77
|
+
# List available languages
|
|
78
|
+
woolly --list-languages
|
|
79
|
+
|
|
80
|
+
# Clear cache
|
|
81
|
+
woolly --clear-cache
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Example Output
|
|
85
|
+
|
|
86
|
+
### Rust
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
$ woolly cliclack
|
|
90
|
+
|
|
91
|
+
Analyzing Rust package: cliclack
|
|
92
|
+
Registry: crates.io
|
|
93
|
+
Cache directory: /home/user/.cache/woolly
|
|
94
|
+
|
|
95
|
+
Analyzing Rust dependencies ━━━━━━━━━━━━━━━━━ 100% • 0:00:15 complete!
|
|
96
|
+
|
|
97
|
+
Dependency Summary for 'cliclack' (Rust)
|
|
98
|
+
╭────────────────────────────┬───────╮
|
|
99
|
+
│ Metric │ Value │
|
|
100
|
+
├────────────────────────────┼───────┤
|
|
101
|
+
│ Total dependencies checked │ 7 │
|
|
102
|
+
│ Packaged in Fedora │ 0 │
|
|
103
|
+
│ Missing from Fedora │ 1 │
|
|
104
|
+
╰────────────────────────────┴───────╯
|
|
105
|
+
|
|
106
|
+
Missing packages that need packaging:
|
|
107
|
+
• cliclack
|
|
108
|
+
|
|
109
|
+
Dependency Tree:
|
|
110
|
+
cliclack v0.3.6 • ✗ not packaged
|
|
111
|
+
├── console v0.16.1 • ✓ packaged (0.16.1)
|
|
112
|
+
│ ├── encode_unicode v1.0.0 • ✓ packaged (1.0.0)
|
|
113
|
+
│ └── windows-sys v0.61.2 • ✗ not packaged
|
|
114
|
+
...
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Python
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
$ woolly --lang python requests
|
|
121
|
+
|
|
122
|
+
Analyzing Python package: requests
|
|
123
|
+
Registry: PyPI
|
|
124
|
+
Cache directory: /home/user/.cache/woolly
|
|
125
|
+
|
|
126
|
+
Analyzing Python dependencies ━━━━━━━━━━━━━━ 100% • 0:00:05 complete!
|
|
127
|
+
|
|
128
|
+
Dependency Summary for 'requests' (Python)
|
|
129
|
+
╭────────────────────────────┬───────╮
|
|
130
|
+
│ Metric │ Value │
|
|
131
|
+
├────────────────────────────┼───────┤
|
|
132
|
+
│ Total dependencies checked │ 5 │
|
|
133
|
+
│ Packaged in Fedora │ 5 │
|
|
134
|
+
│ Missing from Fedora │ 0 │
|
|
135
|
+
╰────────────────────────────┴───────╯
|
|
136
|
+
|
|
137
|
+
Dependency Tree:
|
|
138
|
+
requests v2.32.3 • ✓ packaged (2.32.3) [python3-requests]
|
|
139
|
+
├── charset-normalizer v3.4.0 • ✓ packaged (3.4.0) [python3-charset-normalizer]
|
|
140
|
+
├── idna v3.10 • ✓ packaged (3.10) [python3-idna]
|
|
141
|
+
├── urllib3 v2.2.3 • ✓ packaged (2.2.3) [python3-urllib3]
|
|
142
|
+
└── certifi v2024.8.30 • ✓ packaged (2024.8.30) [python3-certifi]
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## Adding a New Language
|
|
146
|
+
|
|
147
|
+
To add support for a new language, create a new provider in `woolly/languages/`:
|
|
148
|
+
|
|
149
|
+
```python
|
|
150
|
+
# woolly/languages/go.py
|
|
151
|
+
from typing import Optional
|
|
152
|
+
|
|
153
|
+
import requests
|
|
154
|
+
|
|
155
|
+
from woolly.cache import DEFAULT_CACHE_TTL, read_cache, write_cache
|
|
156
|
+
from woolly.languages.base import Dependency, LanguageProvider, PackageInfo
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
class GoProvider(LanguageProvider):
|
|
160
|
+
"""Provider for Go modules."""
|
|
161
|
+
|
|
162
|
+
# Required class attributes
|
|
163
|
+
name = "go"
|
|
164
|
+
display_name = "Go"
|
|
165
|
+
registry_name = "Go Modules"
|
|
166
|
+
fedora_provides_prefix = "golang"
|
|
167
|
+
cache_namespace = "go"
|
|
168
|
+
|
|
169
|
+
# Only these two methods are required to implement:
|
|
170
|
+
|
|
171
|
+
def fetch_package_info(self, package_name: str) -> Optional[PackageInfo]:
|
|
172
|
+
"""Fetch package info from proxy.golang.org."""
|
|
173
|
+
# Your implementation here
|
|
174
|
+
...
|
|
175
|
+
|
|
176
|
+
def fetch_dependencies(self, package_name: str, version: str) -> list[Dependency]:
|
|
177
|
+
"""Fetch dependencies from go.mod."""
|
|
178
|
+
# Your implementation here
|
|
179
|
+
...
|
|
180
|
+
|
|
181
|
+
# Optional: Override these if your language has special naming conventions
|
|
182
|
+
|
|
183
|
+
def normalize_package_name(self, package_name: str) -> str:
|
|
184
|
+
"""Normalize package name for Fedora lookup."""
|
|
185
|
+
return package_name
|
|
186
|
+
|
|
187
|
+
def get_alternative_names(self, package_name: str) -> list[str]:
|
|
188
|
+
"""Alternative names to try if package not found."""
|
|
189
|
+
return []
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
Then register it in `woolly/languages/__init__.py`:
|
|
193
|
+
|
|
194
|
+
```python
|
|
195
|
+
from woolly.languages.go import GoProvider
|
|
196
|
+
|
|
197
|
+
PROVIDERS: dict[str, type[LanguageProvider]] = {
|
|
198
|
+
"rust": RustProvider,
|
|
199
|
+
"python": PythonProvider,
|
|
200
|
+
"go": GoProvider, # Add new provider
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
ALIASES: dict[str, str] = {
|
|
204
|
+
# ... existing aliases
|
|
205
|
+
"golang": "go",
|
|
206
|
+
}
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
## Notes
|
|
210
|
+
|
|
211
|
+
Keep in mind that you may not need all of the packages to be present in Fedora.
|
|
212
|
+
For example, Rust crates may have platform-specific dependencies (like `windows*` crates)
|
|
213
|
+
that aren't used on Linux.
|
woolly-0.2.0/README.md
ADDED
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
# Woolly
|
|
2
|
+
|
|
3
|
+
Check if package dependencies are available in Fedora. Supports multiple languages including Rust and Python.
|
|
4
|
+
|
|
5
|
+
> This tool is merely a starting point for figuring out how much packaging
|
|
6
|
+
> effort you will need to bring a package over to Fedora.
|
|
7
|
+
|
|
8
|
+
## What does "woolly" means?
|
|
9
|
+
|
|
10
|
+
Nothing. I just liked the name.
|
|
11
|
+
|
|
12
|
+
## Supported Languages
|
|
13
|
+
|
|
14
|
+
| Language | Registry | CLI Flag |
|
|
15
|
+
|----------|----------|----------|
|
|
16
|
+
| Rust | crates.io | `--lang rust` (default) |
|
|
17
|
+
| Python | PyPI | `--lang python` |
|
|
18
|
+
|
|
19
|
+
More languages can be easily added by implementing the `LanguageProvider` interface.
|
|
20
|
+
|
|
21
|
+
## Installation
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
# Using uv
|
|
25
|
+
uv pip install .
|
|
26
|
+
|
|
27
|
+
# Or run directly
|
|
28
|
+
uv run woolly --help
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Usage
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
# Check a Rust crate (default)
|
|
35
|
+
woolly ripgrep
|
|
36
|
+
|
|
37
|
+
# Check a Rust crate explicitly
|
|
38
|
+
woolly --lang rust serde
|
|
39
|
+
|
|
40
|
+
# Check a Python package
|
|
41
|
+
woolly --lang python requests
|
|
42
|
+
|
|
43
|
+
# Use language aliases
|
|
44
|
+
woolly -l py flask
|
|
45
|
+
woolly -l rs tokio
|
|
46
|
+
|
|
47
|
+
# List available languages
|
|
48
|
+
woolly --list-languages
|
|
49
|
+
|
|
50
|
+
# Clear cache
|
|
51
|
+
woolly --clear-cache
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Example Output
|
|
55
|
+
|
|
56
|
+
### Rust
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
$ woolly cliclack
|
|
60
|
+
|
|
61
|
+
Analyzing Rust package: cliclack
|
|
62
|
+
Registry: crates.io
|
|
63
|
+
Cache directory: /home/user/.cache/woolly
|
|
64
|
+
|
|
65
|
+
Analyzing Rust dependencies ━━━━━━━━━━━━━━━━━ 100% • 0:00:15 complete!
|
|
66
|
+
|
|
67
|
+
Dependency Summary for 'cliclack' (Rust)
|
|
68
|
+
╭────────────────────────────┬───────╮
|
|
69
|
+
│ Metric │ Value │
|
|
70
|
+
├────────────────────────────┼───────┤
|
|
71
|
+
│ Total dependencies checked │ 7 │
|
|
72
|
+
│ Packaged in Fedora │ 0 │
|
|
73
|
+
│ Missing from Fedora │ 1 │
|
|
74
|
+
╰────────────────────────────┴───────╯
|
|
75
|
+
|
|
76
|
+
Missing packages that need packaging:
|
|
77
|
+
• cliclack
|
|
78
|
+
|
|
79
|
+
Dependency Tree:
|
|
80
|
+
cliclack v0.3.6 • ✗ not packaged
|
|
81
|
+
├── console v0.16.1 • ✓ packaged (0.16.1)
|
|
82
|
+
│ ├── encode_unicode v1.0.0 • ✓ packaged (1.0.0)
|
|
83
|
+
│ └── windows-sys v0.61.2 • ✗ not packaged
|
|
84
|
+
...
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Python
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
$ woolly --lang python requests
|
|
91
|
+
|
|
92
|
+
Analyzing Python package: requests
|
|
93
|
+
Registry: PyPI
|
|
94
|
+
Cache directory: /home/user/.cache/woolly
|
|
95
|
+
|
|
96
|
+
Analyzing Python dependencies ━━━━━━━━━━━━━━ 100% • 0:00:05 complete!
|
|
97
|
+
|
|
98
|
+
Dependency Summary for 'requests' (Python)
|
|
99
|
+
╭────────────────────────────┬───────╮
|
|
100
|
+
│ Metric │ Value │
|
|
101
|
+
├────────────────────────────┼───────┤
|
|
102
|
+
│ Total dependencies checked │ 5 │
|
|
103
|
+
│ Packaged in Fedora │ 5 │
|
|
104
|
+
│ Missing from Fedora │ 0 │
|
|
105
|
+
╰────────────────────────────┴───────╯
|
|
106
|
+
|
|
107
|
+
Dependency Tree:
|
|
108
|
+
requests v2.32.3 • ✓ packaged (2.32.3) [python3-requests]
|
|
109
|
+
├── charset-normalizer v3.4.0 • ✓ packaged (3.4.0) [python3-charset-normalizer]
|
|
110
|
+
├── idna v3.10 • ✓ packaged (3.10) [python3-idna]
|
|
111
|
+
├── urllib3 v2.2.3 • ✓ packaged (2.2.3) [python3-urllib3]
|
|
112
|
+
└── certifi v2024.8.30 • ✓ packaged (2024.8.30) [python3-certifi]
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Adding a New Language
|
|
116
|
+
|
|
117
|
+
To add support for a new language, create a new provider in `woolly/languages/`:
|
|
118
|
+
|
|
119
|
+
```python
|
|
120
|
+
# woolly/languages/go.py
|
|
121
|
+
from typing import Optional
|
|
122
|
+
|
|
123
|
+
import requests
|
|
124
|
+
|
|
125
|
+
from woolly.cache import DEFAULT_CACHE_TTL, read_cache, write_cache
|
|
126
|
+
from woolly.languages.base import Dependency, LanguageProvider, PackageInfo
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
class GoProvider(LanguageProvider):
|
|
130
|
+
"""Provider for Go modules."""
|
|
131
|
+
|
|
132
|
+
# Required class attributes
|
|
133
|
+
name = "go"
|
|
134
|
+
display_name = "Go"
|
|
135
|
+
registry_name = "Go Modules"
|
|
136
|
+
fedora_provides_prefix = "golang"
|
|
137
|
+
cache_namespace = "go"
|
|
138
|
+
|
|
139
|
+
# Only these two methods are required to implement:
|
|
140
|
+
|
|
141
|
+
def fetch_package_info(self, package_name: str) -> Optional[PackageInfo]:
|
|
142
|
+
"""Fetch package info from proxy.golang.org."""
|
|
143
|
+
# Your implementation here
|
|
144
|
+
...
|
|
145
|
+
|
|
146
|
+
def fetch_dependencies(self, package_name: str, version: str) -> list[Dependency]:
|
|
147
|
+
"""Fetch dependencies from go.mod."""
|
|
148
|
+
# Your implementation here
|
|
149
|
+
...
|
|
150
|
+
|
|
151
|
+
# Optional: Override these if your language has special naming conventions
|
|
152
|
+
|
|
153
|
+
def normalize_package_name(self, package_name: str) -> str:
|
|
154
|
+
"""Normalize package name for Fedora lookup."""
|
|
155
|
+
return package_name
|
|
156
|
+
|
|
157
|
+
def get_alternative_names(self, package_name: str) -> list[str]:
|
|
158
|
+
"""Alternative names to try if package not found."""
|
|
159
|
+
return []
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
Then register it in `woolly/languages/__init__.py`:
|
|
163
|
+
|
|
164
|
+
```python
|
|
165
|
+
from woolly.languages.go import GoProvider
|
|
166
|
+
|
|
167
|
+
PROVIDERS: dict[str, type[LanguageProvider]] = {
|
|
168
|
+
"rust": RustProvider,
|
|
169
|
+
"python": PythonProvider,
|
|
170
|
+
"go": GoProvider, # Add new provider
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
ALIASES: dict[str, str] = {
|
|
174
|
+
# ... existing aliases
|
|
175
|
+
"golang": "go",
|
|
176
|
+
}
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
## Notes
|
|
180
|
+
|
|
181
|
+
Keep in mind that you may not need all of the packages to be present in Fedora.
|
|
182
|
+
For example, Rust crates may have platform-specific dependencies (like `windows*` crates)
|
|
183
|
+
that aren't used on Linux.
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "woolly"
|
|
7
|
-
description = "
|
|
7
|
+
description = "Check if package dependencies are available in Fedora. Supports Rust, Python, and more."
|
|
8
8
|
readme = "README.md"
|
|
9
9
|
authors = [
|
|
10
10
|
{ name = "Rodolfo Olivieri", email = "rodolfo.olivieri3@gmail.com"}
|
|
@@ -12,7 +12,9 @@ authors = [
|
|
|
12
12
|
dynamic = ["version"]
|
|
13
13
|
requires-python = ">=3.10"
|
|
14
14
|
dependencies = [
|
|
15
|
-
"
|
|
15
|
+
"cyclopts>=4.3.0",
|
|
16
|
+
"httpx>=0.28.0",
|
|
17
|
+
"pydantic>=2.10.0",
|
|
16
18
|
"rich>=14.2.0",
|
|
17
19
|
]
|
|
18
20
|
classifiers = [
|
|
@@ -47,4 +49,42 @@ woolly = "woolly.__main__:main"
|
|
|
47
49
|
packages = ["woolly"]
|
|
48
50
|
|
|
49
51
|
[tool.hatch.version]
|
|
50
|
-
source = "vcs"
|
|
52
|
+
source = "vcs"
|
|
53
|
+
|
|
54
|
+
[dependency-groups]
|
|
55
|
+
dev = [
|
|
56
|
+
"pyright>=1.1.407",
|
|
57
|
+
"ruff>=0.14.7",
|
|
58
|
+
]
|
|
59
|
+
|
|
60
|
+
test = [
|
|
61
|
+
"pytest>=8.0.0",
|
|
62
|
+
"pytest-cov>=4.1.0",
|
|
63
|
+
"pytest-mock>=3.14.0",
|
|
64
|
+
]
|
|
65
|
+
|
|
66
|
+
[tool.pytest.ini_options]
|
|
67
|
+
testpaths = ["tests"]
|
|
68
|
+
python_files = ["test_*.py"]
|
|
69
|
+
python_classes = ["Test*"]
|
|
70
|
+
python_functions = ["test_*"]
|
|
71
|
+
markers = [
|
|
72
|
+
"unit: Unit tests with mocking",
|
|
73
|
+
"functional: Functional tests without mocking (may require network)",
|
|
74
|
+
"slow: Slow tests that make real API calls",
|
|
75
|
+
]
|
|
76
|
+
addopts = "-v --tb=short"
|
|
77
|
+
|
|
78
|
+
[tool.coverage.run]
|
|
79
|
+
source = ["woolly"]
|
|
80
|
+
branch = true
|
|
81
|
+
omit = [
|
|
82
|
+
"woolly/__main__.py",
|
|
83
|
+
]
|
|
84
|
+
|
|
85
|
+
[tool.coverage.report]
|
|
86
|
+
exclude_lines = [
|
|
87
|
+
"pragma: no cover",
|
|
88
|
+
"if __name__ == .__main__.:",
|
|
89
|
+
"raise NotImplementedError",
|
|
90
|
+
]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Test suite for woolly."""
|