Skip to content

Add an AUR package manager driven by paru or yay - #5749

Open
Gabriel Dufresne (GabrielDuf) wants to merge 5 commits into
mainfrom
feature/aur-helpers
Open

Gabriel Dufresne (GabrielDuf) wants to merge 5 commits into
mainfrom
feature/aur-helpers

Conversation

@GabrielDuf

Copy link
Copy Markdown
Contributor

Fixes #5734

Adds an AUR package manager on Arch-based distributions, driven by paru or yay (whichever is found first, paru preferred). It is offered next to Pacman wherever /etc/os-release names the arch family.

What it does

  • Search (-Ss --aur), details (-Si --aur: maintainer, AUR page link to the PKGBUILD, dependencies), install/update (-S --aur … aur/<name>), uninstall (-Rs), update check (-Qua).
  • Installed list comes from pacman -Qm directly, not the helper, so AUR packages stay visible even when a libalpm soname bump breaks paru/yay until they are rebuilt. While the AUR manager is ready, Pacman lists only native packages (-Qn), so nothing shows twice.
  • Never elevated: makepkg refuses to run as root. A new MustNotRunElevated capability makes RequestsElevation ignore "Run as administrator" (including per-package overrides), and the manager reports itself unavailable while UniGetUI runs as root. The helper receives UniGetUI's own elevator through --sudo/--sudoflags, so pacman's install step uses the same askpass (or pkexec) prompt.
  • Non-interactive: PKGBUILD review is skipped (--skipreview for paru, --answer*=None for yay); the helper is identified from --version, and an unidentified one only gets the options both understand.
  • Version comparison: Pacman and AUR now use AlpmVersion, a port of libalpm's alpm_pkg_vercmp. The default numeric comparison read the pkgrel as a version segment (it ranked 1.0-2 above 1.0.1-1 and hid that update) and misordered epochs. AGENTS.md is updated accordingly.
  • Pacman's dependency parsing and install-location lookup move to a shared AlpmOutput class, used by both managers.
  • The description warns that AUR packages are user-produced and not reviewed by Arch Linux, as discussed in the issue.

