diff --git a/README.md b/README.md index c763892..774fb3a 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,8 @@ Also accepts: `SRCINFO` and `info` `inspect`, `install`, `fetch`, and `remove` accept one or more packages (`grimoire install a b c`). - `grimoire inspect ` shows description + all deps (make/check/optional) -- `grimoire install ` clones the repo, resolves dependencies, builds with `makepkg` +- `grimoire install ` clones the repo, resolves dependencies, builds + - Pass `--noconfirm` to skip prompts (install, update, remove, and search) - Pass `--use-ssh` use SSH instead of HTTPS - Pass `--submod` (install/fetch) to init the repo's git submodules after checkout. - `grimoire remove ` to uninstall from pacman @@ -61,7 +62,7 @@ Point at anything else that ships a `PKGBUILD` with `--repo-url`/`--repo` on - `{pkg}` (the package name) or `{pkgbase}` (its pkgbase ex: amd-ucode -> linux-firmware) ```bash - grimoire repo --add 'provider.ext/user/repo/tree/master/pkgs' VUR + grimoire repo --add 'provider.ext/user/repo/tree/master/pkgs' MYVUR grimoire install ``` A bare `search ` queries **every** section in `repos.ini` and merges the results. @@ -109,7 +110,6 @@ On first use, **auto-creates** `~/.config/grimoire/repos.ini` with `[ARCH]` as t ### More info - Respects `IgnorePkg = x y z` from `/etc/pacman.conf` -- Pass `--noconfirm` to skip prompts (install, update, remove, and search) - Completions are also [available](./base/) and have cached search complete. #### Sources/References: @@ -130,7 +130,7 @@ Tools: Packaging examples [proto](https://gitlab.archlinux.org/pacman/pacman/-/tree/master/proto) -### Cryptographic trust +### Git-GPG Trust - Pass `--verify` (`install`/`fetch`) to require a valid GPG signature before building. If you point at an annotated tag (`--rev `) it runs `git verify-tag`, else `git verify-commit` diff --git a/grimoire b/grimoire index 2c842a7..51649ca 100755 --- a/grimoire +++ b/grimoire @@ -360,15 +360,86 @@ def _iter_sync_db_desc( yield db.stem, fields -@cache -def _resolve_pkgbase(package: str) -> str: - # pkgname -> pkgbase via the pacman sync DBs (each `desc` carries %BASE%). Lets a - # pkgbase-keyed forge (Arch GitLab, the AUR) be reached by package name even for - # split packages (amd-ucode -> linux-firmware). Falls back to the name if unknown. +def _local_db_descs( + name_prefix: str | None = None, +) -> Iterator[tuple[str, Path]]: + # (pkgname, entry-dir) for each package in pacman's local db. Reading the dir + # directly avoids a ~50ms subprocess. Entries are name-version-release dirs; + # ALPM_DB_VERSION and other non-package files lack the two trailing -ver-rel parts. + # name_prefix pre-filters by dir name (single-package lookups stay cheap). + try: + entries = (_pacman_db_path() / "local").iterdir() + except OSError: + return + for entry in entries: + name = entry.name + if name_prefix is not None and not name.startswith(name_prefix): + continue + parts = name.rsplit("-", 2) + if len(parts) == 3: + yield parts[0], entry + + +def _local_db_pkgbase(package: str) -> str | None: + # pkgname -> pkgbase from the LOCAL pacman db, covering foreign/AUR installs the sync + # DBs don't list (e.g. fontobene-qt-qt6 -> fontobene-qt). desc carries %BASE% only + # when it differs from the name. None when the package isn't installed locally. + for name, entry in _local_db_descs(f"{package}-"): + if name != package: + continue + try: + raw = (entry / "desc").read_text() + except OSError: + return None + return dict(_DESC_FIELD_RE.findall(raw)).get("BASE") or package + return None + + +def _db_pkgbase(package: str) -> str | None: + # pkgname -> pkgbase from the pacman DBs (each `desc` carries %BASE%): sync DBs for + # official split packages (amd-ucode -> linux-firmware), then the local db for + # foreign/AUR installs the sync DBs don't list. None when neither knows it. for _repo, fields in _iter_sync_db_desc(f"{package}-"): if fields.get("NAME") == package: return fields.get("BASE") or package - return package + return _local_db_pkgbase(package) + + +def _aur_rpc_pkgbase(package: str) -> str | None: + # pkgname -> pkgbase from the AUR RPC: the only source for a split pkg that is neither + # installed nor in the sync DBs (a fresh `install`). Best-effort -- any network/parse + # failure or a miss returns None, so resolution stays offline-tolerant. + from urllib.request import urlopen + + query = urllib.parse.urlencode({"arg[]": package}) + url = f"https://aur.archlinux.org/rpc/v5/info?{query}" + if DEBUG: + print(f"+ GET {url}", file=sys.stderr) + try: + with urlopen(url, timeout=10) as response: # noqa: S310 - hardcoded https AUR endpoint + data = json.loads(response.read().decode()) + except (OSError, ValueError): + return None + for entry in data.get("results", []): + if entry.get("Name") == package: + base = entry.get("PackageBase") + return base if isinstance(base, str) and base else None + return None + + +@cache +def _resolve_pkgbase(package: str) -> str: + # DB-only pkgbase (no network), for the Arch GitLab {pkgbase} template -- a gitlab + # package's base comes from the sync DBs, never the AUR. Falls back to the name. + return _db_pkgbase(package) or package + + +@cache +def _aur_pkgbase(package: str) -> str: + # Branch name on the AUR git mirror (branch-per-pkgbase): DBs first, then the AUR RPC + # for an uninstalled split pkg. Used only at the mirror-access sites. Falls back to + # the name (a non-split pkg, or an offline RPC miss -- the clone then reports absence). + return _db_pkgbase(package) or _aur_rpc_pkgbase(package) or package @cache @@ -1212,11 +1283,13 @@ def ensure_clone( fetch_refspec = () reset_targets = ("origin/HEAD",) else: - # No repo_url -> the AUR git mirror, one branch per package. + # No repo_url -> the AUR git mirror, one branch per PKGBASE (split packages + # share a branch: fontobene-qt-qt6 lives on the fontobene-qt branch). + base = _aur_pkgbase(package) remote_url = get_aur_remote() - clone_extra = ["--branch", package, "--single-branch"] - fetch_refspec = (package,) - reset_targets = (f"origin/{package}",) + clone_extra = ["--branch", base, "--single-branch"] + fetch_refspec = (base,) + reset_targets = (f"origin/{base}",) reuse_existing = package_dir.exists() and (package_dir / ".git").is_dir() if reuse_existing: @@ -1619,18 +1692,9 @@ def invalidate_inst_cache() -> None: def _list_local_db_packages() -> set[str] | None: - # Reading pacman's local db directory directly avoids a ~50ms subprocess. - # Entries are name-version-release dirs; ALPM_DB_VERSION has no dashes. - try: - entries = [entry.name for entry in (_pacman_db_path() / "local").iterdir()] - except OSError: - return None - packages: set[str] = set() - for entry in entries: - parts = entry.rsplit("-", 2) - if len(parts) == 3: - packages.add(parts[0]) - return packages or None + # Installed package names straight from pacman's local db (None when it's unreadable + # or empty, so the caller falls back to `pacman -Qq`). + return {name for name, _ in _local_db_descs()} or None def installed_package_set() -> set[str]: @@ -1767,8 +1831,11 @@ def resolve_official_dependency(dep: str) -> str | None: def exists_in_aur_mirror(package: str) -> bool: if is_debug_package(package): return True + # Branch-per-pkgbase: resolve a split pkgname to its base branch (DBs, then AUR RPC). try: - output = run_command(_aur_mirror_lsremote_cmd(package), capture=True) + output = run_command( + _aur_mirror_lsremote_cmd(_aur_pkgbase(package)), capture=True + ) except GrimoireErr: return False return bool(output.strip()) @@ -1815,8 +1882,11 @@ def _git_remote_head(url: str, ref: str | None) -> str | None: def _aur_remote_head(package: str) -> str | None: + # Branch-per-pkgbase: a split pkgname's head lives on its base branch. try: - output = run_command(_aur_mirror_lsremote_cmd(package), capture=True) + output = run_command( + _aur_mirror_lsremote_cmd(_aur_pkgbase(package)), capture=True + ) except GrimoireErr: return None return _lsremote_first_sha(output) @@ -1899,7 +1969,8 @@ def fetch_git_file(package: str, path: str) -> str | None: # Import the name (not the package) so it doesn't shadow the top-level urllib. from urllib.request import urlopen - safe_package = urllib.parse.quote(package) + # The mirror is branch-per-pkgbase; a split pkgname resolves to its base branch. + safe_package = urllib.parse.quote(_aur_pkgbase(package)) safe_path = path.lstrip("/") url = f"{GITHUB_RAW_BASE}/{safe_package}/{safe_path}" if DEBUG: @@ -3808,147 +3879,152 @@ if __name__ == "__main__": # def _pacman_db_path() :311 # def _iter_db_descs(db, name_prefix) :323 # def _iter_sync_db_desc(name_prefix) :346 -# def _resolve_pkgbase(package) :364 -# def _sync_db_packages() :375 -# def _sync_db_signature() :389 -# def _sync_db_packages_cached() :407 -# def _read_pacman_auth() :418 -# def _get_elev() :432 -# def _elevate(cmd) :442 -# def _maybe_ssh_rewrite(url) :451 -# def _remote_for(url) :466 -# def _ssh_rewrite_git_env() :472 -# def _ensure_scheme(url) :488 -# def _split_forge_path(parts, markers, ref_offset, gate) :503 -# def parse_repo_url(url) :526 -# def _rebuild(repo_parts, ref, sub) :536 -# def _forge_raw_url(clone_url, ref, path) :570 -# def _repo_registry_path() :595 -# def _ensure_repos_conf() :599 -# def load_repo_registry() :611 -# def _repos_section_end(lines, header_idx) :633 -# def add_repo_alias(name, url) :645 -# def remove_repo_alias(name) :675 -# def resolve_repo_alias(name) :691 -# def _aur_enabled() :700 -# def _resolve_repo_for_package(package, alias, repo_url, branch, subdir) :711 -# def _sub(value) :734 -# def _resolve(raw) :749 -# def _resolve_sources(args, package) :761 -# def _cache_get(key, ttl) :796 -# def _atomic_write(path, payload) :809 -# def _cache_put(key, payload) :818 -# def _completion_cache_path() :824 -# def cached_json(key, ttl, fetch) :832 -# def clear_search_cache() :853 -# def clean_clones(dest_root) :868 -# def _remove_clone(package, dest_root) :884 -# def run_command(cmd, cwd, capture, check, env) :897 -# def run_command(cmd, cwd, capture, check, env) :908 -# def run_command(cmd, cwd, capture, check, env) :918 -# def _resolve_build_dir(clone_root, subdir) :950 -# def _resolve_package_dir(clone_root, subdir, package) :962 -# def _tree_has(package_dir, ref, path) :976 -# def _build_subpath(package_dir, ref, subdir, package) :990 -# def _subdir_hint(package_dir, ref, package) :1001 -# def _http_status(url) :1020 -# def _remote_pkgbuild_present(url, ref, subdir, package) :1035 -# def _clone_with_fallback(package_dir, candidates, package) :1061 -# def _normalize_git_url(url) :1128 -# def _clone_origin(package_dir) :1144 -# def _is_aur_origin(origin) :1155 -# def _origin_label(package_dir) :1161 -# def _init_submodules(clone_root) :1170 -# def ensure_clone(package, dest_root, source, refresh, submodules) :1183 -# def _clone_resolved(package, dest_root, refresh, submodules, source, sources) :1287 -# def _reuse_existing_clone(package, dest_root, sources, submodules) :1307 -# def _clone_any_source(package, dest_root, sources, refresh, submodules) :1337 -# def read_srcinfo(package_dir) :1389 -# def _iter_srcinfo_kv(srcinfo_content) :1398 -# def _str_or_none(value) :1409 -# def _assemble_version(pkgver, pkgrel, epoch) :1413 -# def parse_dependencies(srcinfo_content) :1430 -# def _normalize_dep(dep_entry) :1462 -# def _pkgbase_guesses(dep) :1471 -# def parse_srcinfo_metadata(srcinfo_content) :1482 -# def _reset_git_worktree(package_dir, refs) :1496 -# def _ref_is_annotated_tag(package_dir, ref) :1528 -# def _classify_verify_failure(output, min_trust) :1540 -# def _verify_signature(package_dir, package, ref, min_trust) :1560 -# def _pacman_returns_zero(args) :1601 -# def invalidate_inst_cache() :1617 -# def _list_local_db_packages() :1621 -# def installed_package_set() :1636 -# def is_installed(package) :1649 -# def exists_in_sync_repo(package) :1654 -# def is_dependency_satisfied(dep) :1658 -# def package_provides(package) :1663 -# def _search_aur_candidates(dep, limit) :1676 -# def resolve_aur_dependency(dep) :1703 -# def add_candidate(name) :1709 -# def resolve_official_dependency(dep) :1745 -# def exists_in_aur_mirror(package) :1767 -# def list_foreign_packages() :1777 -# def _local_head(package_dir) :1795 -# def _git_remote_head(url, ref) :1807 -# def _aur_remote_head(package) :1817 -# def get_installed_version(package) :1825 -# def list_installed_packages() :1837 -# def list_repo_packages(name, dest_root) :1851 -# def fetch_git_file(package, path) :1897 -# def git_srcinfo_metadata(package) :1920 -# def install_official_packages(packages, noconfirm) :1930 -# def collect_missing_official_packages(package, dest_root, refresh, visited) :1943 -# def build_and_install(package_dir, noconfirm, refresh) :1989 -# def _classify_build_deps(deps, package) :2009 -# def _confirm_aur_dependencies(aur_dependencies, virtual_providers) :2039 -# def install_package(package, dest_root, refresh, noconfirm, visited, preinstalled_official, source, sources, update_to, verify, min_trust, submodules, local_dir) :2057 -# def _find_pkgbuild_dir(clone_root, package) :2147 -# def build_package(package, dest_root, noconfirm) :2164 -# def remove_package(package, noconfirm) :2182 -# def get_ignored_packages() :2200 -# def _resolve_update_spec(package, alias, url, branch, subdir) :2224 -# def _probe_aur_update(package, dest_root) :2240 -# def _probe_git_update(package, dest_root, source, refresh) :2254 -# def _find_update_source(package, update_specs, dest_root, refresh, branch, subdir) :2281 -# def _run_system_update(noconfirm) :2303 -# def _collect_update_candidates(targets) :2324 -# def _update_target_label(candidate) :2344 -# def _update_source_label(repo, repo_url, update_specs) :2353 -# def _plan_updates(candidates, update_specs, dest_root, ignored, skip_devel, refresh, branch, subdir) :2366 -# def _rebuild_updates(selected, winning_source, dest_root, refresh, noconfirm) :2422 -# def _print_missing_notes(missing, source_label) :2451 -# def update_packages(dest_root, refresh, noconfirm, update_system, include_devel, targets, repo, repo_url, branch, subdir) :2458 -# def search_packages(regex, needle, limit) :2534 -# def _fetch_aur_meta() :2543 -# def _fetch_names_git() :2569 -# def _fetch_aur_packages() :2574 -# def _fetch_aur_packages_with_completion() :2589 -# def aur_packages() :2601 -# def is_regex(pattern) :2611 -# def compute_match_score(name, regex, needle) :2616 -# def search_packages_git(regex, needle, limit) :2641 -# def _repo_package_names(repo_url, branch, subdir, clone_dir) :2673 -# def _enumerate_repo(repo_url, branch, subdir, dest_root) :2707 -# def search_packages_repo(repo_url, branch, subdir, regex, needle, limit, source, dest_root, alias) :2732 -# def order_search_results(results) :2802 -# def format_search_result(index, result) :2807 -# def format_search_result_plain(result) :2834 -# def print_search_results(results) :2846 -# def interactive_select_updates(candidates) :2854 -# def parse_selection(selection, max_index) :2890 -# def interactive_select_results(results) :2926 -# def _join_values(values, sort) :2952 -# def _srcinfo_values(srcinfo_content, key) :2957 -# def srcinfo_info_fields(package, srcinfo_content, repo) :2961 -# def first(key) :2968 -# def join(values) :2972 -# def print_info_fields(fields) :2992 -# def _print_info_summary(package, description, deps) :2998 -# def inspect_package(package, dest_root, refresh, target, source, sources, plain) :3020 -# def fetch_package(package, dest_root, refresh, source, sources, verify, min_trust, submodules) :3053 -# def _search_all_sources(alias, repo_url, regex, needle, limit, branch, subdir, dest_root) :3079 -# def _install_search_picks(selected, dest_root, explicit_url, branch, subdir, refresh, noconfirm) :3132 -# def build_parser() :3180 -# def main(argv) :3473 +# def _local_db_descs(name_prefix) :363 +# def _local_db_pkgbase(package) :383 +# def _db_pkgbase(package) :398 +# def _aur_rpc_pkgbase(package) :408 +# def _resolve_pkgbase(package) :431 +# def _aur_pkgbase(package) :438 +# def _sync_db_packages() :446 +# def _sync_db_signature() :460 +# def _sync_db_packages_cached() :478 +# def _read_pacman_auth() :489 +# def _get_elev() :503 +# def _elevate(cmd) :513 +# def _maybe_ssh_rewrite(url) :522 +# def _remote_for(url) :537 +# def _ssh_rewrite_git_env() :543 +# def _ensure_scheme(url) :559 +# def _split_forge_path(parts, markers, ref_offset, gate) :574 +# def parse_repo_url(url) :597 +# def _rebuild(repo_parts, ref, sub) :607 +# def _forge_raw_url(clone_url, ref, path) :641 +# def _repo_registry_path() :666 +# def _ensure_repos_conf() :670 +# def load_repo_registry() :682 +# def _repos_section_end(lines, header_idx) :704 +# def add_repo_alias(name, url) :716 +# def remove_repo_alias(name) :746 +# def resolve_repo_alias(name) :762 +# def _aur_enabled() :771 +# def _resolve_repo_for_package(package, alias, repo_url, branch, subdir) :782 +# def _sub(value) :805 +# def _resolve(raw) :820 +# def _resolve_sources(args, package) :832 +# def _cache_get(key, ttl) :867 +# def _atomic_write(path, payload) :880 +# def _cache_put(key, payload) :889 +# def _completion_cache_path() :895 +# def cached_json(key, ttl, fetch) :903 +# def clear_search_cache() :924 +# def clean_clones(dest_root) :939 +# def _remove_clone(package, dest_root) :955 +# def run_command(cmd, cwd, capture, check, env) :968 +# def run_command(cmd, cwd, capture, check, env) :979 +# def run_command(cmd, cwd, capture, check, env) :989 +# def _resolve_build_dir(clone_root, subdir) :1021 +# def _resolve_package_dir(clone_root, subdir, package) :1033 +# def _tree_has(package_dir, ref, path) :1047 +# def _build_subpath(package_dir, ref, subdir, package) :1061 +# def _subdir_hint(package_dir, ref, package) :1072 +# def _http_status(url) :1091 +# def _remote_pkgbuild_present(url, ref, subdir, package) :1106 +# def _clone_with_fallback(package_dir, candidates, package) :1132 +# def _normalize_git_url(url) :1199 +# def _clone_origin(package_dir) :1215 +# def _is_aur_origin(origin) :1226 +# def _origin_label(package_dir) :1232 +# def _init_submodules(clone_root) :1241 +# def ensure_clone(package, dest_root, source, refresh, submodules) :1254 +# def _clone_resolved(package, dest_root, refresh, submodules, source, sources) :1360 +# def _reuse_existing_clone(package, dest_root, sources, submodules) :1380 +# def _clone_any_source(package, dest_root, sources, refresh, submodules) :1410 +# def read_srcinfo(package_dir) :1462 +# def _iter_srcinfo_kv(srcinfo_content) :1471 +# def _str_or_none(value) :1482 +# def _assemble_version(pkgver, pkgrel, epoch) :1486 +# def parse_dependencies(srcinfo_content) :1503 +# def _normalize_dep(dep_entry) :1535 +# def _pkgbase_guesses(dep) :1544 +# def parse_srcinfo_metadata(srcinfo_content) :1555 +# def _reset_git_worktree(package_dir, refs) :1569 +# def _ref_is_annotated_tag(package_dir, ref) :1601 +# def _classify_verify_failure(output, min_trust) :1613 +# def _verify_signature(package_dir, package, ref, min_trust) :1633 +# def _pacman_returns_zero(args) :1674 +# def invalidate_inst_cache() :1690 +# def _list_local_db_packages() :1694 +# def installed_package_set() :1700 +# def is_installed(package) :1713 +# def exists_in_sync_repo(package) :1718 +# def is_dependency_satisfied(dep) :1722 +# def package_provides(package) :1727 +# def _search_aur_candidates(dep, limit) :1740 +# def resolve_aur_dependency(dep) :1767 +# def add_candidate(name) :1773 +# def resolve_official_dependency(dep) :1809 +# def exists_in_aur_mirror(package) :1831 +# def list_foreign_packages() :1844 +# def _local_head(package_dir) :1862 +# def _git_remote_head(url, ref) :1874 +# def _aur_remote_head(package) :1884 +# def get_installed_version(package) :1895 +# def list_installed_packages() :1907 +# def list_repo_packages(name, dest_root) :1921 +# def fetch_git_file(package, path) :1967 +# def git_srcinfo_metadata(package) :1991 +# def install_official_packages(packages, noconfirm) :2001 +# def collect_missing_official_packages(package, dest_root, refresh, visited) :2014 +# def build_and_install(package_dir, noconfirm, refresh) :2060 +# def _classify_build_deps(deps, package) :2080 +# def _confirm_aur_dependencies(aur_dependencies, virtual_providers) :2110 +# def install_package(package, dest_root, refresh, noconfirm, visited, preinstalled_official, source, sources, update_to, verify, min_trust, submodules, local_dir) :2128 +# def _find_pkgbuild_dir(clone_root, package) :2218 +# def build_package(package, dest_root, noconfirm) :2235 +# def remove_package(package, noconfirm) :2253 +# def get_ignored_packages() :2271 +# def _resolve_update_spec(package, alias, url, branch, subdir) :2295 +# def _probe_aur_update(package, dest_root) :2311 +# def _probe_git_update(package, dest_root, source, refresh) :2325 +# def _find_update_source(package, update_specs, dest_root, refresh, branch, subdir) :2352 +# def _run_system_update(noconfirm) :2374 +# def _collect_update_candidates(targets) :2395 +# def _update_target_label(candidate) :2415 +# def _update_source_label(repo, repo_url, update_specs) :2424 +# def _plan_updates(candidates, update_specs, dest_root, ignored, skip_devel, refresh, branch, subdir) :2437 +# def _rebuild_updates(selected, winning_source, dest_root, refresh, noconfirm) :2493 +# def _print_missing_notes(missing, source_label) :2522 +# def update_packages(dest_root, refresh, noconfirm, update_system, include_devel, targets, repo, repo_url, branch, subdir) :2529 +# def search_packages(regex, needle, limit) :2605 +# def _fetch_aur_meta() :2614 +# def _fetch_names_git() :2640 +# def _fetch_aur_packages() :2645 +# def _fetch_aur_packages_with_completion() :2660 +# def aur_packages() :2672 +# def is_regex(pattern) :2682 +# def compute_match_score(name, regex, needle) :2687 +# def search_packages_git(regex, needle, limit) :2712 +# def _repo_package_names(repo_url, branch, subdir, clone_dir) :2744 +# def _enumerate_repo(repo_url, branch, subdir, dest_root) :2778 +# def search_packages_repo(repo_url, branch, subdir, regex, needle, limit, source, dest_root, alias) :2803 +# def order_search_results(results) :2873 +# def format_search_result(index, result) :2878 +# def format_search_result_plain(result) :2905 +# def print_search_results(results) :2917 +# def interactive_select_updates(candidates) :2925 +# def parse_selection(selection, max_index) :2961 +# def interactive_select_results(results) :2997 +# def _join_values(values, sort) :3023 +# def _srcinfo_values(srcinfo_content, key) :3028 +# def srcinfo_info_fields(package, srcinfo_content, repo) :3032 +# def first(key) :3039 +# def join(values) :3043 +# def print_info_fields(fields) :3063 +# def _print_info_summary(package, description, deps) :3069 +# def inspect_package(package, dest_root, refresh, target, source, sources, plain) :3091 +# def fetch_package(package, dest_root, refresh, source, sources, verify, min_trust, submodules) :3124 +# def _search_all_sources(alias, repo_url, regex, needle, limit, branch, subdir, dest_root) :3150 +# def _install_search_picks(selected, dest_root, explicit_url, branch, subdir, refresh, noconfirm) :3203 +# def build_parser() :3251 +# def main(argv) :3544 ############# diff --git a/repos.ini b/repos.ini index 97d1c86..79cdbeb 100644 --- a/repos.ini +++ b/repos.ini @@ -1,11 +1,12 @@ # grimoire repo aliases -- example / reference. +# DO NOT EDIT ME: Lives at $XDG_CONFIG_HOME/grimoire/repos.ini +# You can do grimaur --help once to make sure it exists. # # Each [NAME] is a source. Section order is precedence: with no --repo, install / fetch / # inspect / update walk sections top to bottom and use the FIRST that has the package (the # rest are fallbacks); --repo forces one. A bare `search` queries every section and # merges the results (like `pacman -Ss`). Can be managed with `grimoire repo --add/--rm/--ls`. -# Lives at $XDG_CONFIG_HOME/grimoire/repos.ini (usually ~/.config/grimoire/repos.ini). -# +# # URL placeholders, substituted per package: # {pkg} -> the package name # {pkgbase} -> its pkgbase (from the local pacman sync DBs, so split packages resolve)