Giter Site home page Giter Site logo

rinstall's Introduction

rinstall

GitHub branch checks state GitHub

rinstall is an helper tool that installs software and additional data into the system. Many programs often include man pages, documentation, config files and there is no standard way to install them except for using Makefiles or complete build system. However, Makefiles are notoriously complicated to setup; it is especially hard to follow the Directory Variables from the GNU Coding Standard.). Build systems instead cover the installation part but depending on an entire build system to install a shell script or a rust binary is not optimal. You can read more of rinstall rationale here.

rinstall read a declarative YAML file (install.yml) containing the list of the files to install. It then installs the program either system-wide or for the current user (following the XDG BaseDirectories). It reads the default configuration for the system from /etc/rinstall.yml or .config/rinstall.yml, using a default one otherwise.

Packaging status

Features

  • List the files to install and their location in a declarative way
  • Ensure backward compatibility (no need to update install.yml every new rinstall version)
  • Support for both user and system-wide installation
  • Works inside the codebase or from the release tarball
  • Native support for Rust programs and cargo
  • Easy uninstallation of packages
  • Allow templating of documentation and man pages
  • Support for GNU Directory standard, FHS and XDG BaseDirectories, with optional configuration
  • Support most common types of files
  • Reproducible installation
  • Packagers friendly

Build

To build from source run the following command:

$ cargo build --release

To install rinstall for the current user:

$ ./target/release/rinstall install -y

Usage

If the project has an install.yml file present, either in the root directory or in the .package directory, it supports installation via rinstall.

Run rinstall as your user to see the changes that will be done to the filesystem:

$ rinstall install

After having reviewed the changes, add -y or --yes to perform an user installation:

$ rinstall install --yes

The same apply for performing a system-wide installation, enabled by adding the flag --system. To list the changes made to the filesystem, run rinstall in dry mode (i.e. without the flag--yes):

$ rinstall install --system

To accept the changes, run again the command and append the flag -y or --yes. You need to run the command as root to apply the changes to the filestem.

# rinstall install --system -y

Uninstall

When a package gets installed, a file with the suffix .pkg will be created inside $localstatedir/rinstall (by default /usr/local/var/ rinstall for system installations and $HOME/.local/share/rinstall for user installations). This file will contain the list of installed files, allowing the the uninstall subcommand to revert the installation of a package:

$ rinstall uninstall wpaperd
Would remove /home/danyspin97/.local/bin/wpaperd
Would remove /home/danyspin97/.local/bin/wpaperctl
Would remove /home/danyspin97/.local/share/bash-completion/wpaperd.bash
Would remove /home/danyspin97/.local/share/licenses/wpaperd/LICENSE.md
Would remove /home/danyspin97/.local/share/rinstall/wpaperd.pkg

Packagers

rinstall support the packagers use-case out of the box. When calling rinstall inside a package specification (i.e. spec file, PKGBUILD, ebuild), add the --packaging flag and it will enable all relevant flags and ask you the needed information:

$ rinstall install --packaging --destdir mydestdir
>>> Package rinstall
Would install target/release/rinstall -> mydestdir/usr/local/bin/rinstall
Would install target/release/man/rinstall.1 -> mydestdir/usr/local/share/man/man1/rinstall.1
Would install README.md -> mydestdir/usr/local/share/doc/rinstall/README.md
...

Release tarballs

rinstall supports installing from release tarballs (i.e. the tarballs published on Github for each release containing a compiled version of the program).

To allow a program to be installed from a release tarball create a .tarball empty file during the generation and include install.yml. rinstall will then assume that all the files are in the top directory and proceed to install them as usual; this means that for Rust programs, the executables will be searched in the top directory instead of target/release. Please assure that all the files listed in install.yml are included in the tarball.

Configuration

The installation directories chosen by rinstall can be configured by adding and tweaking the file rinstall.yml under the sysconfdir. By default, /etc/rinstall.yml and $HOME/.config/rinstall.yml will be used respectively for the root user and the non-root user.

The root configuration should already be installed by the rinstall package of your distribution and it can also be found in the config/root/ directory of this repository; the non-root user configuration can be found in the config/user/ directory. All the placeholders will be replaced at runtime by rinstall.

Additionally, a different configuration file can be passed by using the --config (or -c) command line argument. All the values can also be overridden when invoking rinstall by using the respective command line arguments.

The configuration is a YAML file that can contain the following keys. If any of them is missing, a default value will be used instead.

  • bindir
  • libdir
  • datarootdir
  • datadir
  • sysconfdir
  • localstatedir
  • runstatedir
  • systemd_unitsdir

