The Aura User Guide

Welcome to the User Guide for Aura, a secure, multilingual package manager for Arch Linux.

Aura's original purpose is as an AUR helper, in that it automates the process of installing packages from the Arch User Repositories. It is, however, capable of much more.

New to Aura? Check out Aura's Philosophy or just jump right into Installation!

💡 Tip: You can press s at any time to search this book.

Contact

The Aura Philosophy

The Aura project began in 2012 as an answer to the shortcomings of other AUR helpers. Certain ground-rules were set in the beginning to guide development. They are:

Aura is Pacman

Aura doesn't just mimic pacman; it is pacman. All pacman operations and their sub-options are allowed. Some even hold special meaning in Aura as well.

Arch is Arch - AUR is AUR

-S yields pacman packages and only pacman packages. In Aura, the -A operation is introduced for obtaining AUR packages. -A comes with sub-options you're used to (-u, -s, -i, etc.) and adds new ones to enhance AUR interaction.

Secure Package Building

PKGBUILDs from the AUR are raw bash code and can contain anything. It's a user's responsibility to verify the contents of a PKGBUILD before building, but people sometimes make mistakes and overlook details. Aura scans PKGBUILDs before building to detect bash misuse and other exploits. The -P command is also provided for scanning your own PKGBUILDs.

Downgradibility

Aura allows you to downgrade individual packages to previous versions with -C. It also handles snapshots of your entire system, so that you can roll back whole sets of packages when problems arise. The option -B will save a package state, and -Br will restore a state you select. -Su and -Au also invoke a save automatically.

Arch Linux for Everyone

English is the dominant language of computing and the internet. That said, it's natural that some people are going to be more comfortable working in their native language. From the beginning, Aura has been built with multiple-language support in mind, making it very easy to add new ones.

Haskell

Aura is written in Haskell, which means easy development and beautiful code. Please feel free to use it as a Haskell reference. Aura code demonstrates:

  • Parser combinators (megaparsec)
  • CLI flag handling (optparse-applicative)
  • Concurrency (scheduler)
  • Shell interaction (typed-process)
  • Pretty printing (prettyprinter)
  • Logging (rio)
  • Modern Haskell project architecture (config, CI, distribution)

Installation

Aura is software specific to Arch Linux. It should also work on Arch-derivatives like Manjaro, but would not be useful on any other Linux distribution.

From the AUR

Prebuilt Binary

It is recommended to install the prebuilt binary of Aura:

git clone https://aur.archlinux.org/aura-bin.git
cd aura-bin
makepkg -s
sudo pacman -U <the-package-file-that-makepkg-produces>

Source Package

For users who choose to build packages themselves or who already have an established Haskell development environment, the vanilla aura package is also available.

git clone https://aur.archlinux.org/aura.git
cd aura
makepkg -s
sudo pacman -U <the-package-file-that-makepkg-produces>

Building from Source

You will need the Stack Tool for Haskell to compile Aura yourself. Then:

git clone https://github.com/fosskers/aura.git
cd aura
stack install -- aura

This may take a while to initially build all of Aura's dependencies. Once complete, your aura binary will be available in /home/YOU/.local/bin/.

Keep in mind that this version of Aura won't be tracked in pacman's database, and so it will be easier to miss updates.

Usage

💡 Did you know? Aura has a manpage with every flag explained in detail. Check it out in your terminal with man aura.

Pacman Commands

First and foremost, Aura is compatible with pacman. This gives us access to the following Commands:

  • -S: Search and install official packages.
> sudo aura -S firefox
  • -Q: Query the database of installed packages.
> aura -Qi firefox
Name            : firefox
Version         : 76.0.1-1
Description     : Standalone web browser from mozilla.org
... etc ...
  • -R: Remove installed packages.
> sudo aura -R firefox
  • -U: Install a manually built package.
> makepkg
... building ...
> sudo aura -U aura-bin-3.1.1-1-x86_64.pkg.tar.xz
  • -D: Interact with Pacman's database directly.
> aura -Dk
No database errors have been found!
  • -F: Make queries regarding files owned by packages.
> aura -Fl firefox
firefox usr/
firefox usr/bin/
firefox usr/bin/firefox
firefox usr/lib/
firefox usr/lib/firefox/
firefox usr/lib/firefox/Throbber-small.gif
firefox usr/lib/firefox/application.ini
... etc ...
  • -T: Check if a dependency is satisfied.
> aura -T firefox "qt>100"
qt>100
  • -V: Display a fun version message.

See the next page for a list of common Pacman idioms.

Aura Commands

Aura also provides a number of new Commands:

  • -A: Search and install packages from the AUR.
> sudo aura -A zoom
  • -B: Create and restore snapshots of installed packages.
> sudo aura -B
aura >>= Saved package state.
  • -C: Downgrade installed packages.
> sudo aura -C aura-bin
aura >>= What version of aura-bin do you want?
1. /var/cache/pacman/pkg/aura-bin-2.3.0-1-x86_64.pkg.tar.xz
2. /var/cache/pacman/pkg/aura-bin-3.0.0-1-x86_64.pkg.tar.xz
3. /var/cache/pacman/pkg/aura-bin-3.0.0-2-x86_64.pkg.tar.xz
4. /var/cache/pacman/pkg/aura-bin-3.1.1-1-x86_64.pkg.tar.xz
>>
  • -L: Search and inspect the Pacman log.
