Files

538 lines
18 KiB
Go

// Package depmap maps Arch Linux dependency relations onto Zeta package
// names.
//
// The name tables (zetapkgs, renames, dropped) are checked-in literals so the
// mapping is hermetic: zetapkgs mirrors the authoritative
// zeta-packages/packages/index.lua "name = ..." entries.
package depmap
import (
"fmt"
"strings"
)
// MapDep maps a single Arch dependency relation to a Zeta dependency string.
//
// Input forms: "name", "name>=1.2", or the optdepend form "name: description".
// It returns ("", false) when the dependency is dropped (base-system packages
// Zeta provides outside the package manager). Every drop, rename, and
// unmapped passthrough fires warn (nil-safe).
func MapDep(spec string, warn func(string)) (string, bool) {
if warn == nil {
warn = func(string) {}
}
// 1. Optdepend description form "name: description" — keep the
// name+constraint part only.
if i := strings.Index(spec, ": "); i >= 0 {
spec = spec[:i]
}
// 2. Split the base name from the version constraint. Arch dependency
// names never contain the operator characters, so the first one found
// starts the constraint.
name, constraint := splitConstraint(spec)
// Zeta's vercmp.parse_dep accepts "=" but normalizes it to "=="
// internally; do the same so emitted specs match Zeta convention.
constraint = normalizeConstraint(constraint)
// 3. Verbatim match against the Zeta package index → passthrough.
if _, ok := zetapkgs[name]; ok {
return name + constraint, true
}
// 4. Known Arch→Zeta rename (case fixes included) → rename, keep the
// constraint.
if to, ok := renames[name]; ok {
warn(fmt.Sprintf("renamed dependency %q -> %q", name, to))
return to + constraint, true
}
// 5. Base-system packages Zeta has no package for → drop.
if _, ok := dropped[name]; ok {
warn(fmt.Sprintf("dropping base-system dependency %q", name))
return "", false
}
// 6. Not in Zeta at all → passthrough loudly.
warn(fmt.Sprintf("unmapped dependency %q (passed through)", name+constraint))
return name + constraint, true
}
// splitConstraint returns the base package name and the raw constraint
// ("", ">=1.2", ...). The split happens at the first operator character
// ('<', '>', '=', '~'); Arch package names never contain these.
func splitConstraint(spec string) (name, constraint string) {
for i := 0; i < len(spec); i++ {
switch spec[i] {
case '<', '>', '=', '~':
return strings.TrimSpace(spec[:i]), spec[i:]
}
}
return strings.TrimSpace(spec), ""
}
// normalizeConstraint rewrites a bare "=" operator to "==" (Zeta's canonical
// form) and leaves every other operator untouched.
func normalizeConstraint(constraint string) string {
trimmed := strings.TrimLeft(constraint, " \t")
if strings.HasPrefix(trimmed, "=") && !strings.HasPrefix(trimmed, "==") {
return constraint[:len(constraint)-len(trimmed)] + "==" + trimmed[1:]
}
return constraint
}
// zetapkgs is the set of every Zeta package name, checked in verbatim from
// zeta-packages/packages/index.lua ("name = ..." entries).
var zetapkgs = map[string]struct{}{
"a52dec": {},
"acl": {},
"adwaita-icon-theme": {},
"adwaita-icon-theme-legacy": {},
"alacritty": {},
"alsa-lib": {},
"aquamarine": {},
"atkmm": {},
"at-spi2-core": {},
"avahi": {},
"bitstreamvera": {},
"brotli": {},
"btop": {},
"bubblewrap": {},
"bzip2": {},
"cairo": {},
"cairomm": {},
"caja": {},
"cava": {},
"cjson": {},
"cmatrix": {},
"composefs": {},
"cpio": {},
"ctwm": {},
"dav1d": {},
"dbus": {},
"dbus-glib": {},
"dejavusans": {},
"discord": {},
"doas": {},
"double-conversion": {},
"edelib": {},
"egl": {},
"eom": {},
"exo": {},
"expat": {},
"extra-cmake-modules": {},
"faad2": {},
"fastfetch": {},
"fd": {},
"femboysay": {},
"fftw3": {},
"file": {},
"firefox": {},
"fish": {},
"flac": {},
"flatpak": {},
"fltk": {},
"fmt": {},
"fontconfig": {},
"freetype": {},
"fribidi": {},
"fvwm3": {},
"garcon": {},
"gdk-pixbuf": {},
"git": {},
"glib": {},
"glibmm": {},
"gmp": {},
"gnupg": {},
"gnutls": {},
"gobject-introspection": {},
"gpgme": {},
"graphene": {},
"gsettings-desktop-schemas": {},
"gtk3": {},
"gtk4": {},
"gtk-layer-shell": {},
"gtkmm3": {},
"gtkmm4": {},
"gtksourceview4": {},
"gzip": {},
"harfbuzz": {},
"hello": {},
"hicolor-icon-theme": {},
"htop": {},
"hwdata": {},
"hyprgraphics": {},
"hyprland": {},
"hyprlang": {},
"hyprpaper": {},
"hyprtoolkit": {},
"hyprutils": {},
"hyprwayland-scanner": {},
"hyprwire": {},
"icu": {},
"imlib2": {},
"iniparser": {},
"iso-codes": {},
"jam": {},
"json-c": {},
"jsoncpp": {},
"kidletime": {},
"kwindowsystem": {},
"labwc": {},
"larp": {},
"layer-shell-qt": {},
"lcms2": {},
"leancrypto": {},
"less": {},
"libappstream": {},
"libarchive": {},
"libassuan": {},
"libb2": {},
"libcanberra": {},
"libcurl": {},
"libdaemon": {},
"libdbusmenu-lxqt": {},
"libdconf": {},
"libdisplay-info": {},
"libdrm": {},
"libebml": {},
"libepoxy": {},
"libevdev": {},
"libevent": {},
"libexif": {},
"libffi": {},
"libfm-extra": {},
"libfm-qt": {},
"libfontenc": {},
"libfuse3": {},
"libfyaml": {},
"libgcrypt": {},
"libglvnd": {},
"libgpg-error": {},
"libgtop": {},
"libgudev": {},
"libICE": {},
"libidn2": {},
"libinput": {},
"libjpeg-turbo": {},
"libjson-glib": {},
"libksba": {},
"liblxqt": {},
"libmatekbd": {},
"libmateweather": {},
"libmatroska": {},
"libmtdev": {},
"libnl": {},
"libnotify": {},
"libogg": {},
"libostree": {},
"libpciaccess": {},
"libpeas": {},
"libpng": {},
"libpsl": {},
"libqtxdg": {},
"libreoffice": {},
"libreoffice-core": {},
"libreoffice-help": {},
"libreoffice-share": {},
"librsvg": {},
"libseccomp": {},
"libshout": {},
"libsigc++": {},
"libsigc++2": {},
"libSM": {},
"libsndfile": {},
"libsoup2": {},
"libsoup3": {},
"libtasn1": {},
"libtdb": {},
"libtheora": {},
"libtinfo": {},
"libtirpc": {},
"libudev": {},
"libunistring": {},
"libuuid": {},
"libva": {},
"libvorbis": {},
"libvpx": {},
"libwacom": {},
"libwebp": {},
"libwnck3": {},
"libX11": {},
"libXau": {},
"libXaw": {},
"libxcb": {},
"libxcb-xrm": {},
"libXcomposite": {},
"libXcursor": {},
"libxcvt": {},
"libXdamage": {},
"libXdmcp": {},
"libXext": {},
"libxfce4ui": {},
"libxfce4util": {},
"libxfce4windowing": {},
"libXfixes": {},
"libXfont2": {},
"libXft": {},
"libXi": {},
"libXinerama": {},
"libXkbfile": {},
"libxklavier": {},
"libxml2": {},
"libxmlb": {},
"libXmu": {},
"libXpm": {},
"libXpresent": {},
"libXrandr": {},
"libXrender": {},
"libXres": {},
"libxshmfence": {},
"libxss": {},
"libXt": {},
"libXtst": {},
"libXvMC": {},
"libXxf86vm": {},
"libyaml": {},
"libz": {},
"lm-sensors": {},
"lua51": {},
"luajit": {},
"luv": {},
"lxqt": {},
"lxqt-about": {},
"lxqt-build-tools": {},
"lxqt-config": {},
"lxqt-globalkeys": {},
"lxqt-menu-data": {},
"lxqt-notificationd": {},
"lxqt-panel": {},
"lxqt-policykit": {},
"lxqt-powermanagement": {},
"lxqt-qtplugin": {},
"lxqt-runner": {},
"lxqt-session": {},
"lxqt-themes": {},
"lz4": {},
"make": {},
"mango": {},
"marco": {},
"mate": {},
"mate-backgrounds": {},
"mate-calc": {},
"mate-control-center": {},
"mate-desktop": {},
"mate-icon-theme": {},
"mate-menus": {},
"mate-notification-daemon": {},
"mate-panel": {},
"mate-polkit": {},
"mate-power-manager": {},
"mate-session-manager": {},
"mate-settings-daemon": {},
"mate-terminal": {},
"mate-utils": {},
"md4c": {},
"menu-cache": {},
"mesa": {},
"mesa-dri-gallium": {},
"mesa-gl": {},
"micro": {},
"mksh": {},
"mm-common": {},
"mpc": {},
"mpfr": {},
"mpg123": {},
"muparser": {},
"neovim": {},
"nettle": {},
"nghttp2": {},
"npth": {},
"nscde": {},
"nss": {},
"ntbtls": {},
"nvidia": {},
"nvidia-compiler": {},
"nvidia-cuda": {},
"nvidia-firmware": {},
"nvidia-kernel": {},
"nvidia-optix": {},
"nvidia-utils": {},
"openbox": {},
"opencode": {},
"openssl": {},
"opsec": {},
"opus": {},
"p11-kit": {},
"pango": {},
"pangomm": {},
"pcmanfm-qt": {},
"pcre2": {},
"pekwm": {},
"pinentry": {},
"pipewire": {},
"pixman": {},
"plasma-wayland-protocols": {},
"pluma": {},
"polkit": {},
"polkit-qt-1": {},
"procps-ng": {},
"pugixml": {},
"pulseaudio": {},
"qt5": {},
"qtbase": {},
"qtdeclarative": {},
"qterminal": {},
"qtermwidget": {},
"qtshadertools": {},
"qtsvg": {},
"qttools": {},
"qtwayland": {},
"ripgrep": {},
"rofi": {},
"rsync": {},
"scenefx": {},
"sdl2": {},
"seatd": {},
"setxkbmap": {},
"shared-mime-info": {},
"solid": {},
"spdlog": {},
"speex": {},
"spirv-tools": {},
"sqlite": {},
"startup-notification": {},
"swaybg": {},
"taglib": {},
"tango-icon-theme": {},
"tar": {},
"thunar": {},
"tllist": {},
"tree": {},
"tree-sitter": {},
"tslib": {},
"twolame": {},
"unibilium": {},
"unzip": {},
"upower": {},
"util-macros": {},
"vim": {},
"vlc": {},
"vte": {},
"vulkan-headers": {},
"waybar": {},
"wayland": {},
"wayland-protocols": {},
"wget": {},
"which": {},
"wlroots": {},
"wlr-protocols": {},
"wmaker": {},
"wofi": {},
"xauth": {},
"xcb-proto": {},
"xcb-util": {},
"xcb-util-cursor": {},
"xcb-util-image": {},
"xcb-util-keysyms": {},
"xcb-util-renderutil": {},
"xcb-util-wm": {},
"xdg-desktop-portal": {},
"xdg-user-dirs": {},
"xdpyinfo": {},
"xf86-input-libinput": {},
"xf86-video-intel": {},
"xfce4": {},
"xfce4-appfinder": {},
"xfce4-dev-tools": {},
"xfce4-notifyd": {},
"xfce4-panel": {},
"xfce4-power-manager": {},
"xfce4-session": {},
"xfce4-settings": {},
"xfce4-terminal": {},
"xfconf": {},
"xfdesktop": {},
"xfwm4": {},
"xgamma": {},
"xinit": {},
"xkbcommon": {},
"xkbcomp": {},
"xkeyboard-config": {},
"xmessage": {},
"xmodmap": {},
"xorg-full": {},
"xorgproto": {},
"xorg-server": {},
"xprop": {},
"xrandr": {},
"xrdb": {},
"xset": {},
"xshmfence": {},
"xterm": {},
"xtrans": {},
"xwayland": {},
"xz-utils": {},
"zip": {},
"zsh": {},
"zstd": {},
}
// renames maps Arch Linux package names to their Zeta counterparts. Sources
// are Arch's canonical (lowercase) spelling; targets are the verbatim names
// in zetapkgs. The libX* entries are pure case fixes (Arch spells the X11
// family lowercase); libxcb and friends are already correct in Zeta and
// deliberately absent.
var renames = map[string]string{
"zlib": "libz",
"xz": "xz-utils",
"freetype2": "freetype",
"libxkbcommon": "xkbcommon",
"libice": "libICE",
"libsm": "libSM",
"libx11": "libX11",
"libxau": "libXau",
"libxaw": "libXaw",
"libxcomposite": "libXcomposite",
"libxcursor": "libXcursor",
"libxdamage": "libXdamage",
"libxdmcp": "libXdmcp",
"libxext": "libXext",
"libxfixes": "libXfixes",
"libxfont2": "libXfont2",
"libxft": "libXft",
"libxi": "libXi",
"libxinerama": "libXinerama",
"libxkbfile": "libXkbfile",
"libxmu": "libXmu",
"libxpm": "libXpm",
"libxpresent": "libXpresent",
"libxrandr": "libXrandr",
"libxrender": "libXrender",
"libxres": "libXres",
"libxt": "libXt",
"libxtst": "libXtst",
"libxvmc": "libXvMC",
"libxxf86vm": "libXxf86vm",
}
// dropped lists Arch base-system packages that Zeta provides outside the
// package manager and therefore has no package for (mirroring the dbus and
// libudev stubs in the index).
var dropped = map[string]struct{}{
"glibc": {},
"gcc-libs": {},
"gcc": {},
"bash": {},
"coreutils": {},
"filesystem": {},
"linux-api-headers": {},
"systemd": {},
"util-linux": {},
"ncurses": {},
"readline": {},
"tzdata": {},
"ca-certificates": {},
}