2 releases

Uses new Rust 2024

new 0.2.3 Apr 12, 2025
0.2.2 Apr 12, 2025

#2 in #updater

23 downloads per month

MIT license

35KB
522 lines

uni-updater

Helper program that updates everything on your system.

Setup

The program reads $XDG_CONFIG_HOME/uni-updater.yml or $HOME/.config/uni-updater.yml by default on Linux. You can also specify a config path with --config flags.

Installation

Using cargo

cargo install --git https://codeberg.org/TTsdzb/uni-updater.git

From Release

Go to the Releases and download the binary file, then put it in your $PATH.

Configuration

The default path of the config file is shown in the following table. You can also explicitly specify the path with --config flag.

Platform Path Example
Linux $XDG_CONFIG_HOME/uni-updater.yml or $HOME/.config/uni-updater.yml /home/alice/.config/uni-updater.yml
macOS $HOME/Library/Application Support/uni-updater.yml /Users/Alice/Library/Application Support/uni-updater.yml
Windows %APPDATA%\uni-updater.yml C:\Users\Alice\AppData\Roaming\uni-updater.yml

The config file mainly contains two parts. templates defines how a thing should be updated, and sequences are implements of the template. They can be compared to classes and objects in object-oriented languages. There is also a global_envs field for convenience.

global_envs

Globally set environment variables during execution. These variables are applied to every command of every sequence, and could be overwritten by sequence level environment variables.

global_envs:
  all_proxy: http://127.0.0.1:7890/"
  http_proxy: http://127.0.0.1:7890/"
  https_proxy: http://127.0.0.1:7890/"
  ftp_proxy: http://127.0.0.1:7890/"

templates

Templates defines the sequence of command when you update something. Just like its name, it supports interpolation for reuse.

Templates are indexed by name. A template must contains a command attribute, which is an array that defines the order of commands. The commands are executed sequencially when updating. Each element of command has a prog indicating the executable name, and an optional args indicating the arguments in array. Take these examples:

templates:
  yay: # Template name
    commands:
      - prog: "yay"

  rustup:
    commands:
      - prog: "rustup"
        args: ["update"]

  tlmgr:
    commands:
      - prog: "tlmgr"
        args: ["update", "all"]

  zim:
    commands:
      - prog: "zsh"
        args: ["-i", "-c", "zimfw upgrade"]
      - prog: "zsh"
        args: ["-i", "-c", "zimfw update"]

A template may have an optional wd attribute to set the working directory when executing commands. If this attribute is not present, commands will inherit the updater's working directory.

templates:
  neovim:
    wd: "/home/ttsdzb/.config/nvim"
    commands:
      - prog: "git"
        args: ["pull"]

Templates can also have an optional envs arrtibute for environment variables during its execution. If a variable got the same name with a global one, it will replace the global one.

templates:
  docker:
    wd: "/home/ttsdzb/%{dir}"
    envs:
      all_proxy: "http://127.0.0.1:10808" # Use a different proxy here
    commands:
      - prog: "docker-compose"
        args: ["pull"]

Every string in a template can have patterns for replacement. The pattern starts with a % followed by the value name in braces. The pattern will be replaced to corresponding values in sequences.

templates:
  remote:
    commands:
      - prog: "ssh"
        args: ["-t", "%{hostname}", "~/.local/bin/uni-updater -c %{color}"]

sequences

Sequences are actually executed by the updater. A sequence contains a name to be displayed in the logs, a template to use, and (optional) values to replace. The values could be emitted if there's no pattern to replace in the corresponding template.

sequences:
  - name: "System Update"
    template: yay

  - name: "Dell Wyse Remote Update"
    template: remote
    values:
      hostname: "wyse"
      color: "12"
  - name: "Frp Server Remote Update"
    template: remote
    values:
      hostname: "frp"
      color: "13"
  - name: "bwg-la Remote Update"
    template: remote
    values:
      hostname: "bwg-la"
      color: "14"

Note: The updater will not prevent execution if a pattern is left without a value! In this case, the pattern will be left untouched, causing unexpected behaviors.

This also indicates that you don't have to escape your characters when writing templates.

Full example (just an example, may not work on your environment out of box)

global_envs:
  all_proxy: http://127.0.0.1:7890/"
  http_proxy: http://127.0.0.1:7890/"
  https_proxy: http://127.0.0.1:7890/"
  ftp_proxy: http://127.0.0.1:7890/"