> aura -Li firefox
Package        : firefox
First Install  : 2016-05-03 08:46
Upgrades       : 75
Recent Actions :
[2020-04-08T14:26:09-0700] [ALPM] upgraded firefox (74.0-2 -> 75.0-1)
[2020-05-04T09:20:53-0700] [ALPM] upgraded firefox (75.0-1 -> 75.0-2)
[2020-05-18T08:39:43-0700] [ALPM] upgraded firefox (75.0-2 -> 76.0.1-1)
  • -O: Handle "orphans" - dependencies whose parent package is no longer installed.
> aura -O
ruby-bundler
vim
  • -P: Perform security analysis of PKGBUILDs.
> aura -Ap myget | aura -P

    sudo pacman -S aurvote

aura >>= sudo indicates that someone may be trying to gain root access to your machine.
aura >>= Potential PKGBUILD vulnerabilities detected.

Aura-as-Pacman

aura can be used in place of pacman in all situations. At the very least, this is two fewer letters to type!

Below are some common pacman idioms for managing your system. The list is a handy reference but not exhaustive. For everything that pacman is capable of, see man pacman.

To find out how to use Aura to interact with the AUR, continue to the next page.

Package Installation and Updates

Install an official package

sudo aura -S firefox

💡 Note: Like with pacman, sudo must be used for all "admin" actions.

Update all official packages

The classic command.

sudo aura -Syu

Install a package built with makepkg

sudo aura -U foobar-1.2.3-1-x86_64.pkg.tar.xz

Removing Packages

The package and all unneeded dependencies

From the manpage of pacman:

This operation is recursive and analogous to a backwards --sync operation, and it helps keep a clean system without orphans.

sudo aura -Rsu firefox

The package and everything that depends on it

Use this with care. See man pacman for more details.

sudo aura -Rcu firefox

Querying your System

Searching an exact package

aura -Qi firefox

Searching a local package by description

> aura -Qs browser
local/chromium 83.0.4103.61-1
    A web browser built for speed, simplicity, and security
local/firefox 76.0.1-1
    Standalone web browser from mozilla.org
local/qt5-webengine 5.14.2-3 (qt qt5)
    Provides support for web applications using the Chromium browser project

Producing a list of installed packages

> aura -Q
a52dec 0.7.4-11
aalib 1.4rc5-14
accounts-qml-module 0.7-2
acetoneiso2 2.3-10
... etc ...

Discovering what package owns a certain file

> aura -Qo /usr/bin/firefox
/usr/bin/firefox is owned by firefox 76.0.1-1

Discovering which files are brought in by a package

> aura -Ql firefox
firefox /usr/
firefox /usr/bin/
firefox /usr/bin/firefox
firefox /usr/lib/
firefox /usr/lib/firefox/
firefox /usr/lib/firefox/Throbber-small.gif
firefox /usr/lib/firefox/application.ini
... etc ...

You can use grep to filter what you're looking for:

> aura -Ql firefox | grep bin
firefox /usr/bin/
firefox /usr/bin/firefox
firefox /usr/lib/firefox/firefox-bin

Clearing your Package Cache

Pacman and Aura store built packages in /var/cache/pacman/pkg/. This directory can grow quite large, but the following commands can help selectively clear it.

💡 Tip: The Aura command -Cc offers additional control over clearing the cache.

Removing the tarballs of uninstalled packages

sudo aura -Sc

Removing all tarballs

sudo aura -Scc

Installing AUR Packages

Let's walk through the full process of installing an AUR package. This will show us how to discover packages, install them, and upgrade them.

💡 Tip: Just want to update all your AUR packages? Aura's author uses sudo aura -Auax.

💡 Tip: For the full list of all options with detailed descriptions, see man aura.

Installing a Package

Searching for a Package

Let's say we want to install a package that can render .md files for us. First, we search the AUR for candidates:

> aura -As readme
aur/gtk3-mushrooms 3.24.11-1 (28 | 1.29)
    GTK3 patched for classic desktops like XFCE or MATE. Please see README.
aur/python-grip-git 4.5.2-1 (15 | 0.00)
    Preview GitHub Markdown files like Readme locally before committing them.
aur/python-grip 4.5.2-1 (13 | 0.14)
    Preview GitHub Markdown files like Readme locally before committing them
aur/gtk3-classic 3.24.14-1 (7 | 1.63)
    GTK3 patched for classic desktops like XFCE or MATE. Please see README.
aur/ruby-github-markup 3.0.4-1 (4 | 0.00)
    The code GitHub uses to render README.markup
... etc ...

By default, results are ordered by their vote count. If -As filled the screen and we only wish to see a few results, we can filter with --head:

> aura -As readme --head 3
aur/gtk3-mushrooms 3.24.11-1 (28 | 1.28)
    GTK3 patched for classic desktops like XFCE or MATE. Please see README.
aur/python-grip-git 4.5.2-1 (15 | 0.00)
    Preview GitHub Markdown files like Readme locally before committing them.
aur/python-grip 4.5.2-1 (13 | 0.14)
    Preview GitHub Markdown files like Readme locally before committing them

--abc can be used to sort alphabetically instead.

Scrutinizing a Package

Alright, python-grip looks good. Let's take a closer look...

> aura -Ai python-grip
Repository  : aur
Name        : python-grip
Version     : 4.5.2-1
AUR Status  : Up to Date
Maintainer  : craftyguy
Project URL : https://github.com/joeyespo/grip
AUR URL     : https://aur.archlinux.org/packages/python-grip
License     : MIT
Depends On  : python python-docopt python-flask python-markdown python-path-and-address python-pygments python-requests
Build Deps  : python-setuptools
Votes       : 13
Popularity  : 0.14
Description : Preview GitHub Markdown files like Readme locally before committing them