In addition, the system-wide configuration can contain the following keys:

  • prefix
  • exec_prefix
  • sbindir
  • libexecdir
  • includedir
  • docdir
  • mandir
  • pam_modulesdir

Please refer to the Directory Variables for their usage.

If any key is missing,

Placeholders in configuration

Root user configuration

In the configuration you may want to set a value based on another directory set prior. For example you may want bindir to be a directory bin relative to the exec_prefix directory. rinstall supports placeholders in the configuration to allow this:

exec_prefix: /usr/local
bindir: @exec_prefix@/bin

The root user configuration allows for the following placeholders:

  • @prefix@, supported by all values
  • @exec_prefix@, supported in bindir and libdir
  • @localstatedir@, supported in runstatedir
  • @datarootdir@, supported in docdir and mandir
  • @libdir, supported in pam_modulesdir and systemd_unitsdir

Non-root user configuration

Non-root user configuration relies on XDG Directories, so it allows placeholders that refer to these values. The placeholders will be replaced by the environment variable and, if it is not set, it will fallback on a default value:

datadir: @XDG_DATA_HOME@
sysconfdir: @XDG_CONFIG_HOME@

The non-root user configuratione supports for the following placeholders:

  • @XDG_DATA_HOME@, supported in datarootdir and datadir
  • @XDG_CONFIG_HOME@, supported in sysconfdir and systemd_unitsdir
  • @XDG_STATE_HOME@, supported in localstatedir
  • @XDG_RUNTIME_DIR@, supported in runstatedir
  • @sysconfdir@, supported in systemd_unitsdir

<pkg-name>

An additional placeholder used when configuring the directories is <pkg- name>; this will automatically be replaced by the package name used inside install.yml. Some directories (e.g. docdir use this placeholder by default). Manually set the directories to remove it.

Writing install.yml

To support rinstall, place an install.yml file into the root of your project. It shall contain the rinstall version to use and the packages to install. Each package shall contain the entries of the files to install, divided by their purpose/destination.

Example file for a program named foo written in Rust that only install an executable with the same name:

rinstall: 0.1.0
pkgs:
  foo:
    type: rust
    exe:
      - foo

install.yml examples

rinstall version

each rinstall release will have a respective version of the spec file; each version might support new entry types but it might remove support for some as well. rinstall will support older releases, along with all its entry types which were allowed.

Packages

rinstall support the installation of multiple packages from the same repository. Put all the packages under a unique name inside the key pkgs in the install.yml file (even if there is only one package):

rinstall: 0.1.0
pkgs:
  foo:
    type: rust
    exe:
      - foo
  bar:
    type: rust
    exe:
      - bar
  bar-c:
    include:
      - bar.h

Entries

Each entry list a file to install and it shall either be a string or a struct containing the following data:

  • src: the source, containing the location to the file that will be installed. Unless noted, it shall always be relative to the project directory.
  • dst: the destination (optional), containing the directory or file where that this entry should be installed to. It shall always be relative, the corresponding system directory will be appended based on the type of entry; e.g. for exe entries, the destination part will be appended to bindir. To mark the destination as a directory, add a leading path separator /.
  • tmpl: enable templating for the current entry; refer to templating for more information.

When the entry is only a string, it shall contains the source and follows the same rules as src.

Example entry defined by a struct:

src: myprog.sh
dst: myprog

Example entry where destination is a directory:

src: myprog
dst: internaldir/

Valid entries

rinstall allows for the following keys:

Note: each entry will be available for both system and non-system wide installations except were expliticly noted.

Type

(since 0.1.0)

The type part can either be rust or default. If no value is specified, then default will be used.

  • rust for projects built using cargo. The target directory is fetched using cargo metadata and used as root directory for executables and libraries. I.e. you don't need to use target/release/myexe when listing executables, but just myexe. If you need to install an executable script in a Rust project, use $PROJECTDIR/ prefix.

  • default for all the other projects. All the directories will be relative to the root directory of the project.

exe

Version System-wide only
since 0.1.0 no
Installed in Defaults to
system-wide $bindir /usr/local/bin
user-wide $bindir $HOME/.local/bin

For the executables.

admin_exe

Version System-wide only
since 0.1.0 yes
Installed in Defaults to
system-wide $sbindir /usr/local/sbin

For admin executables; they will be installed in sbindir (which defaults to /usr/local/sbin).

libs