Verification

  • Ran end to end on real Arch Linux in a throwaway archlinux:latest CI job (not part of this PR, branch since deleted), once with only paru and once with only yay, as an unprivileged user: detection and paru/yay identification, search, details, install of pfetch from the AUR through InstallPackageOperation (with "Run as administrator" set, and correctly ignored), the package listed exactly once under AUR and not under Pacman, a clean update check, and uninstall. 127/127 tests passed in both jobs.
    • The first run caught a real bug: yay -S --aur pfetch installed extra/pfetch-rs because it provides pfetch. Targets are now named aur/<name>, fixed in the second commit.
  • Real paru and yay output captured in that run is now used as test fixtures (search lines, yay's wrapped -Si layout).
  • Unit tests: AurManagerTests, AlpmVersionTests (libalpm's vercmp cases, both directions), plus the setup-guide, reinstall-on-update, broker-request and package-operation suites. Both dotnet format gates pass.

Not covered

  • The graphical askpass prompt itself (CI used passwordless sudo; it proves the elevator and flags are passed through).
  • An actual upgrade of an outdated AUR package (the update check ran and correctly found nothing; upgrades use the same -S … aur/<name> command as installs).
  • A confirmation dialog when the manager is turned on; the warning is in the description for now.

🤖 Generated with Claude Code

Arch users get most of their software from the AUR, which pacman cannot
reach. A new AUR manager (id `aur`, offered on the arch family next to
Pacman) searches, installs, updates and removes AUR packages through
paru or yay, whichever is found first, preferring paru.

Building:
- makepkg refuses to run as root, so the helper always runs as the
  user. The new MustNotRunElevated capability makes RequestsElevation
  ignore "run as administrator", including per-package overrides, and
  the manager reports itself unavailable while UniGetUI runs as root.
  CanRunAsAdmin could not carry this: WinInstaller, MacPkg and Homebrew
  also leave it false.
- The helper gets UniGetUI's own elevator through --sudo/--sudoflags, so
  pacman's install step uses the same sudo askpass (or pkexec) prompt.
  The sudo loop is turned off for an elevator that is not sudo.
- No terminal is attached, so PKGBUILD review is skipped: --skipreview
  for paru, --answerclean/diff/edit=None for yay. The helper is
  identified from --version, then its file name; an unidentified one
  only gets the options both understand. paru reads `--sudoloop=false`
  as sudo flags and yay has no --nosudoloop, hence the per-helper
  spelling.
- Every flag and output format was checked against the paru and yay
  sources; neither has been run end to end on Arch yet.

Listing:
- Installed AUR packages come from `pacman -Qm`, not the helper, so they
  stay visible when a libalpm soname bump breaks paru or yay until they
  are rebuilt. While the AUR manager is ready, Pacman lists only native
  packages (-Qn), so nothing shows twice.
- Updates come from `-Qua`; ignored packages and paru's `latest-commit`
  devel entries are skipped. Exit code 1 with no results means "nothing
  found" only when stderr reports no error, so offline checks fail
  visibly instead of looking empty.
- Listings register their process for the timeout kill and read stderr
  concurrently, so a chatty helper cannot deadlock on a full pipe.
- Details show the maintainer and link the AUR page (which leads to the
  PKGBUILD), as suggested in the issue; makedepends are not presented
  as runtime dependencies.

Pacman and AUR now compare versions with AlpmVersion, a port of
libalpm's alpm_pkg_vercmp. The default numeric comparison reads the
pkgrel as a version segment, so it ranked 1.0-2 above 1.0.1-1 and hid
that update; epochs misordered the same way. Pacman's dependency parsing
and install-location lookup move to a shared AlpmOutput class.

The manager description warns that AUR packages are user-produced and
not reviewed by Arch Linux. A confirmation when the manager is turned on
is left for a follow-up.

Fixes #5734

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Running the manager end to end on Arch Linux showed `yay -S --aur pfetch`
installing extra/pfetch-rs instead: --aur restricts yay's search mode,
but a target name is still satisfied by any sync package that provides
it, and pfetch-rs provides pfetch. The repository package then never
shows up under the AUR manager, and the user did not get the package
they picked. Naming the target `aur/<name>` makes both paru and yay take
it from the AUR. Uninstalls keep the bare name, which pacman resolves.

The same run captured real paru and yay output; search lines and yay's
wrapped -Si layout from it are now test fixtures, and they parse as the
hand-written ones did.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions github-actions Bot added the new-feature A new feature that could be useful in WingetUI label Nov 13, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

AUR operations can bypass prohibited elevation, and uninstall-before-update can remove the selected helper before reinstalling it, leaving AUR operations broken.

6 open issues
What changed in this PR

Adds AUR support to UniGetUI on Arch-based Linux distributions through paru or yay, alongside the existing Pacman integration.

Changes:

  • Adds AUR discovery, package listings, details, and operations with helper-specific arguments and elevation handling.
  • Shares Pacman parsing utilities, introduces libalpm-compatible version comparison, and separates native and foreign package listings.
  • Adds tests, project wiring, setup documentation, and the AUR safety warning.
File Description
src/​UniGetUI.Windows.slnx Includes the AUR project.
src/​UniGetUI.PackageEngine.Tests/​UniGetUI.PackageEngine.Tests.csproj References AUR for testing.
src/​UniGetUI.PackageEngine.Tests/​ReinstallOnUpdateManagerTests.cs Adds AUR capability expectations.
src/​UniGetUI.PackageEngine.Tests/​ManagerSetupGuideTests.cs Includes AUR setup-guide checks.
src/​UniGetUI.PackageEngine.Tests/​AurManagerTests.cs Tests parsing, arguments, detection, and elevation behavior.
src/​UniGetUI.PackageEngine.Tests/​AlpmVersionTests.cs Tests version ordering and Pacman listing selection.
src/​UniGetUI.PackageEngine.PackageEngine/​UniGetUI.PackageEngine.PEInterface.csproj Adds the AUR engine reference.
src/​UniGetUI.PackageEngine.PackageEngine/​PEInterface.cs Registers AUR and coordinates Pacman listings.
src/​UniGetUI.PackageEngine.Managers.Pacman/​Pacman.cs Uses ALPM comparison and conditional native-only listings.
src/​UniGetUI.PackageEngine.Managers.Pacman/​InternalsVisibleTo.cs Exposes internals to tests.
src/​UniGetUI.PackageEngine.Managers.Pacman/​Helpers/​PacmanPkgDetailsHelper.cs Reuses shared parsing and location lookup.
src/​UniGetUI.PackageEngine.Managers.Pacman/​AlpmVersion.cs Implements libalpm-style version comparison.
src/​UniGetUI.PackageEngine.Managers.Pacman/​AlpmOutput.cs Shares dependency parsing and installation-location lookup.
src/​UniGetUI.PackageEngine.Managers.Aur/​UniGetUI.PackageEngine.Managers.Aur.csproj Defines the AUR manager project.
src/​UniGetUI.PackageEngine.Managers.Aur/​InternalsVisibleTo.cs Exposes internals to tests.
src/​UniGetUI.PackageEngine.Managers.Aur/​Helpers/​AurPkgOperationHelper.cs Builds helper-specific operation arguments.
src/​UniGetUI.PackageEngine.Managers.Aur/​Helpers/​AurPkgDetailsHelper.cs Loads AUR details and installation locations.
src/​UniGetUI.PackageEngine.Managers.Aur/​AurOutputParser.cs Parses helper identity and package output.
src/​UniGetUI.PackageEngine.Managers.Aur/​Aur.cs Implements AUR discovery and package listings.
src/​UniGetUI.PackageEngine.Enums/​ManagerCapabilities.cs Adds the no-elevated-execution capability.
src/​UniGetUI.PackageEngine.AgentBroker/​BrokerRequestValidator.cs Honors that capability in elevation requests.
src/​UniGetUI.Avalonia/​ViewModels/​DialogPages/​ManageIgnoredUpdatesViewModel.cs Maps AUR to the Pacman icon.
src/​UniGetUI.Avalonia.slnx Includes the AUR project.
src/​Languages/​lang_en.json Adds the AUR description and safety warning.
docs/​PACKAGE_MANAGERS.md Documents AUR setup, behavior, and limitations.
docs/​CLI.md Lists the stable aur manager identifier.
AGENTS.md Documents Pacman and AUR version-comparison behavior.

Review effort: Balanced

- Refuse operations of managers that elevate on their own while
  elevation is prohibited. With the setting on, ElevatorLoader leaves
  the elevator empty, so the helper received no --sudo and fell back to
  plain sudo for pacman. A new ElevatesItself capability drives the
  refusal in PackageOperation.RefusalBeforeStart, before anything runs.
- Stop offering uninstall-before-update for AUR packages. Updating the
  helper's own package that way removed the executable the reinstall
  then launches. makepkg -S replaces a package in place, so the option
  never had a purpose here.
- Always pass --sudoloop=false to yay. Its sudo loop runs `sudo -v`
  without --sudoflags and retries that until it succeeds, so with a
  sudoloop config and expired credentials the operation waited forever
  instead of opening the askpass prompt. paru passes its flags to the
  loop, so it is still only turned off for an elevator other than sudo.
- Treat exit code 1 with no results as "nothing found" only when stderr
  is empty or warnings only. yay reports a failed RPC call as
  ` -> Get "...": dial tcp: ...` without the word "error", which the
  previous check let through as an empty, successful update check.
- Remove LANGUAGE from listing processes. yay's gotext reads it before
  LC_ALL, so a translated -Si would lose every field ParseDetails reads.
- Set CanListDependencies for AUR, and for Pacman, whose details have
  parsed dependencies all along without the page showing them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Retained helper sudo flags can break pkexec-based package operations, while other unresolved defects can hide incomplete updates, omit installed packages, duplicate dependencies, and break standalone commands.

1 open issue
4 previously missed issues

In code that hasn't changed since last review

Medium severity Treat nonzero update-helper exits as listing failures

src/​UniGetUI.PackageEngine.Managers.Aur/​Aur.cs:184

If the helper emits a valid update row and then exits with a fatal diagnostic, this condition returns the partial results instead of reporting failure. Closing the task logger only records the exit code; PackageManager still leaves LastUpdatesListingFailed false and records a successful health check, so users are not warned that the update listing is incomplete. Throw for every nonzero normalized exit code, regardless of the number of parsed rows.

Medium severity Clear dependencies before reloading package details

src/​UniGetUI.PackageEngine.Managers.Aur/​AurOutputParser.cs:100

PackageDetails.Load reuses the same details object after saved installation options invalidate it, but this parser appends dependencies without clearing the previous list. Each subsequent load duplicates the mandatory and optional dependencies, and dependencies removed upstream remain displayed. Clear the dependency collection before parsing the new details snapshot.

Medium severity Omit GUI-only sudo flags from standalone commands

src/​UniGetUI.PackageEngine.Managers.Aur/​Helpers/​AurPkgOperationHelper.cs:29

This method also supplies GetStandaloneParameters, so copied/manual commands include --sudoflags=-A when the GUI uses sudo with askpass. ElevatorLoader sets SUDO_ASKPASS only in UniGetUI's environment; pasting the command into an independently opened terminal without that variable and with expired credentials makes sudo fail instead of prompting. Keep the GUI elevator flags for executed operations, but omit them for standalone commands so the helper can use terminal-based sudo.

Medium severity Use consistent AUR readiness for each inventory reload

src/​UniGetUI.PackageEngine.PackageEngine/​PEInterface.cs:115

After the manager-initialization timeout, AUR can become ready after the loader skips its listing but before Pacman's background query evaluates this delegate. Pacman then runs -Qn without an AUR listing for that reload, omitting every foreign package. Share one readiness decision across both listings for each reload, or trigger a full inventory reload when AUR finishes late initialization.

6 resolved since last review

Review effort: Balanced

- Always pass --sudoflags with --sudo, empty when the elevator takes no
  arguments. yay applies the command-line value over the sudoflags
  saved in its configuration, so a saved `-A` no longer reaches pkexec.
  paru's config and command line can only add to SudoFlags, so a value
  in paru.conf still does; that is documented rather than worked around
  by replacing the user's whole paru.conf through PARU_CONF.
- Leave --sudo, --sudoflags and the sudo-loop options out of commands
  copied for a terminal. SUDO_ASKPASS exists only in UniGetUI's own
  environment, so `sudo -A` failed there instead of prompting.
- Fail a listing on any nonzero exit, not only an empty one. paru and
  yay exit 0 whenever they print a row, so a nonzero exit with rows
  means part of the list is missing, and it now reaches the manager's
  failure state instead of being shown as complete.
- Clear the dependencies before parsing details. PackageDetails.Load
  reuses the same object when saved options change during a load, and
  each pass appended another copy.
- When manager initialization times out and AUR finishes after the
  first installed-packages reload took its snapshot, reload once more.
  Pacman may have listed with -Qn in that reload while AUR was left out
  of it, hiding every foreign package until the next refresh.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

The AUR follow-up reload can be discarded while the initial package load is active, leaving foreign packages misassigned or missing until a manual refresh; it must wait for the current load to finish.

No open issues 🎉

1 previously missed issue

In code that hasn't changed since last review

Medium severity AUR initialization during load discards the follow-up package reload

src/​UniGetUI.PackageEngine.PackageEngine/​PEInterface.cs:106

If AUR finishes initializing after the initial installed-package load has selected its managers but before that load finishes, this reload is discarded: AbstractPackageLoader.ReloadPackages() returns immediately while IsLoading is true (lines 201–204). The initial load skipped AUR, so foreign packages remain assigned to Pacman—or disappear if Pacman observes AUR becoming ready and uses -Qn—until a manual refresh. Await WaitForCurrentLoadAsync() before requesting the follow-up reload so the late initialization actually refreshes the inventory.

1 resolved since last review

Review effort: Balanced

@randy-but-a-ro randy-but-a-ro Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Pull request was approved automatically: the AI review is complete and all its review threads are resolved. 🎉

Integration Details
{
	"deliveryId": "a90d5560-df7f-11f1-8eff-9df34f2bc22c",
	"headSha": "02059b5d3600ab8c929b27a84cf8bd5af34687f6",
	"reviewer": "copilot-pull-request-reviewer[bot]"
}

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

new-feature A new feature that could be useful in WingetUI

Development

Successfully merging this pull request may close these issues.

[FEATURE REQUEST] Support for AUR helpers

2 participants