Does the PKGBUILD look alright?

> aura -Ap python-grip
# Maintainer: Clayton Craft <clayton at craftyguy dot net>

pkgname=python-grip
pkgver=4.5.2
pkgrel=1
pkgdesc="Preview GitHub Markdown files like Readme locally before committing them"
arch=('any')
license=('MIT')
url="https://github.com/joeyespo/grip"
depends=('python' 'python-docopt' 'python-flask' 'python-markdown'
         'python-path-and-address' 'python-pygments' 'python-requests')
makedepends=('python-setuptools')
source=("$pkgname-$pkgver.tar.gz::https://github.com/joeyespo/grip/archive/v$pkgver.tar.gz")
sha256sums=('bdf8949f33470e9ef9e3f09596b72cda968116ff32f0280baabe837c2ad1b29b')

package() {
  cd grip-$pkgver
  python setup.py install --root="$pkgdir" --optimize=1
  install -Dm644 LICENSE "$pkgdir"/usr/share/licenses/$pkgname/LICENSE
}

Looks good, but let's make sure we didn't miss anything by using Aura's PKGBUILD security scanning:

> aura -Ap python-grip | aura -P

Okay, no output and no error code, so we should be safe to proceed. Normally you don't need to do -P yourself - the same check happens automatically before building packages with -A. See PKGBUILD Security Analysis for more information.

A Normal Install

> sudo aura -A python-grip
aura >>= Determining dependencies...

aura >>= Repository dependencies:
python-docopt
python-flask
aura >>= AUR dependencies:
python-path-and-address
aura >>= AUR Packages:
python-grip
aura >>= Continue? [Y/n]
resolving dependencies...
looking for conflicting packages...

Package (4)                    New Version  Net Change

community/python-itsdangerous  1.1.0-4        0.11 MiB
community/python-werkzeug      1.0.1-2        2.13 MiB
community/python-docopt        0.6.2-7        0.08 MiB
community/python-flask         1.1.2-2        0.80 MiB

Total Installed Size:  3.11 MiB

:: Proceed with installation? [Y/n]
... pacman output ...

aura >>= Building python-path-and-address...
loading packages...
resolving dependencies...
looking for conflicting packages...

Package (1)              New Version  Net Change

python-path-and-address  2.0.1-1        0.01 MiB

Total Installed Size:  0.01 MiB

:: Proceed with installation? [Y/n]
... pacman output ...

aura >>= Building python-grip...
loading packages...
resolving dependencies...
looking for conflicting packages...

Package (1)  New Version  Net Change

python-grip  4.5.2-1        0.34 MiB

Total Installed Size:  0.34 MiB

:: Proceed with installation? [Y/n]
... pacman output ...

A few things to note:

  • python-grip has both official and AUR dependencies. These have to be built and installed in a specific order for python-grip to even build.
  • Aura calls makepkg under the hood. By default, the output of makepkg is hidden.
  • If two or more packages don't depend on each other, they'll be built one after another and installed at the same time. This avoids needless user prompting.

A Verbose Install

But what if we do want to see the output from makepkg? For long builds (e.g. aseprite), it can be reassuring to see the ongoing build output.

Let's add -x to -A:

> sudo aura -Ax python-grip
aura >>= Determining dependencies...

aura >>= Repository dependencies:
python-docopt
python-flask
aura >>= AUR dependencies:
python-path-and-address
aura >>= AUR Packages:
python-grip
aura >>= Continue? [Y/n]

... pacman output ...

aura >>= Building python-path-and-address...
==> Making package: python-path-and-address 2.0.1-1 (Fri 12 Jun 2020 09:39:46 AM PDT)
==> Checking runtime dependencies...
==> Checking buildtime dependencies...
==> Retrieving sources...
  -> Downloading v2.0.1.tar.gz...
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   133  100   133    0     0     70      0  0:00:01  0:00:01 --:--:--    70
100  5130    0  5130    0     0   2197      0 --:--:--  0:00:02 --:--:--  2197
==> Validating source files with md5sums...
    v2.0.1.tar.gz ... Passed
==> Extracting sources...
  -> Extracting v2.0.1.tar.gz with bsdtar
==> Entering fakeroot environment...
==> Starting package()...

... makepkg output ...

==> Finished making: python-path-and-address 2.0.1-1 (Fri 12 Jun 2020 09:39:49 AM PDT)

... etc ...

Wonderful.

Automatically Removing makedepends

There's a difference between the dependencies that a package needs to build and the dependencies it needs to run. We call the former makedepends. Once a package is installed, we no longer need its makedepends sitting around on our machine. Adding -a to -A will automatically clear them out:

> sudo aura -Axa python-grip
aura >>= Determining dependencies...

... the usual ...

Package (1)  Old Version  New Version  Net Change

python-grip  4.5.2-1      4.5.2-1        0.00 MiB

Total Installed Size:  0.34 MiB
Net Upgrade Size:      0.00 MiB

:: Proceed with installation? [Y/n]

... pacman output ...

Ah, there were none in this case. Since python-grip is a Python package, it never really has makedepends. That's okay - it's a good habit to use -a, especially when updating all your AUR packages at once (see below).

Altering the PKGBUILD Before Building

Sometimes you want to change something specific about how a package is built. Without an AUR helper, you'd clone the package from the AUR, edit the PKGBUILD, and then run makepkg, handling dependencies yourself.

Aura's --hotedit flag will let you edit a PKGBUILD on-the-fly. In the example below, I added echo "I CHANGED THE PKGBUILD" to the build commands:

> sudo aura -Axa python-grip --hotedit
aura >>= Determining dependencies...