Version System-wide only
since 0.1.0 no
Installed in Defaults to
system-wide $libdir /usr/local/lib
user-wide $libdir $HOME/.local/lib

For the libraries.

libexec

Version System-wide only
since 0.1.0 yes
Installed in Defaults to
system-wide $libexecdir /usr/local/libexec

include

Version System-wide only
since 0.1.0 yes
Installed in Defaults to
system-wide $includedir /usr/local/include

For headers.

man

Version System-wide only
since 0.1.0 yes
Installed in Defaults to
system-wide $mandir /usr/local/share/man

For the man pages.

data

Version System-wide only
since 0.1.0 no
Installed in Defaults to
system-wide $datarootdir /usr/local/lib
user-wide $XDG_DATA_HOME $HOME/.local/share

For architecture independent files.

docs

Version System-wide only
since 0.1.0 yes
Installed in Defaults to
system-wide $datarootdir/<pkg-name> /usr/local/share/doc/<pkg-name>

For documentation and examples.

config

Version System-wide only
since 0.1.0 no
Installed in Defaults to
system-wide $sysconfdir/<pkg-name> /usr/local/etc/<pkg-name>
user-wide $XDG_CONFIG_HOME/<pkg-name> $HOME/.config/<pkg-name>

For configuration files.

user-config

Version System-wide only
since 0.1.0 no
Installed in Defaults to
system-wide $datarootdir/<pkg-name>/user-config /usr/local/share/docs/<pkg-name>/user-config
user-wide $XDG_CONFIG_HOME $HOME/.config

For configuration files that can only be used by non-root users. For system-wide installations, these files will be treated as documentation.

desktop-files

Version System-wide only
since 0.1.0 no
Installed in Defaults to
system-wide $datarootdir/applications /usr/local/share/applications
user-wide $XDG_DATA_HOME/applications $HOME/.local/share/applications

For .desktop files; they will be installed in folder applications under datarootdir (which defaults to /usr/local/share/applications).

appstream-metadata

Version System-wide only
since 0.1.0 yes
Installed in Defaults to
system-wide $datarootdir/metainfo /usr/local/share/metainfo

For AppStream metadata files.

completions

Version System-wide only
bash since 0.1.0 no
elvish since 0.2.0 no
fish since 0.1.0 yes
zsh since 0.1.0 yes

For completions files; they will be installed in the respective shell completions directory, under datarootdir:

  • $datarootdir/bash-completion/completions for bash
  • $datarootdir/elvish/lib for elvish
  • $datarootdir/fish/vendor_completions.d for fish
  • $datarootdir/zsh/site-functions for zsh

Example:

completions:
  bash:
    - cat.bash
    - cp.bash
  fish:
    - cat.fish
    - cp.fish
  zsh:
    - _cat
    - _cp

pam-modules

Version System-wide only
since 0.1.0 yes
Installed in Defaults to
system-wide $libdir/security /usr/local/lib/security

For PAM modules. If only src is provided, and the name of the file starts with lib, e.g. libpam_mymodule.so, it will be automatically converted to pam_mymodule.so.

systemd-units

Version System-wide only
since 0.1.0 yes
Installed in Defaults to
system-wide $systemd_unitsdir/system /usr/local/lib/systemd/system

For systemd system units.

systemd-user-units

Version System-wide only
since 0.2.0 no
Installed in Defaults to
system-wide $systemd_unitsdir/user /usr/local/lib/systemd/user
user-wide $XDG_DATA_HOME/systemd/user $HOME/.local/share/systemd/user

For systemd user units; they will be installed in @systemd_unitsdir@/user (/usr/local/lib/systemd/user by default).

icons

Version System-wide only
since 0.1.0 no

For icons. There two different locations for icons:

  • @datarootdir@/pixmaps (system-wide only)
  • @datarootdir@/icons

To install an icon into one or the other, use pixmaps:

icons:
  - src: myicon.svg
    pixmaps: true

The icons in the latter are divided into different folders by:

  • theme, which defaults to hicolor
  • dimensions, which is the size of the icon in the form of YxY (48x48) or scalable for svg icons (mandatory)
  • type, which defaults to apps

Example:

icons:
  - src: myicon.svg
    dimensions: scalable

theme and type are optional. For more information the entries in @datarootdir@/icons, have a look at the Directory Layout of the freedesktop icon theme specification.

terminfo

Version System-wide only
since 0.1.0 yes
Installed in Defaults to
system-wide $datarootdir/terminfo /usr/local/share/terminfo

