Skip to content

Instantly share code, notes, and snippets.

@samoht
Last active August 19, 2016 14:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save samoht/2188fbd01b1d40a3e2063f3a270bf8fd to your computer and use it in GitHub Desktop.
Save samoht/2188fbd01b1d40a3e2063f3a270bf8fd to your computer and use it in GitHub Desktop.
opam package

Managing local packages

OPAM is able to manage local packages.

Commands

The opam package sub-command extracts and uses the fields of a local opam file as it is was a globally available package.

Documentation

To access documentation of the current package:

$ opam package homepage # open a browser to the package homepage
$ opam package doc      # open a browser to the package documentation page
$ opam package [issues|bug-reports] # open a browser to the package bug tracker

NOTE: is that useful? Do we want to expose that for non-local packages too?

Install dependencies

To install the local package dependencies in the current switch:

$ opam packages [deps|dependencies] [--depopts] [--show]
  • If --depopts is set, the optional dependencies are also installed.
  • IF --show is set, do not install the packages, just show them.

Build

To build the local package in the context of the current switch:

$ opam package build

NOTE: need to decide what to do with dependencies. For instance:

$ opam package rebuild   # call 'opam update -u' on the depdencencies of the package + `opam build` 
$ opam package build -u  # same as above

Test

To test the local package in the context of the current switch:

$ opam package test

Installl

To install the local package in the context of the current switch (similar to opam pin add [NAME[.VERSION]] .):

$ opam package install [--name NAME[.VERSION]]

NOTE: is that useful? It seems a duplicate of local pins.

@AltGr
Copy link

AltGr commented Aug 19, 2016

Below, I am assuming you are at the root of the source tree of a package we'll call foo.

opam package homepage/doc/issues...

This is just [xdg-]open $(opam show -f homepage --file opam) ; can be built-in as sugar if it's often useful to many ; maybe something generic like an alias for opam show --file ./opam -f would already be good.

opam package build

As I understand it, opam package build would be described as "do what you would for opam install foo assuming foo was pinned to the current directory", except:

  • when actually getting to fetching/building foo, don't mirror, run the commands directly from ./ instead
  • stop after the build of foo (don't install, and dependents are not allowed)

I don't think we should mess with opam update, which can already be done independently, and is unrelated; something like opam package upgrade would be needed, though, to do an upgrade that preserves the version constraints of ./opam -- like would be done if it were an installed pin.
This boils down to deciding wether opam package build is purely a local command on your opam file, or if you want instead to register the package bound to ./ in the switch somehow -- which would actually be a new kind of pin instead ; that would be tempting for "local switches", but I think mixing the two features, while they could be independent, is a bad idea.

So opam package build may add, remove or upgrade packages on your switch, but won't actually affect it in relation with the source you're building.

This would be more or less equivalent to:

opam pin add foo . --no-action # assuming it was not pinned before...
opam install --deps-only foo
opam show --file opam -f "build:" | xargs opam config exec -- # except the output is not properly formatted, and the opam and shell environment for executing the command should be set properly
opam unpin foo

This can't be done properly from the outside of opam.

opam package test

Like above, bit with --test ; which needs fixing for not compiling/running tests of all packages, but that's a different matter.

opam package install

We need this; but actually in two flavours:

  • install to the current switch, like if the package was pinned;
  • install to some prefix in the system

That last case goes well together with, but shouldn't be limited to, local switches, where you fetch some source, use opam to get its deps and build it, then install it on your system. The first case is needed if e.g. you want to also test packages dependent on foo, like is already possible with pinning. Note, however, that done this way the state of package foo in the switch will be transient, and a further opam upgrade will want to revert to the repository version.

Some thoughts and concerns

  • @dbuenzli suggested at some point that, as a replacement for the "mixed-mode pins", we provide a --dirty option for pinned packages, when (re)installing or upgrading them. An idea would be to have a stronger version of that option that would actually run the build from the provided source directory, without an intermediate mirror (while --dirty only changes the way the mirror is synchronised, i.e. using the latest clean commit or not).
  • opam package is not an explicit name, and is a bit tautological. Also, it's not a verb (well it could be but the meaning would be different in that case) -- although since it allows subcommands that may be fine.
  • we support having several packages from the same source tree, with <name>.opam files. That should be supported by opam package too. In this case you might actually want to handle/build all of them (but this raises the question of intermediate installation, and parallel builds could be problematic...)
  • experimenting on this with an opam-package plugin would be feasible; we could start with just a few command wrappers with a plugin written in sh, but that'll be very limited; a proper plugin based on opam-lib could actually do as well as opam itself.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment