# `pkg` Simple and fast package manager for the Slackbuilds.org Slackware packages repository.

[![pipeline status](https://gitlab.com/M0M097/pkg/badges/main/pipeline.svg)](https://gitlab.com/M0M097/pkg/-/commits/main) 
[![coverage report](https://gitlab.com/M0M097/pkg/badges/main/coverage.svg)](https://gitlab.com/M0M097/pkg/-/commits/main)
[![Latest Release](https://gitlab.com/M0M097/pkg/-/badges/release.svg)](https://gitlab.com/M0M097/pkg/-/releases)

[[_TOC_]]

## Installation
A SlackBuild file is provided at [slackbuilds.org](https://slackbuilds.org/repository/15.0/system/pkg/)

`make && sudo make install` will compile the program, give it the same name as the directory name of this directory (`pkg` if you simply cloned it from git) and install it to the default location `/usr/local/bin`.
Edit the makefile or pass arguments to `make` (i.e. `make PREFIX=$HOME/.local`) to change the installation location, name of the binary, etc.

## Configuration
In addition to the command line flags all external commands (to update the repository, install packages, etc), (default) file paths, the command line flags themselves and many other settings can be changed by editing `internal/pkg/config.go` and recompiling. See the comments in the file for more information. No knowledge of `go` is required to change these settings.

This README and the man page are partly automatically generated from the help output of the program. Run `make doc` before `make install` to re-generate it in case you modfied the accepted command line flags.

## Dependencies
All dependencies are present in a default Slackware installation. 
A `go` compiler is required to compile the program. Despite the go standard library no other libraries are used.
In the default configuration, `curl` is used for downloading files, `git` for keeping the repository up to date, `installpkg` for installing/upgrading packages and `bash` for running the Slackbuilds. These can be changed in `internal/pkg/config.go`.

To rebuild the man page you need `go-md2man`. If you want to use another markdown to roff converter, pass it to the makefile: `make doc MD2MAN=yourconverter` (must accept an input file name and write the result to stdout).

To check the unit test coverage with `make cover` you do need the `google-go-lang` package from Slackbuilds.org. `make test`, which runs the tests, sets `-vet=off` and hence also works with gccgo shipped with Slackware.

## API
The public Go API for programmatic interaction with a SlackBuilds repository is provided by `gitlab.com/M0M097/pkg/sborepo`.
Command-line helper functions are provided by `gitlab.com/M0M097/pkg/cli`.
The command orchestration lives under `internal/` and is not part of the supported external API.

## Usage
If invoked with no arguments, it will read white-space seperated packages from `/etc/pkg/pkg_list.txt`, resolves their dependencies and installs/upgrades them in the correct order if they are not already installed or are older than the version in the repository.
The user will be prompted to optionally exclude packages from the list if `-y` is not given.
If the package name is in `/etc/pkg/pkg_list.txt` is followed by `key=value` pairs, these will be passed to the Slackbuild as environment variables. For example, `mypackage FOO=bar` will set the environment variable `FOO` to `bar` when building `mypackage`.
Additionally, if the file `/etc/pkg/mypackage.prebuild` exists and is executable, it will be run before building (and after downloading the sources of) `mypackage`.
The first argument passed to the prebuild script is the path to the directory containing the sources/slackbuild of the package.

An initial `pkg_list.txt` can be generated by running `pkg -l` (list installed SBo packages) and then removing packages which you do not use directly but are, i.e., dependencies of other packages.

`pkg` also updates the `/etc/slackpkg/blacklist` so that orphaned packages are automatically removed when `slackpkg clean-system` is run, and packages in `/etc/pkg/pkg_list.txt` and their dependencies are not removed.
To achive this it first copies `/etc/pkg/blacklist` to `/etc/slackpkg/blacklist` and then appends the packages in `/etc/pkg/pkg_list.txt` and their dependencies to the blacklist. So copy (parts of) your original blacklist to `/etc/pkg/blacklist`, if you want to exclude packages not managed by `pkg` from being removed by `slackpkg clean-system`, otherwise backup your original blacklist and create an empty file at `/etc/pkg/blacklist`. Note: if `/etc/pkg/blacklist` is not present, `pkg` will fail with an error message to ensure that `/etc/slackpkg/blacklist` is not overwritten by mistake.

Packages can also be greylisted in `/etc/pkg/greylist` so that they are not installed by `pkg` but are not removed by `slackpkg clean-system` either (since they are still added to `etc/slackpkg/blacklist`.

If positonal arguments are given, they are treated as package names and installed/upgraded in the correct order. The blacklist is not updated in this case. So `pkg mypackage` will install `mypackage` and its dependencies, but `mypackage` will be removed if `slackpkg clean-system` is run. Add `mypackage` to `/etc/pkg/pkg_list.txt` to prevent this.

`pkg` can also be used to view the README of a packages or list their dependencies/dependents.

By default, it clones the SBo repo to `/var/lib/pkg/sbo` syncs the repository before if the `-u` flag is given.

Any invalid flag like `-h` will print the usage and exit.

## Options

`-b` display build scripts for the given packages

`-d` display information for the given packages

`-f` string
    	path to the input file (default "/etc/pkg/pkg_list.txt")

`-g` ignore the greylist

`-i` don't filter out installed packages

`-j` int
    	maximum number of package builds to run in parallel (default 1)

`-l` list installed packages

`-m` skip MD5Sum checks

`-n` don't install dependencies

`-r` string
    	display dependents within the dependency graph

`-s` search for a package

`-t` track the given packages (show all dependencies)

`-u` update the repository

`-v` display the version of pkg

`-y` Skip all prompts

Most flags can be combined, i.e. `pkg -d -n mypackage` will (re)install `mypackage` regardless of whether it is already installed and will not install its dependencies.

## License
Copyright © 2024-2026  Moritz R. Schaefer. License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>. This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law.

## Disclaimer
I wrote this for personal use. While there is a lot of automated testing there are probably not so many users/testers. Use at your own risk.
