Squash merge move_to_single_file_pkgs into main

This commit is contained in:
Matthew Stobbs
2026-04-13 14:50:45 -06:00
parent ff740426c8
commit 8dc427f027
373 changed files with 3883 additions and 9963 deletions

View File

@@ -2,108 +2,140 @@
## Package definition
Package defintions are just `yaml` tasks in the directory
`tasks/pkgs`, which handle how a package is installed.
A "package" is just a yaml task list that defines how to install a piece of software.
It does this through the use of `helpers` that manage;
Most can be installed using the `syspkgs` list, and are simply
appending the package name to said list based on the system.
- dependency installations
- building from source
- linking binaries to a usable `PATH`
- calling external tools when required
- installation via package managers on the system
If a package can be installed via an entry to `syspkgs` for some,
but not all platforms, handling is done to either inform the user
that the package is not available, or to append the package name
to another installation method such as:
## Anatomy of a Package Definition
- `appimages` to install the appimage of a package
- `cargopkgs` to install via the rust cargo package manager
- `cargoversioned` to install version lockec cargo packages
- `caskpkgs` to install a homebrew cask
- `flatpkgs` to install flatpaks
- `gopkgs` to install using the `go install` command
- `npmpkgs` to install packages from npm
- `pipxpkgs` to install packages from Python pip
- `srcpkgs` to build packages from source
- `tappkgs` to install packages from home brew taps
It starts with package metadata, as a comment block above the installation steps.
This should come after the line `# vim: set filetype=yaml.ansible :`, which sets
up the correct linter and language server when using neovim/vim.
Alternative sources of packages can be defined with entries to:
### Metadata
- `fpremotes` to add a flatpak remote
- `brewtaps` to add a homebrew tap
### Adding system level repositories
Many packages exist in their own external repository for the
given system, such as `/etc/yum.repos.d` for RedHat based linux
distros, `/etc/apt/sources.list.d` for Debian based distros and
others. Since you an add the package to `syspkgs` by enabling a
repo, the coresponding task in `tasks/pkgs` should take the
steps needed to enable the repository.
### Packages with multiple instllation methods
Many packages can be installed in different ways, like the
`bitwarden` package. `bitwarden` can be installed as a `syspkg`
on some machines, a `caskpkg` on macOS, an `appimage`, a `flatpak`
or even a `snap`.
For such packages, a default is chosen to install, in the following order
of precedence: `syspkgs`, `flatpkgs`, `snappkgs`, `appimages`.
In that order, `syspkgs` and `caskpkgs` have equal weight, as it applies
to macOS.
## Formatting rules
- Use indentation explicitness. Lists should be indented:
The metadata consists of `key: value` pairs, at minimum requiring:
```yaml
# Good
my_good_list:
- my_list_item
# Bad
my_bad_list:
- my_list_item
# Package: <package name>
# Description: <package description>
# Version: <latest supported version of package. 'latest' is fine>
# Methods: <list of available methods for installation>
# Helpers: <list of helpers used by the package directly>
# Maintainers: <list of maintainers for this package>
```
This list should match package defaults where it makes sense, for example,
the `Version:` should match the default installed version of the package.
- Variables should be in snake case, separating words
- Short names are fine if they are explicit. ie `vers` can be used instead of `version`
- If more then one variable starts with the same words, put it into a dict if it makes sense:
### Default configuration
Default, non-computed configuration must exist in `vars/main.yml`, generally consisting of
the default version, urls, internal dependencies (internal to Ansible package manager) and
list of files installed after a build, without the `install_prefix`.
When adding default configuration, it MUST match the following:
- Surround the configuration in `# {{{ <package> configuration` and `# }}}`
- Where "package" is the name of the package
- Prefix the configuration with the name of the package, using snake case
- Example: `alacritty_version: v0.16.1`
- This keeps the configuration unique per package, and allows for the defaults
to be overridden where needed.
The things that should be in the default configuration, if relevant, are:
- Default version, as `<package>_version`
- Git repository for pulling the source as `<package>_git_repo`
- Archive URL as `<package>_archive_url`
- Internal dependecies as `<package>_pkg_deps: <list of internal dependencies>`
- Files installed when building from source as `<package>_build_files`
- Default compile flags for the build system.
- Example using cargo: `<package>_cargo_build_flags: <list of build flags>`
- Package build dependencies per ansible_os_family. These are only for system
packages that are required for building the package from source.
- Package runtime dependencies as `<package>_run_deps: <list of run dependencies>`
- These should only be system packages, not internal packages
### Configuration acknowledgement
The "Configuration acknowledgement" MUST be at the start of the yaml file,
and cover everything this package does. This is important for gating when
a package should be configured or not.
It looks like this, using the `air` package:
```yaml
# variables that should be a dict
cargo_locked: true
cargo_pkg: alacritty
# better to just be
cargo:
locked: true
pkg: alacritty
```
- Tasks **MUST** follow the convention in this example:
```yaml
- name: Capitalize first letter of name
- name: Start air configuration
when:
- each condition has it's own line
- (brackets around conditions with) or
(to show they are separate)
become: "{{ not use_local }}" # must be able to be used with use_local
become_user: # this should not be needed, but always follows become if it is
loop: "{{ my_loopable_list }}"
loop_control: # **MUST** always use at least loop_var for any loop
loop_var: my_item
ansible.builtin.set_fact: # always use the full module name
...
- "'air' is not in __configured"
block:
- name: Configure air installation method
...
- name: Finalize air configuration
ansible.builtin.set_fact:
__configured: "{{ __configured | combine( { 'air': true } ) }}"
```
- `name`: Every task needs a name, and the first letter must be capitalized
- `when`: If a when clause exists, it follows the name
- Each clause must have it's own line, including and `or` clause, as seen above
- `become`: must follow the when clause if it exists, name otherwise
- Any other `become_` settings follow `become` in alphabetical order
- `loop`: must be defined just before the module invocation
- Every loop needs to rename the `loop_var` to something that makes sense
- `until` is consider the same as `loop` for the purposes of placement
- The last item must be the module invocation, using the fully qualified name
- For example, don't use `set_fact:`, use `ansible.builtin.set_fact:`
This way, if a package is included as part of another packages build, it only happens once.
### Setting and adding package configuration to list
Adding the configuration for a package is done by appending the configuration to the
appropriate list. Each helper has it's own installation block in `tasks/main.yml`.
Depending on the package installation method, the package must be added to the
appropriate list.
#### Different lists, and when to use them
The following is a list of the different lists that are used, and the
order they are run.
##### System packages
pkg_sys: List of system package manager packages to install
- Installed using `ansible.builtin.package`
- Installs the entire gathered list of packages at once, instead of looping over single items.
- The package list is made unique by applying the `unique` filter to the list
##### Archive packages
Archive packages are binaries installed by extracting an archive and linking the files
in place (usually in `<install_prefix>/bin`).
- Archives are kept in a cache after download, unless `clean_cache` is `true`
- Extracted archives are placed in `<install_prefix>/archive/<name>`
- Archive files are linked to the appropriate place under `install_prefix`, as dictated by
the `pkg.links` list, where `pkg` is the top level dict object of the archive
2. pkg_archive: List of packages installed via archive, like `go`
- Loops over list of archives and downloads, extracts and links them before moving
on to the next.
3. Linux only packages. Flatpaks, appimages, and snapcraft packages.
- Flatpaks: use the lists `flatpak_remotes` and `pkg_flatpak`
- `flatpak_remotes` is a list of dicts containing the flatpak remote configurations
- Managed using `community.general.flatpak_remote` ansible module.
- Format is:
```yaml
remote:
name: <remote name>
url: <flatpakrepo url>
method: <optional. Default 'system'>
```
- `pkg_flatpak` is a list of dicts describing how to install a flatpak
- Managed using `community.general.flatpak` ansible module.
- Format is:
```yaml
flatpak:
name: <flatpak name>
remote: <remote to install from>
method: <optional. Default 'system'>
state: <optional. Default 'present'>
```