📦 Package manager for CLI

AFX - Package manager for CLI

AFX is a package manager for command-line tools and shell plugins. afx can allow us to manage almost all things available on GitHub, Gist and so on. Before, we needed to trawl web pages to download each package one by one. It's very annoying every time we set up new machine and also it's difficult to get how many commands/plugins we installed. So afx's motivation is coming from that and to manage them with YAML files (as a code).

Tests Release

Full document is here: AFX

Features

  • Allows to manage various packages types:
    • GitHub / GitHub Release / Gist / HTTP (web) / Local
  • Manages as CLI commands, shell plugins or both
  • Easy to install/update/uninstall
  • Easy to configure with YAML
    • Environment variables for each packages
    • Aliases for each packges
    • Conditional branches
    • Build steps
    • Run snippet code
    • Dependency between packages
    • etc...
  • Works on bash, zsh and fish

Quick Start

Details are here: Getting Started - AFX

1. Install packages

Write YAML file with name as you like in ~/.config/afx/. Let's say you write this code and then put it into github.yaml. After than you can install packages with install command.

+ github:
+ - name: stedolan/jq
+   description: Command-line JSON processor
+   owner: stedolan
+   repo: jq
+   release:
+     name: jq
+     tag: jq-1.5
+   command:
+     link:
+     - from: '*jq*'
+       to: jq
$ afx install

2. Load packages

You can enable installed packages to your current shell with this command:

$ source <(afx init)

Take it easy to run afx init because it just shows what to apply in your shell to Stdout.

If you want to automatically load packages when you start new shell, you need to add above to your shell-rc file.

3. Update packages

All you have to do for updating is just to update version part (release.tag) to next version then run update command.

  github:
  - name: stedolan/jq
    description: Command-line JSON processor
    owner: stedolan
    repo: jq
    release:
      name: jq
-     tag: jq-1.5
+     tag: jq-1.6
    command:
      link:
      - from: '*jq*'
        to: jq
$ afx update

4. Uninstall packages

Uninstalling is also almost same as install. Just to remove unneeded part from YAML file then run uninstall command.

- github:
- - name: stedolan/jq
-   description: Command-line JSON processor
-   owner: stedolan
-   repo: jq
-   release:
-     name: jq
-     tag: jq-1.6
-   command:
-     link:
-     - from: '*jq*'
-       to: jq
$ afx uninstall

Advanced tips

Shell completion

For zsh user, you can enable shell completion for afx:

$ source <(afx completion zsh)

bash and fish users are also available.

Installation

Download the binary from GitHub Release and drop it in your $PATH.

License

MIT

Owner
Masaki ISHIYAMA
Software Engineer, #terraform #kubernetes #microservices #go #bash #zsh #yaml #hcl https://babarot.me
Masaki ISHIYAMA
Comments
  • [Bug Report] afx does not read symlink

    [Bug Report] afx does not read symlink

    If ~/.config/afx does not exist, afx warns. If ~/.config/afx is symlink, afx does not warn, but say that No packages to install.

    $ exa -la ~/.config
    drwxr-xr-x   - hibiki  1 Apr 09:16 .
    drwxr-x---   - hibiki  1 Apr 10:13 ..
    lrwxrwxrwx  32 hibiki  1 Apr 09:16 afx -> /home/hibiki/dotfiles/config/afx
    $ exa -la ~/.config/afx
    lrwxrwxrwx  32 hibiki  1 Apr 09:16 . -> /home/hibiki/dotfiles/config/afx
    drwxr-xr-x   - hibiki 31 Mar 18:50 ..
    .rw-r--r-- 438 hibiki  1 Apr 10:14 afx.yaml
    

    afx.yaml is here:

    main:
      shell: zsh
      filter_command: fzf --ansi --no-preview --height=40% --reverse
    
    github:
    - name: high-moctane/nextword-data
      description: Dataset for nextword.
      owner: high-moctane
      repo: nextword-data
      release:
        name: '*'
        tag: large
      command:
        env:
          NEXTWORD_DATA_PATH: $XDG_CACHE_HOME/nextword/nextword-data-large
        link:
        - from: nextword-data-large
          to: $XDG_CACHE_HOME/nextword/nextword-data-large
    
  • Error occurs when `afx install`

    Error occurs when `afx install`

    WHY

    When executing afx install, panic occurs with the following error message and the installation fails.

    $ afx install
    ? OK to install these packages? zsh-users/zsh-completions, zsh-users/zsh-autosuggestions, zdharma-continuum/fast-syntax-highlighting, ... (5 packages) Yes
    ✔ b4b4r07/enhancd
    panic: assignment to entry in nil maprs/zsh-autosuggestions, zdharma-continuum/fast-syntax-highl...
    
    goroutine 83 [running]:
    github.com/b4b4r07/afx/pkg/state.add(...)
            /home/jshin/go/pkg/mod/github.com/b4b4r07/[email protected]/pkg/state/state.go:122
    github.com/b4b4r07/afx/pkg/state.(*State).Add(0xc00038c140?, {0x7f96d535bf98?, 0xc00013ecf0?})
            /home/jshin/go/pkg/mod/github.com/b4b4r07/[email protected]/pkg/state/state.go:287 +0x1b3
    github.com/b4b4r07/afx/cmd.(*installCmd).run.func2()
            /home/jshin/go/pkg/mod/github.com/b4b4r07/[email protected]/cmd/install.go:120 +0x1c5
    golang.org/x/sync/errgroup.(*Group).Go.func1()
            /home/jshin/go/pkg/mod/golang.org/x/[email protected]/errgroup/errgroup.go:57 +0x67
    created by golang.org/x/sync/errgroup.(*Group).Go
            /home/jshin/go/pkg/mod/golang.org/x/[email protected]/errgroup/errgroup.go:54 +0x8d
    

    Environment

    OS : Ubuntu 20.04.4 Go : 1.18 afx version : v0.1.19 yaml file

    github:
      - name: zsh-users/zsh-completions
        owner: zsh-users
        repo: zsh-completions
        plugin:
          sources:
            - zsh-completions.plugin.zsh
      - name: zsh-users/zsh-autosuggestions
        owner: zsh-users
        repo: zsh-autosuggestions
        plugin:
          sources:
            - zsh-completions.plugin.zsh
      - name: zdharma-continuum/fast-syntax-highlighting
        owner: zdharma-continuum
        repo: fast-syntax-highlighting
        plugin:
          sources:
            - fast-syntax-highlighting.plugin.zsh
      - name: b4b4r07/enhancd
        owner: b4b4r07
        repo: enhancd
        plugin:
          sources:
            - init.sh
          env:
            ENHANCD_DISABLE_HOME: 1
      - name: tmux-plugins/tpm
        owner: tmux-plugins
        repo: tpm
        command:
          link:
          - from: .
            to: $HOME/.tmux/plugins/tpm
    
  • Initialize error

    Initialize error

    WHAT

    If I take my currently functioning ~/.config/afx/* under the new environment, put the latest release of the afx binary in the path, and run afx install, I get an error that ~/.afx/state.json does not exist.

  • Support gz case (decompress)

    Support gz case (decompress)

    WHAT

    Support an archive file having .gz file extension.

    WHY

    #45 (In this issue, having format field is suggested but it's fixed by supporting it in a fundamental way in this PR)

  • self-update failed

    self-update failed

    WHAT

    After I run afx self-update, an error zsh: exec format error: afx arised. The version before the update was 1.21. I manually reinserted afx and it fixed, so it seems that the detection of OS or architecture is failing during self-update. I use Ubuntu20.04 on WSL2 and afx_linux_x86_64.tar.gz.

  • The tag and the file name do not mesh release on github

    The tag and the file name do not mesh release on github

    WHAT

    Sometimes, as in this lazygit, the tag is v0.34 but the filename uses 0.34 instead of v0.34.

    I can't use .Release.Tag in assets, what should I do?

  • Fix `http.Installed()` behavior

    Fix `http.Installed()` behavior

    WHAT

    Run URL templating just after parsing YAML file and reuse it in all places in http package to get valid URL even if template variables are used in URL field

    WHY

    http package allows to use template variables in URL field but GetHome() is also referring c.URL but it's not templated so Installed() is failed

  • Fix Installed() method behavior on plugin install

    Fix Installed() method behavior on plugin install

    WHAT

    Fix Installed() logic on plugin installation

    WHY

    plugin.Installed() behavior was still kept as old implementations was. So changed to use GetSources (it's considering glob) and add tilde consideration

    ref: https://github.com/b4b4r07/afx/issues/32

  • It is supposed to be installed, but it is not.

    It is supposed to be installed, but it is not.

    WHAT

    It is indeed installed and the commands are usable, but the result of afx init looks like this.

    ## package "junegunn/fzf" is not installed
    ## package "junegunn/fzf" is not installed
    

    My github.yaml

    github:
      - name: junegunn/fzf
        description: A command-line fuzzy finder
        owner: junegunn
        repo: fzf
        command:
          build:
            steps:
              - ./install --all
          link:
            - from: 'bin/fzf'
            - from: 'bin/fzf-tmux'
        plugin:
          sources:
            - ~/.fzf.zsh
          env:
            FZF_DEFAULT_COMMAND: fd --type f
            FZF_DEFAULT_OPTS: --height 50% --reverse
            FZF_CTRL_T_COMMAND: rg --files --hedden --follow --glob "!.git/*"
            FZF_CTRL_T_OPTS: --preview "bat --color=always --style=header,grid --line-range :100 {}"
            FZF_ALT_C_COMMAND: fd --type d
    

    WHY

    If it's a bug, that's the report. If there is something wrong with the settings, please let me know.

  • Update state logic

    Update state logic

    WHAT

    • Use state.ID instead of state.Name
    • Add state rm command
    • Add annotation feature related to bump up version

    WHY

    Currently in state file, each state name is same as pkg name. But if using pkg.name as state.name, it may be problem:

    • changing pkg.name in config file by users

    this operation will be regarded as adding new package and removing that package.

    so we need fixed string not depending on pkg.name

  • Add feature to ask if it's ok to run command

    Add feature to ask if it's ok to run command

    WHAT

    Add a feature to ask it's ok to install/uninstall/update command.

    $ afx install
    ? OK to iinstall these packages? b4b4r07/new-pkg-1, b4b4r07/new-pkg-2 (y/N)
    

    WHY

    Currently it's difficult to know what packages will be installed etc before doing actual operation.

  • [Bug Report] Update error

    [Bug Report] Update error

    WHAT

    When updating a package that is already installed, there is an error that appears to be a problem with the timing of removing the past. When this happens, it is inconvenient because it requires re-entry of GITHUB_TOKEN.

    ❯ afx update
    ? OK to update these packages? cli/cli Yes
    ✖ cli/cli
    [ERROR]: 1 error occurred:
            * 1 error occurred:
                    * cli/cli: failed to get command.link: cli/cli: 2 files matched: []string{"/home/uga/.afx/github.com/cli/cli/gh_2.14.6_linux_amd64/bin/gh", "/home/uga/.afx/github.com/cli/cli/gh_2.14.4_linux_amd64/bin/gh"}
    

    Here is an excerpt from my release.yaml.

    - github:
      - name: cli/cli
        description: Github's official command line tool
        owner: cli
        repo: cli
        release:
          name: gh
          tag: v2.14.6
          asset:
            filename: '{{ .Release.Name }}_{{ replace .Release.Tag "v" "" }}_{{ .OS }}_{{ .Arch }}.tar.gz'
        command:
          link:
            - from: '**/gh'
    

    WHY

    Bug report.

  • [Bug Report] Symlink is not recognized again

    [Bug Report] Symlink is not recognized again

    WHAT

    (Write what you need)

    afx does not read symlink again.

    The cause of the bug exists in between v0.1.21 and v0.1.22. (see https://github.com/b4b4r07/afx/compare/v0.1.21...v0.1.22)

    My current afx.yaml is here.

    Directory Structure

    $ exa -al ~/.config
    lrwxrwxrwx  32 hibiki  7 Jun 14:09 afx -> /home/hibiki/dotfiles/config/afx
    
    $ exa -al ~/.config/afx
    .rw-r--r-- 1.8k hibiki 12 Jun 11:31 afx.yaml
    

    Debug Log

    • v0.1.21
    $ AFX_LOG_LEVEL=debug afx install
    2022/06/12 12:01:43 [INFO] afx version: 0.1.21
    2022/06/12 12:01:43 [INFO] Go runtime version: go1.16.1
    2022/06/12 12:01:43 [INFO] Build tag/SHA: v0.1.21/054f74c
    2022/06/12 12:01:43 [INFO] CLI args: []string{"/home/hibiki/.local/share/aquaproj-aqua/pkgs/github_release/github.com/b4b4r07/afx/v0.1.21/afx_linux_arm64.tar.gz/afx", "install"}
    2022/06/12 12:01:43 [DEBUG] (goroutine): checking new updates...
    2022/06/12 12:01:43 [INFO] Reading config /home/hibiki/dotfiles/config/afx/afx.yaml...
    [ERROR]: failed to initialize afx: /home/hibiki/dotfiles/config/afx/afx.yaml: failed to read config: [23:9] unknown field "directory"
      20 |       - koron/cmigemo
      21 |     command:
      22 |       build:
    > 23 |         directory: nkf-2.1.5
                   ^
      24 |         steps:
      25 |           - make
      26 |           - make install prefix=~/.local
      27 |
    
    • v0.1.22
    $ AFX_LOG_LEVEL=debug afx install
    2022/06/12 12:02:53 [INFO] afx version: 0.1.22
    2022/06/12 12:02:53 [INFO] Go runtime version: go1.16.1
    2022/06/12 12:02:53 [INFO] Build tag/SHA: v0.1.22/4b34e4c
    2022/06/12 12:02:53 [INFO] CLI args: []string{"/home/hibiki/.local/share/aquaproj-aqua/pkgs/github_release/github.com/b4b4r07/afx/v0.1.22/afx_linux_arm64.tar.gz/afx", "install"}
    2022/06/12 12:02:53 [WARN] /home/hibiki/.config/afx: found but cannot be loaded. yaml is only allowed
    2022/06/12 12:02:53 [DEBUG] (goroutine): checking new updates...
    2022/06/12 12:02:53 [DEBUG] mkdir /home/hibiki/.afx
    2022/06/12 12:02:53 [DEBUG] mkdir /home/hibiki/bin
    2022/06/12 12:02:53 [INFO] state additions: (0) []string(nil)
    2022/06/12 12:02:53 [INFO] state deletions: (0) []string(nil)
    2022/06/12 12:02:53 [INFO] state changes: (0) []string(nil)
    2022/06/12 12:02:53 [INFO] state unchanges: (0) []string{...skip...}
    No packages to install
    2022/06/12 12:02:53 [DEBUG] checking updates on afx repo...
    2022/06/12 12:02:53 [INFO] root command execution finished
    

    WHY

    (Write the background of this issue)

  • if `~/.config/afx` is a relative link, cannot execute the `afx` command

    if `~/.config/afx` is a relative link, cannot execute the `afx` command

    WHAT

    if ~/.config/afx is a relative link, cannot execute the afx command

    m ~/.config
    ❯ ls -la
    total 20
    drwxr-xr-x  5 m m 4096 May  3 20:29 .
    drwxr-xr-x 22 m m 4096 May  3 20:29 ..
    lrwxrwxrwx  1 m m   38 May  3 20:29 afx -> /home/m/projs/dotfiles/afx/.config/afx
    
    
    m ~/.config
    ❯ afx
    Package manager for CLI
    ...
    ...
    Use "afx [command] --help" for more information about a command.
    

    but, if ~/.config/afx is a relative link

    ❯ ls ~/.config/ -l
    total 12
    lrwxrwxrwx 1 m m   33 May  3 20:30 afx -> ../projs/dotfiles/afx/.config/afx
    
    m ~/projs/dotfiles master ≡*+9 ~2 -1
    ❯ afx
    [ERROR]: failed to initialize afx: /home/m/.config/afx: failed to walk dir: stat ../projs/dotfiles/afx/.config/afx: no such file or directory
    

    WHY

The smart virtual machines manager. A modern CLI for Vagrant Boxes.
The smart virtual machines manager.  A modern CLI for Vagrant Boxes.

The smart virtual machines manager Table of Contents: What is Vermin Install Vermin Usage Contributors TODO What is Vermin Vermin is a smart, simple a

Dec 22, 2022
A package manager written in Go which uses the LFS Symlink method.

pacsym A package manager powered by symlinks. How to use The package manager assumes that all software installed is installed with /usr/pkg/<packagena

Dec 11, 2021
A Golang package for simplifying storing configuration in the OS-provided secret manager.

go-keyconfig A Golang package for simplifying storing configuration in the OS-provided secret manager. Operating System Support OS Secret Manager MacO

Jul 22, 2022
The missing package manager for golang binaries (its homebrew for "go install")

Bingo: The missing package manager for golang binaries (its homebrew for "go install") Do you love the simplicity of being able to download & compile

Oct 31, 2022
Io's package manager
Io's package manager

Amirani Io's package manager Contributors ✨ Thanks goes to these wonderful people (emoji key): an aspirin ?? ?? ?? ?? This project follows the all-con

Feb 20, 2022
Alertmanager-cli is a cli writtin in golang to silence alerts in AlertManager

Alertmanager-cli is a cli writtin in golang to silence alerts in AlertManager

Aug 27, 2022
Go Version Manager

gvm By Josh Bussdieker (jbuss, jaja, jbussdieker) while working at Moovweb Currently lovingly maintained by Benjamin Knigge Pull requests and other an

Jan 2, 2023
A simple and powerful SSH keys manager
A simple and powerful SSH keys manager

SKM is a simple and powerful SSH Keys Manager. It helps you to manage your multiple SSH keys easily! Features Create, List, Delete your SSH key(s) Man

Dec 17, 2022
Go version manager. Super simple tool to install and manage Go versions. Install go without root. Gobrew doesn't require shell rehash.

gobrew Go version manager Install or update With curl $ curl -sLk https://git.io/gobrew | sh - or with go $ go get -u github.com/kevincobain2000/gobre

Jan 5, 2023
Kubernetes Lazy User Manager

klum - Kubernetes Lazy User Manager klum does the following basic tasks: Create/Delete/Modify users Easily manage roles associated with users Issues k

Dec 6, 2022
network-node-manager is a kubernetes controller that controls the network configuration of a node to resolve network issues of kubernetes.
network-node-manager is a kubernetes controller that controls the network configuration of a node to resolve network issues of kubernetes.

Network Node Manager network-node-manager is a kubernetes controller that controls the network configuration of a node to resolve network issues of ku

Dec 18, 2022
Grafana Dashboard Manager

Grafana dash-n-grab Grafana Dash-n-Grab (GDG) -- Dashboard/DataSource Manager. The purpose of this project is to provide an easy to use CLI to interac

Dec 31, 2022
operator to install cluster manager and klusterlet.

registration-operator Minimum cluster registration and work Community, discussion, contribution, and support Check the CONTRIBUTING Doc for how to con

Dec 14, 2022
The Scylla Manager.

Scylla Manager Welcome to Scylla Manager repository! Scylla Manager user docs can be found here. Scylla Manager consists of tree components: a server

Jan 4, 2023
This manager helps handle the life cycle of your eBPF programs

eBPF Manager This repository implements a manager on top of Cilium's eBPF library. This declarative manager simplifies attaching and detaching eBPF pr

Dec 1, 2022
GO ABI for AWS Secrets-Manager

secrets-manager-cli GO ABI for AWS Secrets-Manager SDK Setup AWS Documentation Download (Source) go get github.com/aws/aws-sdk-go-v2/aws go get github

Nov 16, 2021
Composer is a simple process manager for dev environments.

Composer Composer is a simple service manager for dev environments. How to build/install it? To build composer under ./bin, run: make build To build

May 12, 2022
This repo contains example on how to consume secrets from Google Secret Manager from GKE

GKE Secret Manager. Environment setup This repo contains examples of how to consume secrets from Google Secret Manager (GSM) from Google Kubernetes En

Dec 5, 2022
Machine controller manager provider local

Out of tree (controller-based) implementation for local as a new provider. The local out-of-tree provider implements the interface defined at MCM OOT driver.

Feb 20, 2022