Files
nix-config/scripts/README_tui.md
mjallen18 70002a19e2 hmm
2026-04-07 18:39:42 -05:00

315 lines
7.8 KiB
Markdown
Executable File

# Version TUI Documentation
## Overview
The `version_tui.py` script is an interactive terminal interface for managing package versions in a NixOS repository. It provides a unified way to update version.json files, Python packages, and Home Assistant components.
## Architecture
### Core Components
1. **Package Discovery**: Scans the repository for different package types
2. **Version Management**: Handles version.json, Python default.nix, and Home Assistant components
3. **Hash Computation**: Uses modern Nix commands for reliable hash generation
4. **Interactive Interface**: Curses-based TUI with color support and keyboard navigation
## Package Types Supported
### 1. Regular Packages (`packages/**/version.json`)
- Standard version.json format with variables and sources
- Support for variants (base + overrides)
- Multiple fetcher types: github, git, url
### 2. Python Packages (`packages/python/*/default.nix`)
- Parses version, pname, and source info from default.nix
- Supports fetchFromGitHub and fetchPypi patterns
- Updates version, hash, tag, and rev fields
### 3. Home Assistant Components (`packages/homeassistant/*/default.nix`)
- Specialized parsing for HA component structure
- Handles domain, version, owner, and repo extraction
- GitHub-aware source management
## Fetcher Types
### GitHub Fetcher
```json
{
"fetcher": "github",
"owner": "owner",
"repo": "repo",
"tag": "v1.0.0",
"rev": "commit-hash",
"hash": "sha256-..."
}
```
### Git Fetcher
```json
{
"fetcher": "git",
"url": "https://github.com/user/repo.git",
"rev": "commit-hash",
"hash": "sha256-..."
}
```
### URL Fetcher
```json
{
"fetcher": "url",
"url": "https://example.com/file.tar.gz",
"hash": "sha256-..."
}
```
## Key Functions
### Hash Computation
#### `nix_prefetch_url(url: str)`
**Purpose**: Compute SHA256 SRI hash for URL sources
**Method**:
1. Try `nix store prefetch-file` (modern, SRI output)
2. Fallback to `nix-prefetch-url` (legacy, needs conversion)
3. Convert to SRI format if needed
#### `nix_prefetch_git(url: str, rev: str)`
**Purpose**: Compute SHA256 SRI hash for Git repositories
**Method**:
1. Use `nix eval` with `builtins.fetchGit` to get store path
2. Hash the store path with `nix hash path --type sha256`
3. Fallback to `nix-prefetch-git` if available
### API Functions
#### `gh_latest_release(owner, repo, token)`
- Gets latest release from GitHub API
- Returns tag_name of latest release
- Handles API errors gracefully
#### `gh_latest_tag(owner, repo, token)`
- Gets all tags and returns the first one
- Limited to 100 tags per page
- Sorts by GitHub's default ordering
#### `gh_head_commit(owner, repo)`
- Uses `git ls-remote` to get HEAD commit
- No API token required
- Fallback for when GitHub API fails
### Special Cases
#### Raspberry Pi Linux
- Prefers `stable_YYYYMMDD` tags over latest
- Falls back to series-specific tags (`rpi-X.Y`)
- Maintains compatibility with existing tagging schemes
#### CachyOS Linux
- Fetches latest version from upstream PKGBUILD
- Supports different suffixes (rc, hardened, lts)
- Handles both .SRCINFO and PKGBUILD parsing
## UI Navigation
### Main Package List
```
↑/k/j : Navigate up/down
g/G : Go to top/bottom
Enter : Open package details
f : Cycle filters (all → regular → python → all)
q/ESC : Quit
```
### Package Details Screen
```
←/h/l : Switch variants (if available)
↑/k/j : Navigate sources
r : Refresh candidates
h : Recompute hash
e : Edit field (path=value)
s : Save changes
i : Show full URL (URL sources)
Enter : Action menu for selected source
Backspace : Return to package list
q/ESC : Quit
```
### Action Menu
```
↑/k/j : Select option
Enter : Execute selected action
Backspace : Cancel
```
## File Structure Analysis
### version.json Format
```json
{
"schemaVersion": 1,
"variables": {
"key": "value"
},
"sources": {
"name": {
"fetcher": "type",
"...": "..."
}
},
"variants": {
"variant-name": {
"sources": {
"name": {
"override": "value"
}
}
}
}
}
```
### Python Package Parsing
The script extracts information from patterns like:
```nix
{
pname = "package-name";
version = "1.0.0";
src = fetchFromGitHub {
owner = "user";
repo = "repo";
rev = "v1.0.0";
sha256 = "...";
};
}
```
### Home Assistant Component Parsing
```nix
{
domain = "component_name";
version = "1.0.0";
src = fetchFromGitHub {
owner = "user";
repo = "repo";
rev = "v1.0.0";
sha256 = "...";
};
}
```
## Error Handling
### Network Errors
- Timeouts: 10-second timeout on HTTP requests
- HTTP status codes: Proper handling of 4xx/5xx responses
- Retry logic: Graceful fallback when APIs fail
### API Rate Limiting
- Uses `GITHUB_TOKEN` environment variable if available
- Provides clear error messages when rate limited
- Falls back to git commands when API fails
### Git Command Failures
- Robust error handling for git ls-remote
- Validation of git command output
- Clear error messages for debugging
## Configuration
### Environment Variables
- `GITHUB_TOKEN`: GitHub personal access token (optional)
- Increases API rate limits from 60/hour to 5000/hour
### Dependencies
- **Required**: `nix` command with experimental features
- **Optional**: `nix-prefetch-git`, `git` commands
- **Python**: Standard library + curses
## Troubleshooting
### Hash Mismatches
1. Check if using correct Nix version
2. Verify network connectivity to GitHub
3. Try manual hash computation:
```bash
nix store prefetch-file --hash-type sha256 <url>
```
### Missing Candidates
1. Check GitHub token availability
2. Verify repository exists and is accessible
3. Check network connectivity
4. Try manual API calls with curl
### Display Issues
1. Ensure terminal supports colors and Unicode
2. Check terminal size (minimum 80x24 recommended)
3. Try resizing terminal window
4. Use `-r` flag to force redraw
## Development
### Adding New Fetcher Types
1. Update `fetch_candidates_for()` method
2. Add parsing logic to appropriate `parse_*()` function
3. Update hash computation methods
4. Add UI handling for new type
### Testing Changes
```bash
# Test individual functions
python3 -c "
from scripts.version_tui import nix_prefetch_url
print(nix_prefetch_url('https://example.com/file.tar.gz'))
"
# Test package parsing
python3 -c "
from scripts.version_tui import parse_python_package
print(parse_python_package(Path('packages/python/example/default.nix')))
"
```
## Architecture Decisions
### Why Multiple Hash Methods?
- Different Nix versions have different available commands
- Modern Nix uses `nix store prefetch-file` and `nix eval`
- Legacy systems use `nix-prefetch-url` and `nix-prefetch-git`
- Script tries modern methods first, falls back gracefully
### Why Template Rendering?
- Variables allow flexible version specifications
- Supports `${variable}` substitution in URLs and tags
- Enables consistent updates across variants
- Reduces duplication in version.json files
### Why Two-Step Git Hash?
- `builtins.fetchGit` provides store paths, not hashes
- `nix hash path` works reliably on store paths
- More consistent than trying to parse git command output
- Works with all git repository formats
## File Organization
```
scripts/
├── version_tui.py # Main script
├── __pycache__/ # Python cache
└── README_tui.md # This documentation
```
## Security Considerations
- No sensitive data is logged
- GitHub tokens are handled securely via environment
- Hash computation uses read-only operations
- No credentials are stored or transmitted unnecessarily
## Performance
- Lazy loading of candidates (only when needed)
- Caching of computed hashes during session
- Parallel network requests where possible
- Efficient terminal rendering with minimal refreshes