7.3 KiB
Tutorial: install your language
Presumably, your language isn't installed by default in Ubuntu. If
not, you'll need to add an install:
block to your language
configuration describing how to install it.
The easiest case is system packages, which are supported out of the box, for example:
install:
apt:
- ruby
npm:
- pug-cli
pip:
- bython
gem:
- solargraph
cpan:
- Acme::Chef
opam:
- ocamlformat
For more advanced configuration you need to understand how Debian
packaging works. To build a package, we place files into a ${pkg}
directory mirroring how they should be installed on the system, so for
example a binary intended for /usr/local/bin/prettier
would be
placed at ${pkg}/usr/local/bin/prettier
. Then the ${pkg}
directory
can be turned into a .deb
, which can be installed on any system.
If you have trouble, see the tutorial on debugging package installation.
Download a binary or script
We prefer to put all binaries in /usr/local/bin
rather than
/usr/bin
where they might conflict with default Ubuntu packages.
install:
manual: |
install -d "${pkg}/usr/local/bin"
wget http://www.blue.sky.or.jp/grass/grass.rb
chmod +x grass.rb
cp -T grass.rb "${pkg}/usr/local/bin/grass"
Get the latest version from GitHub
There is a predefined latest_release
function that can be used to
get the name of the latest tag in a GitHub repository.
install:
manual: |
install -d "${pkg}/usr/local/bin"
ver="$(latest_release snoe/clojure-lsp)"
wget "https://github.com/snoe/clojure-lsp/releases/download/${ver}/clojure-lsp"
chmod +x clojure-lsp
cp clojure-lsp "${pkg}/usr/local/bin/"
Get the latest version from some other website
In the case that there's no "download the latest version" URL, we
typically use disgusting grep
pipelines to extract it in a
semi-reliable way from a stable-seeming webpage.
install:
manual: |
install -d "${pkg}/usr/local/bin"
path="$(curl -fsSL http://static.red-lang.org/download.html | grep -Eo '/dl/linux/[^"]+' | head -n1)"
wget "http://static.red-lang.org${path}" -O red
chmod +x red
cp red "${pkg}/usr/local/bin/"
Unpack a tarball
Sometimes tarballs can be extracted directly to /usr/local
. However,
unless there's an obviously correct way to do that, we typically put
language distributions in /opt/<lang>
and then put symlinks in
/usr/local/bin
for the binaries. The -C
and --strip-components
flags are very helpful for controlling the extraction.
Also, one thing that might be unintuitive is that we use system-global
paths for the targets of symlinks (/opt/swift/bin/swiftc
) but
${pkg}
paths for the link names (${pkg}/usr/local/bin/swiftc
).
This is because while we are putting all files into ${pkg}
during
build, the eventual place they will be installed by the package is
into the root filesystem, so any references to paths within files
(including symlink targets) must not mention ${pkg}
.
install:
manual: |
install -d "${pkg}/opt/swift"
install -d "${pkg}/usr/local/bin"
ver="$(latest_release apple/swift | grep -Eo '[0-9.]+')"
wget "https://swift.org/builds/swift-${ver}-release/ubuntu2004/swift-${ver}-RELEASE/swift-${ver}-RELEASE-ubuntu20.04.tar.gz" -O swift.tar.gz
tar -xf swift.tar.gz -C "${pkg}/opt/swift" --strip-components=2
ln -s /opt/swift/bin/swiftc /opt/swift/bin/sourcekit-lsp "${pkg}/usr/local/bin/"
Compile from source
Sometimes there is no binary distribution. In this case you want to
clone/download the source code and run the appropriate compilation
command. GCC and LLVM plus a number of scripting languages are already
installed into the packaging
image by default, but you might have to
include a prepare
block listing additional things to install to be
able to compile the software.
For example, in this case the build.sh
script provided by Zot
happens to require some Qt development dependencies at compile time,
and a non-development dependency at runtime.
install:
prepare:
apt:
- qt5-qmake
- qtscript5-dev
apt:
- libqt5script5
manual: |
install -d "${pkg}/usr/local/bin"
git clone https://github.com/manyoso/zot.git
pushd zot
./build.sh
cp build/bin/zot "${pkg}/usr/local/bin/"
popd
Use a shared dependency
Your language may need to use software such as Prettier which is also
used by other languages but does not have an Ubuntu package. In that
case we package it as a Riju shared dependency (check the shared
directory for a list), and you declare the dependency using the riju
key.
install:
riju:
- prettier
Install custom scripts or config files
Sometimes you may need to add a wrapper script or config file
somewhere on the filesystem. Riju has the scripts
and files
keys
for this. The keys of these maps are the filesystem paths (scripts
defaults to putting things in /usr/local/bin
if relative paths are
given).
install:
scripts:
teco-encode: |
#!/usr/bin/env -S python3 -u
import re
import sys
for line in sys.stdin:
line = re.sub(r"\^(.)", lambda m: chr(ord(m.group(1)) ^ 0b1000000), line)
line = line.replace("$", chr(27))
print(line, end="")
files:
"/opt/sqlite/sqls.yml": |
connections:
- driver: sqlite3
dataSourceName: db.sqlite3
Setting up skeleton files
Sometimes your language may require some configuration files in
addition to the actual file to be compiled. Or alternatively, your
language may do a bunch of caching work the first time it starts up,
which you don't want to happen every time someone launches it on Riju.
Both of these problems can be solved by preparing files to be copied
into the user's home directory at the start of a new Riju session
(this is done using the setup
key, which is explained later).
In the following example, we ask .NET to create a project template for
us, and then compile the project. Then we take the files that were
created for the project, plus cache directories in $HOME
, and copy
them into /opt
so that they can be copied back later using setup
.
By convention, we name such directories skel
.
install:
prepare:
apt:
- $(grep-aptavail -wF Package "dotnet-sdk-3\.[0-9.]+" -s Package -n | sort -Vr | head -n1)
manual: |
install -d "${pkg}/opt/qsharp/skel"
dotnet new -i Microsoft.Quantum.ProjectTemplates
dotnet new console -lang Q# -o main
dotnet run --project main
shopt -s dotglob
cp -R * "${HOME}/.dotnet" "${HOME}/.nuget" "${pkg}/opt/qsharp/skel/"
rm "${pkg}/opt/qsharp/skel/main/Program.qs"
chmod -R a=u,go-w "${pkg}/opt/qsharp/skel"
Dealing with versioned APT packages
For some reason, some APT packages have version numbers in their
names. For example, you can't sudo apt install lua
; you have to
sudo apt install lua5.4
. The best way to deal with these situations
is to use various grep-aptavail
hacks to identify the latest
available version programmatically. Check the man page as well as uses
of grep-aptavail
in Riju to understand the options.
install:
apt:
- $(grep-aptavail -XF Provides lua -a -XF Version "$(grep-aptavail -XF Provides lua -s Version -n | sort -Vr | head -n1)" -s Package -n | head -n1)