... the usual ...

aura >>= Building python-grip...
aura >>= Would you like to edit the PKGBUILD of python-grip? [Y/n]

... Your EDITOR opens, and your changes are saved to the real PKGBUILD file ...

==> Making package: python-grip 4.5.2-1 (Fri 12 Jun 2020 09:52:26 AM PDT)
==> Checking runtime dependencies...
==> Checking buildtime dependencies...
==> Retrieving sources...
  -> Downloading python-grip-4.5.2.tar.gz...
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   121  100   121    0     0    288      0 --:--:-- --:--:-- --:--:--   289
100  174k    0  174k    0     0   165k      0 --:--:--  0:00:01 --:--:--  938k
==> Validating source files with sha256sums...
    python-grip-4.5.2.tar.gz ... Passed
==> Extracting sources...
  -> Extracting python-grip-4.5.2.tar.gz with bsdtar
==> Entering fakeroot environment...
==> Starting package()...
I CHANGED THE PKGBUILD

... normal makepkg output, etc ...

Some things to note:

  • If .install or .patch files are present, --hotedit will also prompt you to edit those.
  • You can change the dependency lists, but this will only affect makepkg's dependency resolution, not Aura's. If you want Aura to skip dependency checks completely because you know you're right (and you know makepkg will succeed after you hotedit), use the --skipdepcheck flag. See issue #605 for more information.
  • If you want customizations to a PKGBUILD to apply to all future builds of a package, it's recommended that you maintain a separate PKGBUILD and call makepkg yourself.

Updating your AUR Packages

sudo aura -Ayu works, but sudo aura -Auax is a more common way to update your installed AUR packages.

  • -A: Only consider AUR packages.
  • -u: Update all packages that can be.
  • -a: Uninstall unneeded makedepends afterward.
  • -x: Display makepkg output as we go.
> sudo aura -Auax
aura >>= Fetching package information...
aura >>= Comparing package versions...
aura >>= AUR Packages to upgrade:
aseprite :: 1.2.16.2-3 -> 1.2.19.2-1

aura >>= Saved package state.
aura >>= Determining dependencies...

aura >>= Repository dependencies:
ninja
aura >>= AUR Packages:
aseprite
aura >>= Continue? [Y/n]

Note that -u automatically invoked a saving of the current package state. If you update your system and there is a serious problem, you can roll back with -Br and return to the state that was just saved. See Package Set Snapshots for more detail.

Displaying PKGBUILD Changes

Hey wait a minute, aren't we supposed to check PKGBUILDs before building packages? -k will show us any changes that were made to a PKGBUILD compared to the version we have installed:

> sudo aura -Auaxk
aura >>= Fetching package information...
aura >>= Comparing package versions...
aura >>= AUR Packages to upgrade:
aseprite :: 1.2.16.2-3 -> 1.2.19.2-1

aura >>= Saved package state.
aura >>= aseprite PKGBUILD changes:
--- /var/cache/aura/pkgbuilds/aseprite.pb	2020-02-26 14:11:52.427913916 -0800
+++ /tmp/new.pb	2020-06-12 10:19:55.564270161 -0700
@@ -7,50 +7,57 @@
 # Contributor: Kamil Biduś <kamil.bidus@gmail.com>

 pkgname=aseprite
-pkgver=1.2.16.2
-pkgrel=3
+pkgver=1.2.19.2
+pkgrel=1
 pkgdesc='Create animated sprites and pixel art'
-arch=('x86_64' 'i686')
+arch=('x86_64')
 url="http://www.aseprite.org/"
 license=('custom')
-depends=('cmark' 'pixman' 'curl' 'giflib' 'zlib' 'libpng' 'libjpeg-turbo' 'tinyxml' 'freetype2'
-         'harfbuzz' 'nettle' 'fontconfig' 'libxcursor' 'desktop-file-utils' 'hicolor-icon-theme')
-makedepends=('cmake' 'ninja' 'git' 'python2')
+depends=('cmark' 'curl' 'giflib' 'zlib' 'libpng' 'tinyxml' 'freetype2' 'fontconfig' 'libxcursor'
+         'hicolor-icon-theme')
+makedepends=('cmake' 'ninja' 'git' 'python2' 'freeglut' 'xorgproto' 'libxi' 'harfbuzz-icu'
+             'nettle')

... etc ...

aura >>= Determining dependencies...

aura >>= Repository dependencies:
ninja
aura >>= AUR Packages:
aseprite
aura >>= Continue? [Y/n]

Including *-git Packages

The AUR has many packages postfixed with -git, -svn, etc. These typically pull straight from the master branch of some code respository, and so the idea of comparing version numbers to detect updates doesn't work as well.

--devel will consider all such packages for updates:

> sudo aura -Auax --devel
aura >>= Fetching package information...
aura >>= Comparing package versions...
aura >>= AUR Packages to upgrade:
aseprite    :: 1.2.16.2-3 -> 1.2.19.2-1
libumem-git

aura >>= Saved package state.
aura >>= Determining dependencies...

aura >>= Repository dependencies:
ninja
aura >>= AUR Packages:
aseprite
libumem-git
aura >>= Continue? [Y/n]

Notice that no a -> b version number update was shown for the -git package.

💡 Note: Usually packages are built in semi-randomly named directories within /tmp, which is cleared upon every reboot of the machine. (Pass -c/--clean to -A to be proactive about clearing these directories.)

"VCS" packages on the other hand are stored elsewhere and given fixed names, so that updates invoke a git pull instead of a full git clone (which may be expensive!).

See the next page for more information.

Forcing a Rebuild

