commit local changes.
This commit is contained in:
@@ -0,0 +1,201 @@
|
||||
# sjaur
|
||||
|
||||
Fast, fuzzy **TUI search for the [Arch User Repository](https://aur.archlinux.org) and the official Arch Linux repositories** — with real package installation, built on the official AUR metadata dump and your local pacman sync databases.
|
||||
|
||||
```
|
||||
┌ Search: firfox ────────────────────────────────────────────────────────┐
|
||||
├──────────────────────────────────────┬─────────────────────────────────┤
|
||||
│ firefox 130.0-1 +3500 │ Name firefox │
|
||||
│ firefox-nightly 131.0b1 +120 │ Version 130.0-1 │
|
||||
│ firefox-wayland 129.0 +90 │ Maintainer jonas │
|
||||
│ … │ Votes 3500 │
|
||||
│ │ Popularity 214.53 │
|
||||
│ │ … │
|
||||
├──────────────────────────────────────┴─────────────────────────────────┤
|
||||
│ 9 results · 24 ms · cache 2.1 hours old │
|
||||
└────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
Typo-tolerant ranking across name, description, maintainer, keywords,
|
||||
provides, and dependency fields — all served from a local snapshot, so
|
||||
searching never touches the network.
|
||||
|
||||
## Install
|
||||
|
||||
```bash
|
||||
cd sjaur
|
||||
python -m venv .venv
|
||||
.venv/bin/pip install .
|
||||
```
|
||||
|
||||
Then link the executable onto your `PATH` (or copy it):
|
||||
|
||||
```bash
|
||||
sudo ln -s "$(pwd)/.venv/bin/sjaur" /usr/local/bin/sjaur
|
||||
# or, without root:
|
||||
mkdir -p ~/.local/bin && ln -s "$(pwd)/.venv/bin/sjaur" ~/.local/bin/sjaur
|
||||
```
|
||||
|
||||
Requirements: Python ≥ 3.10 and Linux (deps: `rapidfuzz`, `textual`).
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
sjaur # launch the TUI
|
||||
sjaur --update # force a metadata refresh, then exit
|
||||
sjaur --version
|
||||
sjaur --help
|
||||
```
|
||||
|
||||
Optional:
|
||||
|
||||
- `--cache-dir <dir>` overrides the cache location (default `~/.cache/sjaur`)
|
||||
- `--no-repos` searches the AUR only (skip official repository packages)
|
||||
- `--repos-dir <dir>` overrides the pacman sync database directory
|
||||
(default `/var/lib/pacman/sync`)
|
||||
|
||||
## Official repository packages
|
||||
|
||||
By default, sjaur merges the packages of your **local pacman sync databases**
|
||||
(`core`, `extra`, …) into the search index. They appear with a repository
|
||||
badge (`firefox [extra]`), can be installed directly via
|
||||
`sudo pacman -S <name>` (`i` in the TUI — no build step, pacman asks for
|
||||
confirmation), and work with all search features including `@maintainer`
|
||||
(the packager email is used, e.g. `@heftig`). Votes, popularity, and
|
||||
out-of-date status are AUR-only concepts and are hidden for repo packages.
|
||||
|
||||
The databases are read-only and stay where pacman manages them; run
|
||||
`pacman -Sy` as usual to refresh them. On systems without sync databases,
|
||||
sjaur falls back to AUR-only search with a warning.
|
||||
|
||||
## Search syntax
|
||||
|
||||
| Query | Meaning |
|
||||
| --------------------------- | ---------------------------------------------------------------- |
|
||||
| `firefox` | fuzzy search across all package fields |
|
||||
| `@max_musterman` | fuzzy-search the **maintainer** field |
|
||||
| `@max_musterman firefox` | maintainer search combined with a normal search |
|
||||
| `@john python editor` | maintainer query is `john`; `python editor` is the normal query |
|
||||
|
||||
Rules:
|
||||
|
||||
- Only the **first whitespace-delimited word** after `@` is the maintainer
|
||||
query; everything after it is the normal search.
|
||||
- Matching stays fuzzy: `@max_musterman` also finds `max_mustermann`,
|
||||
`max-musterman` or `max_musterman123` — no exact match required.
|
||||
- With `@`, the result score is
|
||||
`maintainer_similarity × 0.65 + package_score × 0.35`, so maintainer matches
|
||||
dominate while the text query still orders the results.
|
||||
- The parser is table-driven, so future operators (e.g. `#keyword`,
|
||||
`depends:python`) can be added without touching the search engine.
|
||||
|
||||
### Live search
|
||||
|
||||
Results update **while you type** — no Enter needed:
|
||||
|
||||
1. On every keystroke the current list is instantly narrowed client-side
|
||||
(packages that no longer match disappear immediately).
|
||||
2. After a short pause (0.18 s), the full fuzzy search over all fields runs
|
||||
in the background and refines the list.
|
||||
|
||||
Editing or retyping a recent query restores its result set instantly from an
|
||||
in-memory cache; the status line shows `live` while you are typing and the
|
||||
measured search time once the background search has finished.
|
||||
|
||||
## Keys
|
||||
|
||||
| Key | Action |
|
||||
| ---------------------- | ----------------------------------------- |
|
||||
| typing | **live search** — results update on every keystroke |
|
||||
| `↑` / `↓` | navigate results |
|
||||
| `enter` | open package details (`esc` returns) |
|
||||
| `i` / `ctrl+i` | install the selected package |
|
||||
| `tab` / `shift+tab` | switch between search field and results |
|
||||
| `page up` / `page down`, `home` / `end` | scroll / jump |
|
||||
| `ctrl+r` | reload AUR metadata now |
|
||||
| `f1` | help overlay |
|
||||
| `esc` | clear search / leave current view |
|
||||
| `ctrl+c` | quit |
|
||||
|
||||
## Installing packages
|
||||
|
||||
With a package highlighted, press `i` (or `ctrl+i`) and confirm with `y`.
|
||||
sjaur then runs the classic AUR workflow with plain system tools:
|
||||
|
||||
1. **Clone** the package repository from
|
||||
`https://aur.archlinux.org/<name>.git` into `~/.cache/sjaur/build/<name>`
|
||||
(an existing clone is **reused**; confirm with `u` instead of `y` to
|
||||
hard-reset and update it first).
|
||||
2. **Review** the PKGBUILD — it is printed to the terminal, and you can open
|
||||
it in `$EDITOR` before deciding. **Always read it**: the AUR ships
|
||||
user-produced build scripts.
|
||||
3. **Build & install** via `makepkg --syncdeps --install`. pacman's
|
||||
confirmation, the sudo password prompt, and the whole build output appear
|
||||
directly in your terminal; the TUI suspends and resumes afterwards.
|
||||
|
||||
The result is reported in the terminal; press Enter to return to sjaur.
|
||||
If anything fails (clone error, dependency problem, aborted build), the
|
||||
message explains what happened and the TUI keeps running.
|
||||
|
||||
> **Security note:** AUR packages are user-produced content. sjaur shows the
|
||||
> PKGBUILD (and any bundled install scripts) before building — never install
|
||||
> packages whose build steps you do not understand.
|
||||
|
||||
## Package details
|
||||
|
||||
Selecting a package shows everything the local snapshot knows — name,
|
||||
version, description, maintainer, votes, popularity, last modified,
|
||||
out-of-date status, upstream URL, AUR page, licenses, groups, keywords,
|
||||
depends, makedepends, checkdepends, optdepends, provides, conflicts, replaces
|
||||
— without any additional network request.
|
||||
|
||||
## Cache behavior
|
||||
|
||||
`sjaur` keeps a decompressed copy of the official extended metadata dump
|
||||
(`https://aur.archlinux.org/packages-meta-ext-v1.json.gz`) in:
|
||||
|
||||
```
|
||||
~/.cache/sjaur/packages-meta-ext-v1.json
|
||||
```
|
||||
|
||||
- At startup the cache's **modification time** is checked; if it is younger
|
||||
than **24 hours** it is used as-is, otherwise a fresh dump is downloaded.
|
||||
- The replacement is **atomic**: the dump is downloaded to a temporary file,
|
||||
decompressed, validated as JSON, and only then swapped in with
|
||||
`os.replace`. A failed download never destroys a working cache.
|
||||
- If the download fails but a (stale) cache exists, the old cache is used and
|
||||
a warning is shown. If there is no usable cache at all, `sjaur` exits with
|
||||
a clear error.
|
||||
- `SJAUR_CACHE_DIR` overrides the cache directory (XDG `XDG_CACHE_HOME` is
|
||||
respected).
|
||||
|
||||
## Development
|
||||
|
||||
```bash
|
||||
python -m venv .venv
|
||||
.venv/bin/pip install -e '.[dev]'
|
||||
.venv/bin/pytest # run the test suite
|
||||
.venv/bin/mypy src # type-check
|
||||
```
|
||||
|
||||
Project layout:
|
||||
|
||||
```
|
||||
sjaur/
|
||||
├── src/sjaur/
|
||||
│ ├── cli.py argument parsing and startup flow
|
||||
│ ├── cache.py download / decompress / validate / atomic replace
|
||||
│ ├── metadata.py typed Package model, tolerant dump parsing
|
||||
│ ├── repodb.py local pacman sync database reader
|
||||
│ ├── query.py extensible query parser (@maintainer, …)
|
||||
│ ├── search.py fuzzy scoring and ranking engine
|
||||
│ ├── installer.py clone / review / makepkg / pacman install workflow
|
||||
│ ├── config.py paths and constants
|
||||
│ ├── errors.py user-facing error types
|
||||
│ └── tui/ Textual application, detail view
|
||||
└── tests/
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
MIT — see [LICENSE](LICENSE).
|
||||
Reference in New Issue
Block a user