Opam pin does not have the desired effect

I have the following problem. I have created an opam package fmlib which is released. When I install the package via opam install name I can use the package.

Now I have made some changes to the package and want to ust them in some other program before releasing a new version of the package. From my understanding opam pin is the proper command to do this. The changed version of the package is in a separate branch pretty on github. So issued

   opam pin add fmlib https://github.com/hbr/fmlib.git#pretty

However I cannot use the new functionality. Looking into the directory .opam/default/lib/fmlib_prettyreveals that the source code of the changed files is not present.

I have the speciality that fmlib uses several packages (fmlib_std, fmlib_pretty, … ) where the change happens in the package fmlib_pretty. However even pinning fmlib_pretty does not change anything.

Does anyone have an idea on how to find out whats wrong. I remember that I had used opam pin in the past on the same packages and it had the desired effect.

Thanks for any hint.

What’s the output of opam pin?

I think I have solved the problem. But I do not understand the mechanics of opam pin completely. Therefore some experts might comment.

  • I have a collection of opam packages which are in one github repository.
  • One package fmlibuses all the others. It is an empty umbrella package. The idea is to issue opam install fmliband get all the others installed with one command. The collection of packages are released together.

However opam seems to treat the packages individually. So pinning the umbrella package has not the desired effect of pinning the used packages as well. If I pin the individual packages I get the desired effect.

Yes, the “umbrella package” is your own view of it. There is no such concept in opam. I mean if you pin fmlib, should it also pin say dune or ocaml ?

> opam show fmlib -f depends          
"ocaml" {>= "4.08.0"}
"dune" {>= "3.0.0"}
"odoc" {with-doc}
"fmlib_std" {= version}
"fmlib_pretty" {= version}
"fmlib_parse" {= version}
"fmlib_js" {= version}
"fmlib_browser" {= version}

One thing you can do though is to specify pin-depends: in the opam file of fmlib with pins on the individual packages. That way a pin on fmlib would trigger a pin on the other packages.

Thanks for the comment. It seems to be the best to pin the subpackages individually. Since I don’t need this very often, it is no problem to do it that way.

One question remains. Consider the following scenario:

  • I introduce a change in one subpackage (e.g. fmlib_pretty) which is a breaking change for another subpackage (e.g. fmlib_parse) which depends on the first one.
  • In the git branch I commit all changes in fmlib_parse necessary to adapt to the changes in fmlib_pretty. I.e. my github branch is consistent.
  • However the pinnings must be done in sequence. So if I pin fmlib_pretty then the package fmlib_parse on my computer cannot be compiled (since it is not yet pinned).

Is it possible to pin fmlib_parse in a second step or does the first pin fail?

yes, using opam pin add --no-action which pins the package or directory you want but does not install them.

if you pin them one by one yes, but here i assume you’d want to pin the whole project, not enumerate all the packages. You can pin the whole project at once using:

opam pin add https://github.com/hbr/fmlib.git#pretty
1 Like

This is great!! The most convenient solution for me. I.e. without naming the subpackages I get the whole project pinned.

Thank you.