templates:
  yay:
    commands:
      - prog: "yay"
  rustup:
    commands:
      - prog: "rustup"
        args: ["update"]
  tlmgr:
    commands:
      - prog: "tlmgr"
        args: ["update", "all"]
  zim:
    commands:
      - prog: "zsh"
        args: ["-i", "-c", "zimfw upgrade"]
      - prog: "zsh"
        args: ["-i", "-c", "zimfw update"]
  neovim:
    wd: "/home/ttsdzb/.config/nvim"
    commands:
      - prog: "git"
        args: ["pull"]
  remote:
    commands:
      - prog: "ssh"
        args: ["-t", "%{hostname}", "~/.local/bin/uni-updater -c %{color}"]

sequences:
  - name: "System Update"
    template: yay
  - name: "Rust Toolchain Update"
    template: rustup
  - name: "TeX Live Update"
    template: tlmgr
  - name: "Zim Update"
    template: zim
  - name: "Neovim Config Update"
    template: neovim

  - name: "Dell Wyse Remote Update"
    template: remote
    values:
      hostname: "wyse"
      color: "12"
  - name: "Frp Server Remote Update"
    template: remote
    values:
      hostname: "frp"
      color: "12"
  - name: "Web Server Remote Update"
    template: remote
    values:
      hostname: "web"
      color: "12"

Arguments

Recipes

Mainly from topgrade's source code, but also from @hour-keeper's experience.

System Update

A simple way to update system

Arch

use yay
yay:
  commands:
    - prog: "yay"
use paru
paru:
  commands:
    - prog: "paru"
use pacman
paru:
  commands:
    - prog: "sudo"
      args: ["pacman", "-Syu"]

etc-update

A .pacnew file processing tool(also support Gentoo, but Gentoo Wiki not recommand it.)

etc-update:
  commands:
    - prog: "sudo"
      args: ["etc-update"]

Rustup

Rust toolchain manager.

rustup:
  commands:
    - prog: "rustup"
      args: ["update"]

Cargo

Rust package manager. Cargo is not really a software manager as it seems, but here are two tools cargo-update cargo-cache provides this functionality.

cargo:
  commands:
    - prog: "cargo"
      args: ["update"]
    - prog: "cargo"
      args: ["cache", "--autoclean"]

Fwupd

linux firmware update tool.

fwupd:
  commands:
    - prog: "sudo"
      args: ["fwupdmgr", "refresh"]
    - prog: "sudo"
      args: ["fwupdmgr", "update"]

tldr-pages

Collaborative cheatsheets for console commands.

tlrc

The official tldr-pages client written in Rust.

tldr:
  commands:
    - prog: "tldr"
      args: ["--update"]

pipx

Recommended way to install single pip package as a utility.

pipx:
  commands:
    - prog: "pipx"
      args: ["upgrade-all"]

chezmoi

A dotfiles management tool

chezmoi:
  commands:
    - prog: "chezmoi"
      args: ["update"]

pnpm

One of the best node.js packages managers.

pnpm:
  commands:
    - prog: "pnpm"
      args: ["update", "-g"]

Git Update

gitup

gitup:
  commands:
    - prog: "gitup"
      args: ["~/src", "~/.emacs.d", "~/.zsh"]

Remote

Updating a remote server.

remote:
  commands:
    - prog: "ssh"
      args: ["-t", "%{hostname}", "/usr/local/bin/uni-updater -c %{color}"]

Need Restart

needrestart checks which daemons need to be restarted after library upgrades. It is known that the software has been added to the debian package with a hook to automatically execute after apt upgrade, but the Arch package only provides a pacman hook to show changes, which requires a separate execution of needrestart in order to restart the service and so on.

restart:
  commands:
    - prog: "sudo"
      args: ["needrestart", "-r", "a"]

Troubleshooting

invalid type: map

Because serde_yml's YAML Anchors and Aliases support is temporarily unreleased, Some YAML Anchors and Aliases syntax like &p <<: *p are not available in the current version of the software.

FAQ

Why not topgrade?

  • I want to interactively included in the update process so I have control of what's going on, instead of clicking yes automatically, which make some of its features useless for me.
  • I don't want to upgrade things that is conflict to another. For example, upgrading system pip breaks package installed by system package manager. So I still have to find out what to update first, just like this program.
  • Topgrade depends on pre-defined recipes, and will not work immediately if your program cannot be recognized by it.
  • Some of topgrade's recipes are too aggressive and may break my setup, but again it's hard to alter since it's pre-defined.

Dependencies

~14–25MB
~391K SLoC