Do people actually use vessel?

I’m at the point where I want library-level unit testing, and it seems like the general recommendation is to use motoko-matchers.

To install that, it seems like I also need to install vessel and point my package-set.dhall file to the latest version of vessel-package-sets.

Here’s a couple issues I saw from doing research:

  • vessel-package-sets seems pretty out-of-date… it’s stuck at Motoko v0.6.8, which is older than the current version of v0.6.14
  • vessel-package-sets needs to be regularly maintained to work properly, since it only supports a single version of any library, unlike package.json in JavaScript… that seems problematic, and it’s also not regularly maintained
  • Does motoko-matchers require wasmtime to actually run tests? The documentation isn’t clear
  • motoko-matchers was last tested on Motoko v0.5.8
  • There doesn’t seem to be a good reason to use vessel if you’re not using vessel-package-sets

Any help would be appreciated. Thanks!

2 Likes

A bit of staleness is not unexpected, as the main author of vessel, @kritzcreek, has left DFINTY a while ago.

That said, vessel is probably still the best way to manage dependencies (short of vendoring them, or maybe git submodules), and I use it in all my (toy) project when I need extra libraries such as sha256 . For example, in GitHub - nomeata/motoko-certified-http: A motoko canister that can server certified HTTP assets I am using vessel to pull in GitHub - nomeata/motoko-merkle-tree: A merkelized key-value store for Motoko (or rather, I did until I applied some simplifications).

It would probably be good to have more libraries on

https://dfinity.github.io/vessel-package-set/

But I agree that more active maintenance of the package set is lacking. But is it the cause of a problem, or a symptom?

2 Likes

vessel-package-sets seems pretty out-of-date… it’s stuck at Motoko v0.6.8, which is older than the current version of v0.6.14

It’s the latest compiler version CI tested against. Given that v0.6.14 just has patch bumps compared to v0.6.8 I’m assuming that the package-set should work just fine with the newer compiler version. There’s no reason to release a new package-set if none of the packages changed their versions. But updating the compiler version used on CI also isn’t hard.

vessel-package-sets needs to be regularly maintained to work properly, since it only supports a single version of any library, unlike package.json in JavaScript… that seems problematic, and it’s also not regularly maintained

npm’'s dependency model puts the onus on every single developer to try to keep their individual project building on a foundation of shifting dependencies underneath them. With the package-set approach we can share that work of making new versions of dependencies build together and then contribute the compatible version updates back upstream. Now that doesn’t stop you from maintaining your own project-local package-set like you’d do with package.json.

Does motoko-matchers require wasmtime to actually run tests? The documentation isn’t clear

That’s how I’ve run them so far. You can totally compile a Motoko actor and have it run matchers tests on the replica, though the feedback cycle would be much slower. I have an example of doing that here: GitHub - kritzcreek/ic101

There doesn’t seem to be a good reason to use vessel if you’re not using vessel-package-sets

vessel-package-sets forms a reasonable basis of “These are commonly used packages”. But, if you have your own, maybe company internal?, set of packages you like to use and share you can extend it or build your own package set. I know that Aviate Labs have done that for their collection of Motoko libraries: GitHub - aviate-labs/package-set: Aviate Labs' package set for Vessel

Here’s a cool example of a library that uses both dfinity/vessel-package-set and combines it with aviate-labs/package-set to collect all the dependencies it needs.

Having more active maintenance of vessel-package-set would certainly be nice, but my priorities have shifted around a bit, so it would require involvement of the community. There’s certainly nothing particularly hard about it, it’s just work.

6 Likes

Thanks, this is really helpful.

With the package-set approach we can share that work of making new versions of dependencies build together and then contribute the compatible version updates back upstream.

Can you explain how the package-set approach this? From what I can tell here, library maintainers still have their work cut out for them, as they need to continually update their dependencies if other packages/libraries use a newer version of a dependency they also use.


As an aside, I’m curious why vessel uses a different moc binary than the one shipped with dfx by default. Why not use the same moc as the one shipped with the version of dfx specified in the user’s dfx.json?

