woolly 0.1.0__py3-none-any.whl → 0.3.0__py3-none-any.whl
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/__main__.py +12 -473
- woolly/cache.py +88 -0
- woolly/commands/__init__.py +27 -0
- woolly/commands/check.py +422 -0
- woolly/commands/clear_cache.py +42 -0
- woolly/commands/list_formats.py +24 -0
- woolly/commands/list_languages.py +26 -0
- woolly/debug.py +195 -0
- woolly/http.py +34 -0
- woolly/languages/__init__.py +102 -0
- woolly/languages/base.py +374 -0
- woolly/languages/python.py +200 -0
- woolly/languages/rust.py +130 -0
- woolly/progress.py +69 -0
- woolly/reporters/__init__.py +111 -0
- woolly/reporters/base.py +213 -0
- woolly/reporters/json.py +175 -0
- woolly/reporters/markdown.py +117 -0
- woolly/reporters/stdout.py +75 -0
- woolly-0.3.0.dist-info/METADATA +322 -0
- woolly-0.3.0.dist-info/RECORD +25 -0
- {woolly-0.1.0.dist-info → woolly-0.3.0.dist-info}/WHEEL +1 -1
- woolly-0.1.0.dist-info/METADATA +0 -101
- woolly-0.1.0.dist-info/RECORD +0 -7
- {woolly-0.1.0.dist-info → woolly-0.3.0.dist-info}/entry_points.txt +0 -0
- {woolly-0.1.0.dist-info → woolly-0.3.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Markdown report generator.
|
|
3
|
+
|
|
4
|
+
Generates a markdown file with the full dependency analysis.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from woolly.reporters.base import ReportData, Reporter, strip_markup
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class MarkdownReporter(Reporter):
|
|
11
|
+
"""Reporter that generates a Markdown file."""
|
|
12
|
+
|
|
13
|
+
name = "markdown"
|
|
14
|
+
description = "Markdown report file"
|
|
15
|
+
file_extension = "md"
|
|
16
|
+
writes_to_file = True
|
|
17
|
+
|
|
18
|
+
def generate(self, data: ReportData) -> str:
|
|
19
|
+
"""Generate markdown report content."""
|
|
20
|
+
lines = []
|
|
21
|
+
|
|
22
|
+
# Header
|
|
23
|
+
lines.append(f"# Dependency Report: {data.root_package}")
|
|
24
|
+
lines.append("")
|
|
25
|
+
lines.append(f"**Generated:** {data.timestamp.strftime('%Y-%m-%d %H:%M:%S')}")
|
|
26
|
+
lines.append(f"**Language:** {data.language}")
|
|
27
|
+
lines.append(f"**Registry:** {data.registry}")
|
|
28
|
+
if data.version:
|
|
29
|
+
lines.append(f"**Version:** {data.version}")
|
|
30
|
+
if data.include_optional:
|
|
31
|
+
lines.append("**Include optional:** Yes")
|
|
32
|
+
lines.append("")
|
|
33
|
+
|
|
34
|
+
# Summary
|
|
35
|
+
lines.append("## Summary")
|
|
36
|
+
lines.append("")
|
|
37
|
+
lines.append("| Metric | Value |")
|
|
38
|
+
lines.append("|--------|-------|")
|
|
39
|
+
lines.append(f"| Total dependencies checked | {data.total_dependencies} |")
|
|
40
|
+
lines.append(f"| Packaged in Fedora | {data.packaged_count} |")
|
|
41
|
+
lines.append(f"| Missing from Fedora | {data.missing_count} |")
|
|
42
|
+
|
|
43
|
+
# Optional dependency stats
|
|
44
|
+
if data.optional_total > 0:
|
|
45
|
+
lines.append(f"| Optional dependencies | {data.optional_total} |")
|
|
46
|
+
lines.append(f"| Optional - Packaged | {data.optional_packaged} |")
|
|
47
|
+
lines.append(f"| Optional - Missing | {data.optional_missing} |")
|
|
48
|
+
lines.append("")
|
|
49
|
+
|
|
50
|
+
# Missing packages - use computed properties from ReportData
|
|
51
|
+
required_missing = data.required_missing_packages
|
|
52
|
+
optional_missing = data.optional_missing_set
|
|
53
|
+
|
|
54
|
+
if required_missing:
|
|
55
|
+
lines.append("## Missing Packages")
|
|
56
|
+
lines.append("")
|
|
57
|
+
lines.append("The following packages need to be packaged for Fedora:")
|
|
58
|
+
lines.append("")
|
|
59
|
+
for name in sorted(required_missing):
|
|
60
|
+
lines.append(f"- `{name}`")
|
|
61
|
+
lines.append("")
|
|
62
|
+
|
|
63
|
+
if optional_missing:
|
|
64
|
+
lines.append("## Missing Optional Packages")
|
|
65
|
+
lines.append("")
|
|
66
|
+
lines.append("The following optional packages are not available in Fedora:")
|
|
67
|
+
lines.append("")
|
|
68
|
+
for name in sorted(optional_missing):
|
|
69
|
+
lines.append(f"- `{name}` *(optional)*")
|
|
70
|
+
lines.append("")
|
|
71
|
+
|
|
72
|
+
# Packaged packages - use computed property
|
|
73
|
+
if data.unique_packaged_packages:
|
|
74
|
+
lines.append("## Packaged Packages")
|
|
75
|
+
lines.append("")
|
|
76
|
+
lines.append("The following packages are already available in Fedora:")
|
|
77
|
+
lines.append("")
|
|
78
|
+
for name in sorted(data.unique_packaged_packages):
|
|
79
|
+
lines.append(f"- `{name}`")
|
|
80
|
+
lines.append("")
|
|
81
|
+
|
|
82
|
+
# Dependency tree
|
|
83
|
+
lines.append("## Dependency Tree")
|
|
84
|
+
lines.append("")
|
|
85
|
+
lines.append("```")
|
|
86
|
+
lines.append(self._tree_to_text(data.tree))
|
|
87
|
+
lines.append("```")
|
|
88
|
+
lines.append("")
|
|
89
|
+
|
|
90
|
+
return "\n".join(lines)
|
|
91
|
+
|
|
92
|
+
def _tree_to_text(self, tree, prefix: str = "") -> str:
|
|
93
|
+
"""Convert Rich Tree to plain text representation."""
|
|
94
|
+
lines = []
|
|
95
|
+
|
|
96
|
+
# Get label text (strip Rich markup) using inherited method and shared utility
|
|
97
|
+
label = self._get_label(tree)
|
|
98
|
+
label = strip_markup(label)
|
|
99
|
+
|
|
100
|
+
lines.append(label)
|
|
101
|
+
|
|
102
|
+
# Get children using inherited method
|
|
103
|
+
children = self._get_children(tree)
|
|
104
|
+
|
|
105
|
+
for i, child in enumerate(children):
|
|
106
|
+
is_last_child = i == len(children) - 1
|
|
107
|
+
child_prefix = "└── " if is_last_child else "├── "
|
|
108
|
+
continuation = " " if is_last_child else "│ "
|
|
109
|
+
|
|
110
|
+
child_text = self._tree_to_text(child, prefix + continuation)
|
|
111
|
+
child_lines = child_text.split("\n")
|
|
112
|
+
lines.append(prefix + child_prefix + child_lines[0])
|
|
113
|
+
for line in child_lines[1:]:
|
|
114
|
+
if line: # Skip empty lines
|
|
115
|
+
lines.append(line)
|
|
116
|
+
|
|
117
|
+
return "\n".join(lines)
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Standard output reporter using Rich.
|
|
3
|
+
|
|
4
|
+
This is the default reporter that outputs to the console with colors and formatting.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from rich import box
|
|
8
|
+
from rich.console import Console
|
|
9
|
+
from rich.table import Table
|
|
10
|
+
|
|
11
|
+
from woolly.reporters.base import ReportData, Reporter
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class StdoutReporter(Reporter):
|
|
15
|
+
"""Reporter that outputs to stdout using Rich formatting."""
|
|
16
|
+
|
|
17
|
+
name = "stdout"
|
|
18
|
+
description = "Rich console output (default)"
|
|
19
|
+
file_extension = None
|
|
20
|
+
writes_to_file = False
|
|
21
|
+
|
|
22
|
+
def __init__(self, console: Console | None = None):
|
|
23
|
+
self.console = console or Console()
|
|
24
|
+
|
|
25
|
+
def generate(self, data: ReportData) -> str:
|
|
26
|
+
"""Generate and print the report to stdout."""
|
|
27
|
+
# Print summary table
|
|
28
|
+
table = Table(
|
|
29
|
+
title=f"Dependency Summary for '{data.root_package}' ({data.language})",
|
|
30
|
+
box=box.ROUNDED,
|
|
31
|
+
)
|
|
32
|
+
table.add_column("Metric", style="bold")
|
|
33
|
+
table.add_column("Value", justify="right")
|
|
34
|
+
|
|
35
|
+
table.add_row("Total dependencies checked", str(data.total_dependencies))
|
|
36
|
+
table.add_row("[green]Packaged in Fedora[/green]", str(data.packaged_count))
|
|
37
|
+
table.add_row("[red]Missing from Fedora[/red]", str(data.missing_count))
|
|
38
|
+
|
|
39
|
+
# Show optional dependency stats if any were found
|
|
40
|
+
if data.optional_total > 0:
|
|
41
|
+
table.add_row("", "") # Empty row as separator
|
|
42
|
+
table.add_row(
|
|
43
|
+
"[yellow]Optional dependencies[/yellow]", str(data.optional_total)
|
|
44
|
+
)
|
|
45
|
+
table.add_row("[yellow] ├─ Packaged[/yellow]", str(data.optional_packaged))
|
|
46
|
+
table.add_row("[yellow] └─ Missing[/yellow]", str(data.optional_missing))
|
|
47
|
+
|
|
48
|
+
self.console.print(table)
|
|
49
|
+
self.console.print()
|
|
50
|
+
|
|
51
|
+
# Print missing packages list using computed properties
|
|
52
|
+
if data.missing_packages:
|
|
53
|
+
required_missing = data.required_missing_packages
|
|
54
|
+
optional_missing = data.optional_missing_set
|
|
55
|
+
|
|
56
|
+
if required_missing:
|
|
57
|
+
self.console.print("[bold]Missing packages that need packaging:[/bold]")
|
|
58
|
+
for name in sorted(required_missing):
|
|
59
|
+
self.console.print(f" • {name}")
|
|
60
|
+
self.console.print()
|
|
61
|
+
|
|
62
|
+
if optional_missing:
|
|
63
|
+
self.console.print(
|
|
64
|
+
"[bold yellow]Missing optional packages:[/bold yellow]"
|
|
65
|
+
)
|
|
66
|
+
for name in sorted(optional_missing):
|
|
67
|
+
self.console.print(f" • {name} [dim](optional)[/dim]")
|
|
68
|
+
self.console.print()
|
|
69
|
+
|
|
70
|
+
# Print dependency tree
|
|
71
|
+
self.console.print("[bold]Dependency Tree:[/bold]")
|
|
72
|
+
self.console.print(data.tree)
|
|
73
|
+
self.console.print()
|
|
74
|
+
|
|
75
|
+
return "" # Output is printed directly
|
|
@@ -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)
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
woolly/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
woolly/__main__.py,sha256=em9-CiwyaP3N5FKr_Srv6Eh8Vm6TOC3VWSwXR1BjzV8,304
|
|
3
|
+
woolly/cache.py,sha256=tzZE0FrymWQZSpJ5ZFgv2G17CVYq7SzsxpVWsF7ByXI,2405
|
|
4
|
+
woolly/debug.py,sha256=85_0_lsqccT8TAkyWFinOIqkPVPpcmrKuNfIYQOEqZ4,5294
|
|
5
|
+
woolly/http.py,sha256=xPFbHPWEWTN4mjEONyJ9hERmb62mMWun0jRjTAaaNE8,872
|
|
6
|
+
woolly/progress.py,sha256=Ij-K3-6-qeVLFKD_WdSfuclZh6uiso9XSSVRlpbB4jA,2040
|
|
7
|
+
woolly/commands/__init__.py,sha256=3xzeIPYD0dmVWwRXHkdPmsF2IIRU6KyvDwgemKdyghI,840
|
|
8
|
+
woolly/commands/check.py,sha256=kCFQClTOiBAP-DRpAQFbDGgIKiPv8SlMYKoQzx6Fq4E,13312
|
|
9
|
+
woolly/commands/clear_cache.py,sha256=nCS52v_hNvKTwj62CKrQRfjX53fGpZnWpfB0GMmi8e4,1039
|
|
10
|
+
woolly/commands/list_formats.py,sha256=f4UAWjoBbDu8YhobQyccErwpmOqElrCxBg0xcnJVDUQ,695
|
|
11
|
+
woolly/commands/list_languages.py,sha256=VFjvMgXnvaW3O-MBEpzf5nd89yQ9TqLqcULPDCDUthg,857
|
|
12
|
+
woolly/languages/__init__.py,sha256=CwcPDIMvFpCK1tFbx5rew_5mLrrMy6s4HT6C-ZZz_7M,2527
|
|
13
|
+
woolly/languages/base.py,sha256=Sjm9wXWeM36w6eYx_YyHm0jM6TqAUshlCiSPczW1_IA,12365
|
|
14
|
+
woolly/languages/python.py,sha256=aA1fmHO0VWV_sHjZF92G30frv916Veh6cqjIj354UgM,6723
|
|
15
|
+
woolly/languages/rust.py,sha256=DdhflO0PDvpgGy41lst9vUW9vF1Xrf94RJIMAsWSRDc,4508
|
|
16
|
+
woolly/reporters/__init__.py,sha256=dS1XZGPTjvCkDetiWikkmBn7OnpvnmMXGZDYz2LVQr4,2833
|
|
17
|
+
woolly/reporters/base.py,sha256=xXwrNb2NVVktQHjYCBT4nCzdqpvQsVCVsSs5-hB0D8I,6264
|
|
18
|
+
woolly/reporters/json.py,sha256=mJb3tZDxvzEZ2zeOKELKJaU1E3b4TG86_DtsEJ8JHGE,5707
|
|
19
|
+
woolly/reporters/markdown.py,sha256=fh--BH1rQP46qhTXiWcTHX3X9kjQJsAAXFFiToqK-RA,4300
|
|
20
|
+
woolly/reporters/stdout.py,sha256=Xzku45BElUFyHh_pCWqAW4efb2mhC54CEja0xN6Xoe0,2784
|
|
21
|
+
woolly-0.3.0.dist-info/METADATA,sha256=SMLGfdfa3_Rk6S36nGkJfiagX2bvmYMpb4llzvE6NCc,10402
|
|
22
|
+
woolly-0.3.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
23
|
+
woolly-0.3.0.dist-info/entry_points.txt,sha256=tMSCR0PXsaIWiiY5fwQ5eowwNqPSrH0j9QriPDoE75k,48
|
|
24
|
+
woolly-0.3.0.dist-info/licenses/LICENSE,sha256=TnfrdmTYydTTenujKk2LdAuDuLSMwjpXhW7EU2VR0e8,1064
|
|
25
|
+
woolly-0.3.0.dist-info/RECORD,,
|
woolly-0.1.0.dist-info/METADATA
DELETED
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: woolly
|
|
3
|
-
Version: 0.1.0
|
|
4
|
-
Summary: Recursively search for RPMs in Fedora for Rust crates.
|
|
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: requests>=2.32.5
|
|
26
|
-
Requires-Dist: rich>=14.2.0
|
|
27
|
-
Description-Content-Type: text/markdown
|
|
28
|
-
|
|
29
|
-
# Woolly
|
|
30
|
-
|
|
31
|
-
Recursively search for RPMs in Fedora for a given Rust [crate](https://crate.io).
|
|
32
|
-
|
|
33
|
-
> This tool is merely a starting point for figuring out how much packaging
|
|
34
|
-
> effort you will need to bring a rust crate over to Fedora.
|
|
35
|
-
|
|
36
|
-
## What does "woolly" means?
|
|
37
|
-
|
|
38
|
-
Nothing. I just liked the name.
|
|
39
|
-
|
|
40
|
-
## Running the project
|
|
41
|
-
|
|
42
|
-
```bash
|
|
43
|
-
$ uv run rust_rpm_inspector
|
|
44
|
-
|
|
45
|
-
Analyzing crate: cliclack
|
|
46
|
-
Cache directory: /home/r0x0d/.cache/fedora-rust-checker
|
|
47
|
-
|
|
48
|
-
Analyzing dependencies ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% • 0:00:15 complete!
|
|
49
|
-
|
|
50
|
-
Dependency Summary for 'cliclack'
|
|
51
|
-
╭────────────────────────────┬───────╮
|
|
52
|
-
│ Metric │ Value │
|
|
53
|
-
├────────────────────────────┼───────┤
|
|
54
|
-
│ Total dependencies checked │ 7 │
|
|
55
|
-
│ Packaged in Fedora │ 0 │
|
|
56
|
-
│ Missing from Fedora │ 1 │
|
|
57
|
-
╰────────────────────────────┴───────╯
|
|
58
|
-
|
|
59
|
-
Missing crates that need packaging:
|
|
60
|
-
• cliclack
|
|
61
|
-
|
|
62
|
-
Dependency Tree:
|
|
63
|
-
cliclack v0.3.6 • ✗ not packaged
|
|
64
|
-
├── console v0.16.1 • ✓ packaged (0.16.1)
|
|
65
|
-
│ ├── encode_unicode v1.0.0 • ✓ packaged (1.0.0)
|
|
66
|
-
│ └── windows-sys v0.61.2 • ✗ not packaged
|
|
67
|
-
│ └── windows-link v0.2.1 • ✗ not packaged
|
|
68
|
-
├── indicatif v0.18.3 • ✓ packaged (0.16.2, 0.18.0, 0.18.1)
|
|
69
|
-
│ ├── console (already visited)
|
|
70
|
-
│ ├── portable-atomic v1.11.1 • ✓ packaged (1.11.1)
|
|
71
|
-
│ ├── unit-prefix v0.5.2 • ✓ packaged (0.5.1)
|
|
72
|
-
│ └── web-time v1.1.0 • ✓ packaged (1.1.0)
|
|
73
|
-
│ ├── js-sys v0.3.82 • ✗ not packaged
|
|
74
|
-
│ │ ├── once_cell v1.21.3 • ✓ packaged (1.21.3)
|
|
75
|
-
│ │ └── wasm-bindgen v0.2.105 • ✗ not packaged
|
|
76
|
-
│ │ ├── cfg-if v1.0.4 • ✓ packaged (0.1.10, 1.0.3, 1.0.4)
|
|
77
|
-
│ │ ├── once_cell (already visited)
|
|
78
|
-
│ │ ├── wasm-bindgen-macro v0.2.105 • ✗ not packaged
|
|
79
|
-
│ │ │ ├── quote v1.0.42 • ✓ packaged (0.3.15, 1.0.40, 1.0.41)
|
|
80
|
-
│ │ │ │ └── proc-macro2 v1.0.103 • ✓ packaged (1.0.101, 1.0.103)
|
|
81
|
-
│ │ │ │ └── unicode-ident v1.0.22 • ✓ packaged (1.0.19, 1.0.22)
|
|
82
|
-
│ │ │ └── wasm-bindgen-macro-support v0.2.105 • ✗ not packaged
|
|
83
|
-
│ │ │ ├── bumpalo v3.19.0 • ✓ packaged (3.19.0)
|
|
84
|
-
│ │ │ ├── proc-macro2 (already visited)
|
|
85
|
-
│ │ │ ├── quote (already visited)
|
|
86
|
-
│ │ │ ├── syn v2.0.110 • ✓ packaged (1.0.109, 2.0.106, 2.0.108)
|
|
87
|
-
│ │ │ │ ├── proc-macro2 (already visited)
|
|
88
|
-
│ │ │ │ └── unicode-ident (already visited)
|
|
89
|
-
│ │ │ └── wasm-bindgen-shared v0.2.105 • ✗ not packaged
|
|
90
|
-
│ │ │ └── unicode-ident (already visited)
|
|
91
|
-
│ │ └── wasm-bindgen-shared (already visited)
|
|
92
|
-
│ └── wasm-bindgen (already visited)
|
|
93
|
-
├── once_cell (already visited)
|
|
94
|
-
├── strsim v0.11.1 • ✓ packaged (0.10.0, 0.11.1)
|
|
95
|
-
├── textwrap v0.16.2 • ✓ packaged (0.11.0, 0.15.2, 0.16.2)
|
|
96
|
-
└── zeroize v1.8.2 • ✓ packaged (1.8.1, 1.8.2)
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
Keep in mind that you may not need all of RPMs to be present in Fedora, like
|
|
100
|
-
the output above, we have `windows*` crates in the dependency tree, but they
|
|
101
|
-
are not used at all.
|
woolly-0.1.0.dist-info/RECORD
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
woolly/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
-
woolly/__main__.py,sha256=_XB9nZAFBJptgQYaL6OO9VRLh2SYGjRTPS5DXndJx7w,15592
|
|
3
|
-
woolly-0.1.0.dist-info/METADATA,sha256=H11_hfzIbdrVvqsHeL4fvLcxgQeOeCrnB-FG8G47i2o,4895
|
|
4
|
-
woolly-0.1.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
5
|
-
woolly-0.1.0.dist-info/entry_points.txt,sha256=tMSCR0PXsaIWiiY5fwQ5eowwNqPSrH0j9QriPDoE75k,48
|
|
6
|
-
woolly-0.1.0.dist-info/licenses/LICENSE,sha256=TnfrdmTYydTTenujKk2LdAuDuLSMwjpXhW7EU2VR0e8,1064
|
|
7
|
-
woolly-0.1.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|