This repository provides an OPAM package for Topiary. In particular, issues with Topiary itself should be reported there while issues with Topiary's packaging in OPAM should be reported here.
Topiary is written in Rust and is therefore not an OCaml project per se. However, as it allows formatting OCaml (among other languages), it does belong to its ecosystem and, therefore, it makes sense to package it via OPAM.
This is actually not so complicated. OPAM “is a source-based package manager for
OCaml”, which prevents using it to distribute precompiled binaries, but it is
actually OCaml agnostic, meaning it is possible to call cargo build
in an OPAM
package.
The difficulty is then that such a package depends on the presence of Rust on the system in the right version. Additionally, Cargo tends to download Rust dependencies when building which cannot possibly happen in the OPAM sandbox. One way around this is to provide another repository containing Topiary and all its dependencies as well as what is necessary to get the OPAM package working. This is where you are.
Credits are due to all the participants of this OCaml discuss thread for their
encouragements and their ideas and to the people behind tezos-rust-libs
on
which this package is based.
The compilation of Topiary depends on the presence of Rust on the system in a recent enough version. Currently, Rust 1.70.0 is required. Our continuous integration keeps track of several distributions whose Rust version is listed here for convenience:
Distribution | Rust Version |
---|---|
Alpine | |
Archlinux | |
CentOS | |
Debian | |
Fedora | |
openSUSE | |
Ubuntu |
This repository is made of the following building blocks:
-
topiary/
is a Git submodule pointing to Topiary's Git at a certain commit (in general at a certain tag). The file.gitmodules
declares the submodule to Git. -
Cargo.toml
andCargo.lock
define a Cargo workspace containing only Topiary. This allows working with Cargo to vendor dependencies without changing the content of thetopiary/
directory. -
vendor/
is a directory filled automatically by Cargo and containing all the dependencies of Topiary, vendored. This is a way to provide all the dependencies at upfront and to avoid having Cargo download them during the installation. The file.cargo/config.toml
contains a configuration that tells Cargo to look intovendor/
instead of its usual sources. -
make-topiary-wrapper.sh
is a Shell script creating a wrapper around Topiary that provides it with the right environment. In particular, Topiary needs to be made aware of where it can find its “language files”. -
topiary.opam
contains the definition of the OPAM package for Topiary.
Make sure you have Rust and Cargo. This repository comes with a Nix flake, so simply running:
$ nix develop
should provide you with everything you need. Alternatively, on a Nix
machine,
you can use:
$ nix shell nixpkgs#{cargo,rustc}
Use OPAM's pinning mechanism to inform it of the development version of Topiary.
$ opam pin add --no-action topiary.dev /path/to/this/repository
[topiary.dev] synchronised (file:///path/to/this/repository)
topiary is now pinned to git+file:///path/to/this/repository#branch-name (version dev)
From the root of this repository, .
suffices; OPAM will make an absolute link
out of this. After this, you can simply rely on OPAM's usual commands and you
will get access to a new version of Topiary, dev
:
$ opam show topiary
<><> topiary: information on all versions <><><><><><><><><><><><><><><><><><><>
name topiary
all-versions 0.1.0 0.2.0 0.2.1 0.2.2 0.2.3 dev
<><> Version-specific details <><><><><><><><><><><><><><><><><><><><><><><><><>
version dev
pin git+file:///path/to/this/repository#branch-name
[...]
$ opam install topiary
<><> Synchronising pinned packages ><><><><><><><><><><><><><><><><><><><><><><>
[topiary.dev] synchronised (git+file:///path/to/this/repository#branch-name)
The following actions will be performed:
∗ install topiary dev*
<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><><><>
⬇ retrieved topiary.dev (no changes)
∗ installed topiary.dev
Done.
If your working directory is not clean, you might want to add --working-dir
(or -w
for short) to your commands; otherwise, OPAM only picks up on the Git
index and not the work tree. Be careful, though, as this might hide some subtle
bugs due to some files not being committed.
-
Update the Git submodule containing Topiary. Make sure it is checked out at a tag of your choosing:
$ cd topiary $ git fetch remote: Enumerating objects: 299, done. [...] From ssh://github.com/tweag/topiary * [new tag] v0.1.0 -> v0.1.0 $ git checkout v0.1.0 HEAD is now at c4fe76c GraphViz visualisation support (#326) $ cd ..
-
Commit this update:
$ git add topiary/ $ git commit -m 'Bump submodule to v0.1.0' [main 3bb3a28] Bump submodule to v0.1.0 1 file changed, 1 insertion(+), 1 deletion(-)
-
Remove the previous local Cargo configuration and vendoring:
$ rm .cargo/config.toml $ rm -R vendor/
Otherwise, the next step will yield an error, something in the lines of: “failed to get
<whatever>
as a dependency of packagetopiary
”. -
Update the
Cargo.toml
file. This usually consists in copying the content oftopiary/Cargo.toml
file and prefixing all the local paths bytopiary/
. In particular,workspace.members
andworkspace.default-members
need to be updated. Sometimes, locally vendored dependencies might need the same treatment, as in for instance:topiary-web-tree-sitter-sys = { version = "0.5.1", path = "./topiary/topiary-web-tree-sitter-sys" }
Make sure that the version number in
Cargo.toml
is correct; this is trivial if it was copied from thetopiary/
submodule. -
Update the
Cargo.lock
file. Again, this usually consists in copying the one fromtopiary/Cargo.lock
. -
Regenerate the
vendor/
directory:$ cargo vendor Downloaded hermit-abi v0.1.19 Downloaded is-terminal v0.4.7 Downloaded instant v0.1.12 [...] Vendoring indexmap v1.9.3 (~/.cargo/registry/src/github.com-1ecc6299db9ec823/indexmap-1.9.3) to vendor/indexmap Vendoring instant v0.1.12 (~/.cargo/registry/src/github.com-1ecc6299db9ec823/instant-0.1.12) to vendor/instant Vendoring io-lifetimes v1.0.10 (~/.cargo/registry/src/github.com-1ecc6299db9ec823/io-lifetimes-1.0.10) to vendor/io-lifetimes Vendoring is-terminal v0.4.7 (~/.cargo/registry/src/github.com-1ecc6299db9ec823/is-terminal-0.4.7) to vendor/is-terminal [...] To use vendored sources, add this to your .cargo/config.toml for this project: [source.crates-io] replace-with = "vendored-sources" [...] [source.vendored-sources] directory = "vendor"
Note in particular the last lines about adding something to the local Cargo configuration.
-
Recreate the local Cargo configuration with the content given by
cargo vendor
.$ nano .cargo/config.toml
-
Commit this update:
$ git add Cargo.toml Cargo.lock .cargo/ $ git add --force vendor/ $ git commit -m 'Update Cargo dependencies' [main 95d67dc] Update Cargo dependencies 8 files changed, 125 insertions(+), 57 deletions(-)
Note that we use
--force
when addingvendor/
because we otherwise risk ignoring files due to.gitignore
which Cargo will still expect. -
Adapt the OPAM package or the other files if necessary and commit the changes.
-
Test that it looks like it works (see How to develop).
-
Open a new pull request on this repository and check that the continuous integration is happy with the current status of things. Merge the pull request in question.
-
Add a tag mimmicking that of Topiary (eg.
v0.1.0
for Topiary'sv0.1.0
). -
Create an archive containing all the content of this repository at that tag:
$ git-archive-all source-code-with-submodules.tar.xz
This will be necessary to provide a downloadable archive that contains the files from all the submodules.
-
Create a release for the tag in question. Link to the corresponding release in Topiary. Attach the archive.
-
Compute the MD5 and SHA512 sums of the archive in question:
$ md5sum source-code-with-submodules.tar.xz cd825a17db25cb94fd876eef055090e4 source-code-with-submodules.tar.xz $ sha512sum source-code-with-submodules.tar.xz ae6946aaba0f784773cca71019f73aa62d9b976646ea25e451c220f45da49e6c7e4147e2dd57e3c4764a9038946c38b9de33ce5d463c46ea3f3271d5b98dd46f source-code-with-submodules.tar.xz
-
Send the new package to the OPAM repository. The
src
field of theurl
object should be:https://github.com/tweag/topiary-opam/releases/download/<tag>/source-code-with-submodules.tar.xz