For terminfo sources. The source files won't be compiled by rinstall. Please compile them manually after installation by using tic. The files there are divided into different folders based on the first letter of the file name. For example the file alacritty.info should be installed in /usr/local/share/terminfo/a/alacritty.info. Just use the name of the file in src or dst and rinstall will handle the directory.

licenses

Version System-wide only
since 0.1.0 no
Installed in Defaults to
system-wide $datarootdir/licenses/<pkg-name> /usr/local/share/licenses/<pkg-name>
user-wide $XDG_DATA_HOME/licenses/<pkg-name> $HOME/.local/share/applications/<pkg-name>

For licenses.

pkg-config

Version System-wide only
since 0.1.0 yes
Installed in Defaults to
system-wide $libdir/pkgconfig /usr/local/lib/pkgconfig

For pkg-config files.

Templating

Sometimes it might be required to refer to some installed file or some location. However, these locations are only known when installing, so they can't be hard-coded into the file itself. rinstall allows to replace some placeholders with the actual directories.

To enable templating for a file, add tmpl: true to an entry:

docs:
  - src: my-doc.md
    tmpl: true

my-doc.md file will contains one of the placeholders specified below and they will be replaced automatically by rinstall. For example if it contains the following contents:

This project has used @prefix@ as its prefix and @bindir@ as its bindir.

Then we invoke rinstall like this:

# rinstall install -y --prefix /usr --bindir "@prefix@/bin"

The documentation file my-doc.md installed will look like the following:

This project has used /usr as its prefix and /usr/bin as its bindir.

Allowed placeholders

The following placeholders will be replaced with their respective value when templating is enabled for an entry:

  • @prefix@
  • @exec_prefix@
  • @bindir@
  • @datarootdir@
  • @datadir@
  • @sysconfdir@
  • @localstatedir@
  • @runstatedir@
  • @includedir@
  • @docdir@
  • @mandir@
  • @pam_modulesdir@
  • @systemd_unitsdir@

License

rinstall is licensed under the GPL-3+ license.

rinstall's People

Contributors

0x5c avatar classabbyamp avatar danyspin97 avatar firasuke avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

Forkers

jgarte 0x5c

rinstall's Issues

rinstall tries to overwrite directories with files in some cases

The cause appears to be when paths don't end in a slash when trying to compute the destination path of files.

This can be seen in numerous places, including the default bindir path for users $HOME/.local/bin, along with any completion file.

Trying to use a freshly built rinstall to install itself:

$ cargo run --release -- install
>>> Package rinstall
WARNING: file /home/USER/.local/bin already exists, add --force to overwrite it
Would install target/release/rinstall -> /home/USER/.local/bin
WARNING: file /home/USER/.local/share/bash-completion already exists, add --force to overwrite it
Would install target/release/completions/rinstall.bash -> /home/USER/.local/share/bash-completion
WARNING: file /home/USER/.local/share/elvish/lib already exists, add --force to overwrite it
Would install target/release/completions/rinstall.elv -> /home/USER/.local/share/elvish/lib
Would install LICENSE.md -> /home/USER/.local/share/licenses/rinstall/LICENSE.md
Would install pkginfo -> /home/USER/.local/share/rinstall/rinstall.pkg

After adding a slash to all completion paths in package.rs and using --bindir $HOME/.local/bin/, the computed paths make sense

$ cargo run --release -- install --bindir $HOME/.local/bin/
>>> Package rinstall
Would install target/release/rinstall -> /home/USER/.local/bin/rinstall
Would install target/release/completions/rinstall.bash -> /home/USER/.local/share/bash-completion/rinstall.bash
Would install target/release/completions/rinstall.elv -> /home/USER/.local/share/elvish/lib/rinstall.elv
Would install LICENSE.md -> /home/USER/.local/share/licenses/rinstall/LICENSE.md
Would install pkginfo -> /home/USER/.local/share/rinstall/rinstall.pkg

Simply ensuring that all directory paths end with / seems to 'fix' the bug, but it almost feels like the real problem might be in how the file paths are computed.

Support non binary files inside rust target directory

kanidm is correctly putting completions inside the target directory (OUT_DIR), as build.rs shouldn't modify any file outside this directory:

   completions:
      bash:
        - target/release/build/completions/kanidmd.bash
        - target/release/build/completions/kanidm_badlist_preprocess.bash
        - target/release/build/completions/kanidm.bash

rinstall should automatically search for this files inside the OUT_DIR. I think it could never happen that the same file is inside both the project target directory and the OUT_DIR.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.