For example, I’m currently stuck on dfx 0.7.1, which I believe uses Motoko 0.6.1. But the vessel-package-set is currently tested on Motoko 0.6.7.

If I install vessel and use that latest vessel-package-set, then my canister code will be compiled with moc 0.6.1 but my dependency code will be compiled with moc 0.6.7. Isn’t that a problem? (I suppose, as you mentioned, semver means that 0.6.7 is backwards compatible with 0.6.1, but one day they’ll have to bump to 0.7.x.)

Or is this where I should change the compiler field in vessel.dhall?

Not sure what the difference between that and the version in vessel verify --version 0.6.1 is…

1 Like

I’m toying around with creating my own package set and had a question about the sha hash that gets appended to the upstream package-set source when other packages are using this package-set as an upstream source. I’d like to know how this sha256 is being generated - I’ve tried git hash-object package-set.dhall and shasum -a 256 package-set.dhall on the source package-set.dhall file in dfinity/vessel but am unable to match the shasums shown in the example

For example, after installing vessel when I run vessel init, my package-set.dhall remote for dfinity’s vessel-package-set looks like:

let upstream = https://github.com/dfinity/vessel-package-set/releases/download/mo-0.6.18-20220107/package-set.dhall sha256:af8b8dbe762468ce9b002fb0c62e65e1a3ee0d003e793c4404a16f8531a71b59

In the aviate-labs/package-set example linked above, the author’s example references the upstream as:

let upstream = https://github.com/aviate-labs/package-set/releases/download/v0.1.3/package-set.dhall sha256:ca68dad1e4a68319d44c587f505176963615d533b8ac98bdb534f37d1d6a5b47

I use it. Though I only use it for base. But I do think it is important to have a package manager. I haven’t had to create my own shared libraries as of yet. A good one would be Time but even then base can be extended for that. At some point we do want to add more libraries. I added it because I was going to to unit testing but ended up doing integration testing as I learn the language since it goes beyond just using the modules.

The main thing though is I’m trying to understand how that release hash is getting generated in the first place so that I can reuse my other packages without needing to clutter up my package-set.dhall with a bunch of imports. Something like what’s done here.

I’m not sure if I’m supposed to be able to reproduce this sha 256 or not, but figured it was a checksum I could generate pretty simply by just piping the file from the release into the sha256 algorithm.

I bet @kritzcreek would have some insights on the proper way to do this.

@icme That hash is a hash of the normalized representation of the .dhall file. They’re calling a “semantic integrity check” Haskell for all: Semantic integrity checks are the next generation of semantic versioning

The TLDR:

  • Dhall expressions that evaluate to the same result have the same hash. So adding a comment, renaming a variable, or extracting a piece of duplicated logic into a function do not change the hash.

If you install the dhall binary you can use its dhall hash command to hash arbitrary dhall expressions:

~
❯ echo 10 | dhall hash
sha256:d4428061b6fd69b6b45574603ac71060f9756a5c9a1642df322812e3a7ea858b

~
❯ echo let x = 10 in x | dhall hash
sha256:d4428061b6fd69b6b45574603ac71060f9756a5c9a1642df322812e3a7ea858b

Here’s one example of two expressions with different source text that evaluate to the same hash.

4 Likes

Oh and dhall freeze automatically appends it to all the imports in a given file. So that might be simpler than using dhall hash if you just want to add it to your imports.

3 Likes

Why do you use it for motoko-base? I did before, but then realized that when I upgraded dfx, the motoko-base didn’t upgrade automatically without me manually updating the dependency hash in package-set.dhall for vessel to pick it up.

I pointed it to the master branch. Hmm yeah I haven’t checked if it updates automatically. I use it for that because I thought I was going to use it for other things like unit testing. I mean it makes sense to use a package manager specially as the ecosystem grows. I think the repo is getting picked up again. Would be nice if it was part of dfx and had a npm type of repo with good search and trends. But these are all things that need capital and people’s time to build out.

1 Like