By default, Aura won't rebuild a package if the most recent version is already installed (or even just available in your package cache). But sometimes you do want to force a rebuild. For instance, some -git packages have no concept of a version number. Even with --devel, an update will never be detected. In these cases, --force will cause the package to be completely rebuilt.

Blindly Accepting all Prompts

Tired of pressing the Enter key? Or maybe you've automated aura into a script. In these cases, you may want to accept all prompts automatically. pacman exposes the --noconfirm flag for this, which also affects Aura.

💡 Note: If a PKGBUILD vulnerability was detected, Aura will exit and not proceed with building, even if --noconfirm was given.

See PKGBUILD Security Analysis for more information.

Package Storage Locations

This page explains all important filepaths for Aura. Build paths can be configured in aura.conf or changed dynamically with CLI flags.

Where are packages built?

By default, non-VCS packages are built within /tmp in a semi-randomly named directory. This avoids odd collisions during repeated attempts at building a package. /tmp is cleared automatically upon a restart of the machine, but for users who don't restart often, -c/--clean can be passed to -A to delete these build directories proactively.

--build can be passed to -A with an absolute filepath to build packages in a directory other than /tmp.

VCS packages (i.e. *-git) are built and stored in /var/cache/aura/vcs/ in subdirectories with fixed names. This is so that they can be reused during upgrades; makepkg is smart enough to do git pull instead of a full git clone in these cases.

--vcspath can be passed to -A to build/store such packages elsewhere.

Where are packages stored?

Once built, all packages are sent to the Pacman cache: /var/cache/pacman/pkg/.

This directory can grow quite large, but can be cleaned with -Cc.

What other filepaths are there?

Aura stores historical PKGBUILDs in /var/cache/aura/pkgbuilds/, and saved package set states in /var/cache/aura/states/.

Downgrading Packages

The -C command is used to interact with the Package Cache.

Searching the Cache

-Cs can show us what's available in the cache.

> aura -Cs firefox
/var/cache/pacman/pkg/firefox-75.0-2-x86_64.pkg.tar.zst
/var/cache/pacman/pkg/firefox-76.0.1-1-x86_64.pkg.tar.zst

Downgrading or Installing "Lost" Versions

Let's say the newest version of some package is somehow broken. Let's downgrade:

> sudo aura -C firefox
aura >>= What version of firefox do you want?
1. /var/cache/pacman/pkg/firefox-75.0-2-x86_64.pkg.tar.zst
2. /var/cache/pacman/pkg/firefox-76.0.1-1-x86_64.pkg.tar.zst
>> 1
loading packages...
warning: downgrading package firefox (76.0.1-1 => 75.0-2)
resolving dependencies...
looking for conflicting packages...

Package (1)  Old Version  New Version  Net Change

firefox      76.0.1-1     75.0-2        -2.08 MiB

Total Installed Size:  184.97 MiB
Net Upgrade Size:       -2.08 MiB

:: Proceed with installation? [Y/n]

... pacman output ...

In fact, -C works even if we no longer have that package installed. All that matters is whether you have a copy of the old version in your cache.

Cleaning the Cache

-Cc can help keep our cache small.

> sudo aura -Cc 2
aura >>= The cache contains 2050 packages, consuming 5887 megabytes.
aura >>= 2 of each package file will be kept.
aura >>= The rest will be deleted. Okay? [Y/n]
aura >>= Cleaning package cache...
aura >>= 529 megabytes freed.

Managing Orphan Packages

Orphan packages are those marked as Installed as a dependency for another package, but which are missing the parent package that depended on them. This can occur when a package with many dependencies is installed and then later removed via a single -R (without -su). Or when a package is upgraded, and the new version no longer requires a certain dependency.

In these cases, the dependencies are left behind and becomes orphans, chewing up disk space.

The -O command can help deal with these.

What packages have become orphans?

> aura -O
python-docopt
python-flask
python-path-and-address

Weird! Are they really not needed?

> aura -Qi python-docopt
Name            : python-docopt
Version         : 0.6.2-7
Description     : Pythonic argument parser, that will make you smile
Architecture    : any
URL             : https://github.com/docopt/docopt
Licenses        : MIT
Groups          : None
Provides        : None
Depends On      : python
Optional Deps   : None
Required By     : None
Optional For    : None
Conflicts With  : None
Replaces        : None
Installed Size  : 83.17 KiB
Packager        : Evangelos Foutras <evangelos@foutrelis.com>
Build Date      : Thu Oct 31 09:48:34 2019
Install Date    : Fri Jun 12 09:43:12 2020
Install Reason  : Installed as a dependency for another package
Install Script  : No
Validated By    : Signature

Sure enough, Required By: None.

Uninstalling Orphans

Clearing orphans doesn't just save us space now - it saves the space of all future upgrades we won't have to download anymore.

-Oj will uninstall all such packages. Under the hood, it passes -Rsu to pacman, hence there are more packages to uninstall than first appeared in the -O list above.

> sudo aura -Oj
checking dependencies...

Package (5)              Old Version  Net Change

python-itsdangerous      1.1.0-4       -0.11 MiB
python-werkzeug          1.0.1-2       -2.13 MiB
python-docopt            0.6.2-7       -0.08 MiB
python-flask             1.1.2-2       -0.80 MiB
python-path-and-address  2.0.1-1       -0.01 MiB

Total Removed Size:  3.12 MiB

:: Do you want to remove these packages? [Y/n]

Adopting an Orphan

Changing a package's install reason from "dependency" to "explicitly installed" is possible via pacman alone, but Aura offers a shorthand:

> sudo aura -Oa python-path-and-address
python-path-and-address: install reason has been set to 'explicitly installed'

Saving Package Set Snapshots

Arch Linux (and Linux in general) used to have a reputation of breaking every time packages were upgraded. Around 2010, Aura's author used to run Arch on a Macbook, and such catastrophic breakage did occur every six months or so. But fast-forward to the present day, and such problems are rare. Even so, the idea of "whole system rollback" is spreading, and even since those early Arch-on-Mac days, Aura has had the -B Command for saving and restoring entire package sets.

Saving a Package Set

> sudo aura -B
aura >>= Saved package state.

This saves a file like 2020.06(Jun).14.08.56.46.json to /var/cache/aura/states/. If we take a peek inside, we see:

> cat 2020.06\(Jun\).14.08.56.46.json | aeson-pretty | head
{
    "time": "2020-06-14T08:56:46.437911573-07:00",
    "pinned": false,
    "packages": {
        "rasqal": "1:0.9.33-3",
        "java-environment-common": "3-3",
        "kwallet": "5.70.0-1",
        "python2-livereload": "2.6.1-1",
        "nethogs": "0.8.6-1",
        "coreutils": "8.32-1",

Simple enough - a list of all installed packages with their versions. We'll talk about pinned below.

These files are in JSON format in case other tools wish to read them.

Restoring a Package Set

I performed a big -Syu of about 250 packages, but wish to roll them all back to the saved state I just made above. Let's see that happen:

> sudo aura -Br
 1. /var/cache/aura/states/2018.07(Jul).06.10.03.18.json
 2. /var/cache/aura/states/2020.05(May).04.09.15.57.json
 3. /var/cache/aura/states/2020.05(May).11.11.30.35.json

... many choices ...

49. /var/cache/aura/states/2020.06(Jun).12.10.23.12.json
50. /var/cache/aura/states/2020.06(Jun).14.08.56.46.json
51. /var/cache/aura/states/2020.06(Jun).14.09.03.59.json
>> 51
aura >>= Requested downgrade versions not available for:
lib32-libdrm
libdrm
libretro-nestopia
linux-firmware
portaudio
runc
spandsp
virtualbox
vlc
xine-lib

resolving dependencies...
looking for conflicting packages...

Package (234)                 Old Version             New Version           Net Change

acorn                         1:7.3.1-1               1:7.2.0-1               0.00 MiB
alsa-lib                      1.2.3-1                 1.2.2-1                -0.01 MiB
alsa-topology-conf            1.2.3-1                 1.2.2-2                -0.19 MiB
alsa-ucm-conf                 1.2.3-1                 1.2.2-1                -0.02 MiB
alsa-utils                    1.2.3-1                 1.2.2-1                 0.00 MiB

... etc ...

wine                          5.10-1                  5.9-1                  -1.26 MiB
x265                          3.4-1                   3.3-1                  -0.01 MiB
xkeyboard-config              2.30-1                  2.29-1                  0.09 MiB

Total Installed Size:  3315.10 MiB
Net Upgrade Size:       -38.46 MiB

:: Proceed with installation? [Y/n]

... downgrading ...

It all went smoothly, even rolling back the kernel. Notice that Aura will warn you if it couldn't find certain versions to roll back to.

Clearing out old Saved States

50 saved states is a little much. I probably don't even have most of the packages necessary to roll back to those early states, since I use -Cc often. Let's clear out the old ones:

> sudo aura -Bc 5
aura >>= You currently have 52 saved package states.
aura >>= 1 of these are pinned, and won't be removed.
aura >>= Most recently saved: 2020.06(Jun).14.09.17.09.json
aura >>= 5 package states will be kept. Remove the rest? [Y/n]

And sure enough, only the most recent remain:

> sudo aura -Br
1. /var/cache/aura/states/2018.07(Jul).06.10.03.18.json
2. /var/cache/aura/states/2020.06(Jun).12.10.22.56.json
3. /var/cache/aura/states/2020.06(Jun).12.10.23.12.json
4. /var/cache/aura/states/2020.06(Jun).14.08.56.46.json
5. /var/cache/aura/states/2020.06(Jun).14.09.03.59.json
6. /var/cache/aura/states/2020.06(Jun).14.09.17.09.json
>>

Hey wait, what is that state from 2018 still doing there? Notice:

aura >>= 1 of these are pinned, and won't be removed.

Now we can talk about pinning.

Pinning a Saved State

If we don't want a certain package state to be removed by -Bc no matter what, we can pin it. There is no flag for this, we need to open the .json file of the state we wish to pin, and change its pinned field from false to true.

PKGBUILD Security Analysis

In 2018 July, the Acroread package was compromised. While the offending commit is no longer available, the mailing list mentions the cause: someone had injected a line into Acroread's PKGBUILD that curls down some custom code from the internet and pipes it into a new bash process. Many people discovered that they had been victim to this vulnerability, and it came without warning and left no obvious trace.

The top of the AUR page states:

DISCLAIMER: AUR packages are user produced content. Any use of the provided files is at your own risk.

"Caveat emptor". And it is considered standard practice to always check PKGBUILDs before building a package. That said, people aren't perfect, and can miss details. Should they be punished for that with a system vulnerability? Aura's author doesn't think so.

Since 2018 August (Aura 2.0), Aura has had automatic bash vulnerability detection. After dependency checking, each PKGBUILD is parsed and scanned for malicious bash patterns. If one is detected, you'll see a message like this:

> sudo aura -A myget
aura >>= Determining dependencies...

aura >>= WARNING: The PKGBUILD of myget contains blacklisted bash expressions.

    sudo pacman -S aurvote

aura >>= sudo indicates that someone may be trying to gain root access to your machine.
aura >>= Do you wish to quit the build process? [Y/n]
aura >>= Cancelled further processing to avoid potentially malicious bash code.

Clearly a PKGBUILD should not be calling sudo pacman on its own. This is a clear violation of best practices. To be fair, the author of this PKGBUILD is probably not malicious, but the package must be fixed either way.

Aside from automatic detection, as of 2020 May (Aura 3.0) Aura also has the -P command which can be used to scan any PKGBUILD you give it.

💡 Note: The presence of automatic PKGBUILD scanning is not an excuse to be lazy! Please continue to check PKGBUILDs yourself!

Scanning a PKGBUILD from Stdin

Wondering about the safety of a particular package on the AUR? We don't have to try and build it - we can scan the PKGBUILD in isolation:

> aura -Ap myget | aura -P

    sudo pacman -S aurvote

aura >>= sudo indicates that someone may be trying to gain root access to your machine.
aura >>= Potential PKGBUILD vulnerabilities detected.

Recall that -Ap pulls a PKGBUILD from the AUR and prints it to the terminal.

Scanning a PKGBUILD File

-P is also intended as a tool for AUR package maintainers, to help them insure that they aren't unintentionally doing something dangerous or suspicious. Let's check Aura's own PKGBUILD...

> aura -Pf PKGBUILD
>

No error code! Phew...

Scanning a Directory

You can also indicate a directory that you know contains a file named PKGBUILD:

> aura -Pd aura/
>

Safe again.

Log Interaction

Pacman keeps an extensive log file, but doesn't really offer any way to interact with it. Aura has the -L command to perform some interesting lookups.

View the Log File

To open the entire log file in less:

> aura -L
[2016-05-03 04:13] [PACMAN] Running 'pacman -r /mnt -Sy --cachedir=/mnt/var/cache/pacman/pkg base base-devel'
[2016-05-03 04:13] [PACMAN] synchronizing package lists
[2016-05-03 04:26] [ALPM] transaction started
[2016-05-03 04:26] [ALPM] installed linux-api-headers (4.4.1-1)
[2016-05-03 04:26] [ALPM] installed tzdata (2016d-1)
[2016-05-03 04:26] [ALPM] installed iana-etc (20160314-1)
[2016-05-03 04:26] [ALPM] installed filesystem (2015.09-1)
[2016-05-03 04:26] [ALPM] installed glibc (2.23-1)

... etc ...

A blast from the past! Looks like a set up Arch on this laptop in 2016. And what was the most recent thing pacman did (press G)?

... etc ...

[2020-06-14T09:19:43-0700] [ALPM] running 'update-ca-trust.hook'...
[2020-06-14T09:19:51-0700] [ALPM] running 'update-desktop-database.hook'...
[2020-06-14T09:19:51-0700] [ALPM] running 'update-mime-database.hook'...
[2020-06-14T09:19:57-0700] [ALPM] running 'xorg-mkfontscale.hook'...

Search the Log File

-Ls returns all log lines that match a given string:

> aura -Ls firefox
[2016-05-03 08:45] [PACMAN] Running 'pacman -S firefox'
[2016-05-03 08:46] [ALPM] installed firefox (46.0-2)
[2016-05-07 11:09] [ALPM] upgraded firefox (46.0-2 -> 46.0.1-1)
[2016-06-19 14:30] [ALPM] upgraded firefox (46.0.1-1 -> 47.0-1)
[2016-06-23 15:46] [ALPM] upgraded firefox (47.0-1 -> 47.0-2)
[2016-07-25 07:25] [ALPM] upgraded firefox (47.0-2 -> 47.0.1-1)

... etc ...

Query all Logs for a Package

More interesting than just a raw search is -Li:

> aura -Li firefox
Package        : firefox
First Install  : 2016-05-03 08:46
Upgrades       : 76
Recent Actions :
[2020-04-08T14:26:09-0700] [ALPM] upgraded firefox (74.0-2 -> 75.0-1)
[2020-05-04T09:20:53-0700] [ALPM] upgraded firefox (75.0-1 -> 75.0-2)
[2020-05-18T08:39:43-0700] [ALPM] upgraded firefox (75.0-2 -> 76.0.1-1)
[2020-06-12T11:39:58-0700] [ALPM] downgraded firefox (76.0.1-1 -> 75.0-2)
[2020-06-12T11:41:03-0700] [ALPM] upgraded firefox (75.0-2 -> 77.0.1-1)

Neat! I often use this to check the last time I updated a particular package.

Configuring Aura

For certain settings we use all the time (e.g. language, build paths, etc.), Aura is configurable via /etc/aura.conf. If you installed Aura from the AUR, this file was generated for you automatically. Otherwise, a full template is available here and contains all instructions.

💡 Tip: You can check all configuration options in full detail with man aura.conf.

Appendix

The following pages contain extra notes and knowledge that is not needed for ordinary Aura usage.

Language Localisation Guide

Welcome! こんにちは! Saluton!

If you're reading this then it's likely that you want to help localise Aura into another language. Arch users everywhere can benefit from your contribution, and it's a great opportunity to contribute to Open Source.

What You Need

  1. The Aura source code.

  2. An editor. Whichever one you like.

  3. git. As Aura is hosted on github, cloning, making changes and adding pull requests will be easiest if you have a working git/github setup.

  4. Minimal Haskell knowledge. You'll see just how much below.

  5. A brain (hopefully yours) with a language in it. As for me, no hablo español, Я не могу говорить по-русски, nor do I يتكلم العربية, so that's where you come in.

Localisation

Step One - Tell Haskell About the New Language

The languages we have already available to us are defined in lib/Aura/Types.hs. You'll notice this entry:

data Language = English
              | Japanese
              | Polish
              ...  -- More in between.
              | Indonesia
              | Chinese
                deriving (Eq, Enum, Ord, Show)

As an example, let's say we're adding French translations to Aura. First, let's extend our Language type:

data Language = English
              | Japanese
              | Polish
              ...  -- More in between.
              | Indonesia
              | Chinese
              | French  -- Added a pipe character and the new Language name.
                deriving (Eq, Enum, Ord, Show)

Step Two - Adding your Language's Locale Code

All strings that contain messages for the user are stored in a single source file: lib/Aura/Languages.hs. One function here is called langFromLocale:

langFromLocale :: T.Text -> Language
langFromLocale = T.take 2 >>> \case
    "ja" -> Japanese
    "pl" -> Polish
    ...   -- More in between.
    "id" -> Indonesia
    "zh" -> Chinese
    _    -> English

This helps Aura auto-detect your computer's human language. By default, it picks English. Let's add French:

langFromLocale :: T.Text -> Language
langFromLocale = T.take 2 >>> \case
    "ja" -> Japanese
    "pl" -> Polish
    ...   -- More in between.
    "id" -> Indonesia
    "zh" -> Chinese
    "fr" -> French
    _    -> English

Your entry must go above the _ -> English line.

Don't know your locale code? You can find them all in /usr/share/i18n/locales.

Step Three - Translation

This is the real work. Let's take a look at a simple message. The user is trying to build a package as root... what to tell them?

trueRoot_3 :: Language -> T.Text
trueRoot_3 = \case
  Japanese -> "「root」としてパッケージを作成するのは「makepkg v4.2」で不可能になりました。"
  German   -> "Seit makepkg v4.2 ist es nicht mehr möglich als root zu bauen."
  Spanish  -> "Desde makepkg v4.2 no es posible compilar paquetes como root."
  Chinese  -> "自从 makepkg v4.2 以后,就不能以根用户身份构建软件了。"
  Swedish  -> "I makepkg v4.2 och uppåt är det inte tillåtet att bygga som root."
  _        -> "As of makepkg v4.2, building as root is no longer possible."

We use the naming convention someIssue_n to show what the error involves. _3 in the above means that there are (at least) 3 potential errors involving "true root".

As with langFromLocale, your French entry would go above the _ -> "As of makepkg..." line.

Sometimes you'll get functions with extra variables to put in the message:

buildPackages_1 :: T.Text -> Language -> T.Text
buildPackages_1 (bt -> p) = \case
  Japanese   -> p ++ "を作成中・・・"
  _          -> "Building " ++ p ++ "..."

The arguments p is probably a package name. To double check, just check out the function that calls this message dispatch. A quick search tells us it's in lib/Aura/Build.hs, and the function is called build. Once you know what's going on, go ahead and add the translation:

buildPackages_1 :: String -> Language -> String
buildPackages_1 (bt -> p) = \case
  Japanese   -> p ++ "を作成中・・・"
  French     -> "Construction de " ++ p ++ "…"
  _          -> "Building " ++ p ++ "..."

Obviously the syntax among languages is different, and so where you insert the variables you've been given into the sentence depends on your language.

Reminder: There are two main files to add translations to: lib/Aura/Languages.hs and lib/Aura/Languages/Fields.hs.

Step Four - Command-line Flag

We choose output languages in Aura by using flags on the command line. Japanese, for example, uses the --japanese flag. We'll have to make a flag for the new language you're adding too.

At the bottom of exec/Flags.hs you'll find:

language :: Parser Language
language = foldr1 (<|>) $ map (\(f, v) -> flag' v (long f <> hidden)) langs
  where langs = [ ( "japanese",   Japanese ),   ( "日本語",     Japanese )
                , ( "polish",     Polish ),     ( "polski",    Polish )
                , ( "croatian",   Croatian ),   ( "hrvatski",  Croatian )
                ... -- More in between.
                , ( "norwegian",  Norwegian ),  ( "norsk",     Norwegian )
                , ( "indonesian", Indonesia )
                , ( "chinese",    Chinese ),    ( "中文",       Chinese ) ]

The convention is to add two flags for each language. One is that language's name in English, and the other is its name in its own language (e.g. "croatian" and "hrvatski"). The second element of each pair is the same value you added to the Language type.

Step Five - Pull Request

With the translations complete, you'll need to tell us about it on Github. Once your changes are looked over, we'll release a new version of Aura with your language included as soon as possible. Provided you followed the above instructions, this shouldn't take long. Furthermore, chances are we won't be able to proofread the translation itself, as we probably don't speak your language. You could hide your doomsday take-over plans in the code and no one would know.

Step Six - You've Helped Others who Speak your Language

You've done a great thing by increasing Aura's usability. Your name will be included in both Aura's README and in its -V version message. Thanks a lot for your hard work!

FAQ

Why doesn't package XYZ build?

If you're on the most recent version of Aura and are still having problems, this could be for a few reasons:

  • There is something wrong with the upstream package source files or a dependency.
    • If so, check the comments on the AUR page for that package.
  • There is something strange going on with environment variables.
    • If so, double-check your aura.conf and LOCALE.
  • You've found a real bug in Aura.

How do I debug a problem?

To display extra output during Aura's operation, pass --log-level=debug. If Aura is failing mysteriously somewhere, that output will at least let us know how far it got internally.