Aconfmgr
A configuration manager for Arch Linux
Install / Use
/learn @CyberShadow/AconfmgrREADME
aconfmgr: A configuration manager for Arch Linux<br>


aconfmgr is a package to track, manage, and restore the configuration of an Arch Linux system.
Its goals are:
- Quickly configure a new system, or restore an existing system according to a saved configuration
- Track temporary/undesired changes to the system's configuration
- Identify obsolete packages and maintain a lean system
aconfmgr tracks the list of installed packages (both native and external), as well as changes to configuration files (/etc/).
Since the system configuration is described as shell scripts, it is trivially extensible.

Table of Contents
Usage
Installation
Simply clone (or download+unzip) the GitHub repository. aconfmgr will install dependencies as needed during execution. An AUR package is also available.
First run
Run aconfmgr save to transcribe the system's configuration to the configuration directory. This will create the file 99-unsorted.sh in the configuration directory, as well as other files describing the system configuration. (The configuration directory will usually be ~/.config/aconfmgr, or ./config if running directly from git, or it can be overridden with -c.)
On the first run, aconfmgr will likely include some files which you may not want to include in your system configuration. These can be temporary or auto-generated files which are not directly owned by a package. To prevent aconfmgr from including these files in the configuration, create e.g. 10-ignores.sh in the configuration directory, with the lines e.g. IgnorePath '/path/to/file.ext' or IgnorePath '/path/to/dir/*'. (See ignoring files for details.) Delete everything from the configuration directory except that file and re-run aconfmgr save to regenerate a configuration minding these ignore rules.
Once aconfmgr save finishes, you should review the contents of 99-unsorted.sh, and sort it into one or more new files (e.g.: 10-base.sh, 20-drivers.sh, 30-gui.sh, 50-misc.sh ...). The files should have a .sh extension, and use bash syntax. I suggest adding a comment for each package describing why installing the package was needed, so it is clear when the package is no longer needed and can be removed.
During this process, you may identify packages or system changes which are no longer needed. Do not sort them into your configuration files - instead, delete the file 99-unsorted.sh, and run aconfmgr apply. This will synchronize the system state against your configuration, thus removing the omitted packages. (You will be given a chance to confirm all changes before they are applied.)
Note: you don't need to run aconfmgr via sudo. It will elevate as necessary by invoking sudo itself.
Maintenance
The configuration directory should be versioned using a version control system (e.g. Git). Ideally, the file 99-unsorted.sh should not be versioned - it will only be created when the current configuration does not reflect the current system state, therefore indicating that there are system changes that have not been accounted for.
Periodic maintenance consists of running aconfmgr save; if this results in uncommitted changes to the configuration directory, then there are unaccounted system changes. The changes should be reviewed, sorted, documented, committed and pushed.
Restoring
To restore a system to its earlier state, or to set up a new system, simply make sure the correct configuration is in the configuration directory and run aconfmgr apply. You will be able to preview and confirm any actual system changes.
Modus operandi
The aconfmgr script has two subcommands:
aconfmgr savecalculates the difference between the current system's configuration and the configuration described by the configuration directory, and writes it back to the configuration directory.aconfmgr applyapplies the difference between the configuration described by the configuration directory and the current system's configuration, installing/removing packages and creating/editing configuration files.
The configuration directory contains shell scripts, initially generated by the save subcommand, and then usually edited by the user. Evaluating these scripts will compile a system configuration description in the output directory. The difference between that directory's contents, and the actual current system configuration, dictates the actions ultimately taken by aconfmgr.
aconfmgr save will write the difference to the file 99-unsorted.sh (under the configuration directory) as a series of shell commands which attempt to bring the configuration up to date with the current system. When starting with an empty configuration, this difference will consist of the entire system description. Since the script only appends to that file, it may end up undoing configuration changes done earlier in the scripts (e.g. removing packages from the package list). It is up to the user to refactor the configuration to remove redundancies, document changes, and improve maintainability.
aconfmgr apply will apply the differences to the actual system.
The contracts of both commands are that they are mutually idempotent: after a successful invocation of either, invoking either command immediately after will be a no-op.
Packages
Background: On Arch Linux, every installed package is installed either explicitly, or as a dependency for another package. Packages can also have mandatory (hard) or optional dependencies. You can view this information using pacman -Qi <package> ("Install Reason", "Depends On", "Optional Deps").
aconfmgr only tracks explicitly-installed packages, ignoring their hard dependencies. Therefore:
aconfmgr savewill only save installed packages that are marked as explicitly installed.- Installed packages that are neither explicitly installed, nor are hard dependencies of other installed packages, are considered prunable orphans and will be removed.
- Packages that are only optional dependencies of other packages must be listed explicitly, otherwise they will be pruned.
aconfmgr applyremoves unlisted packages by unpinning them (setting their install reason as "installed as a dependency"), after which it prunes all orphan packages. If the package is still required by another package, it will remain on the system (until it is no longer required); otherwise, it is removed.- Packages that are installed and explicitly listed in the configuration will have their install reason set to "explicitly installed".
Advanced Usage
Configuration syntax
The configuration files use bash syntax. The easiest way to learn the syntax is to run aconfmgr save and examine its output (99-unsorted.sh).
Some simple helper functions are defined in src/helpers.bash (sourced automatically). You are encouraged to examine their implementation - their main goal is not so much to provide an API as simply to make the generated configuration terser and more readable. As such, their use is in no way required, and they can be substituted with their underlying implementations.
The list of provided helper functions:
AddPackage [--foreign] PACKAGE...- Adds a package to the list of packages to be installed.RemovePackage [--foreign] PACKAGE...- Removes an earlier-added package to the list of packages to be installed.IgnorePackage [--foreign] PACKAGE...- Adds a package to the list of packages to be ignored.AddPackageGroup GROUP- Adds all packages currently in the given group to the list of packages to be installed.CopyFile PATH [MODE [OWNER [GROUP]]]- Copies a file from thefilessubdirectory to the output.CopyFileTo SRC-PATH DST-PATH [MODE [OWNER [GROUP]]]- As above, but allows source and output paths to vary.CreateFile [--no-clobber] PATH [MODE [OWNER [GROUP]]]- Creates an empty file, to be included in the output. Prints its absolute path to standard output.GetPackageOriginalFile [--no-clobber] PACKAGE PATH- Extracts the original file from a package's archive for inclusion in the output. Prints its absolute path to standard output.CreateLink PATH TARGET [OWNER [GROUP]]- Creates a symbolic link with the specified target.RemoveFile PATH- Rem
