How to locally upgrade an OPAM package

The opam manual shows how to test a newly defined package by installing it locally before publishing it (https://opam.ocaml.org/doc/Packaging.html).

How can i do the same thing for a new version of an existing package ?

In my case, i have a package rfsm.1.7.0 already published and installed in the current switch:

$ opam info rfsm

<><> rfsm: information on all versions ><><><><><><><><><><><><><><><><><><>  🐫 
name                   rfsm
all-installed-versions 1.6 [4.06.0]  1.6.0 [4.08.1]  1.7.0 [4.10.0 4.14.0]
all-versions           1.0  1.4.2  1.5  1.6-alpha-3  1.6.0  1.7.0

<><> Version-specific details <><><><><><><><><><><><><><><><><><><><><><><>  🐫 
version     1.7.0
repository  default
pin         git+file:///Users/jserot/Dev/ml/rfsm#master
source-hash 02401584
...
depends     "dune" {>= "3.11"}
            "menhir" {>= "2.0"}
            "lascar" {>= "0.7"}
            "ocamlgraph" {>= "1.8"}
            "ocaml" {>= "4.10"}
            "odoc" {with-doc}

and have developed, tested , tagged and pushed to GH vers 2.0 of the same package.

If i try, from the root directory of the package:

opam install .

i get

[rfsm.1.7.0] synchronised (no changes)
[ERROR] Package conflict!
  * No agreement on the version of ocaml:
    - (invariant) → ocaml-base-compiler = 5.0.0 → ocaml = 5.0.0
    - rfsm >= 1.7.0 → lascar >= 0.7 → ocaml < 5.0.0
...

and a lot of similar errors which i do not understand since the lascar package is notlonger part of the rfsm-2.0 package dependencies.

Why is the opam install command for version 2.0 of the package apparently taking care of dependencies listed in version 1.7.0 ?
Am i missing sth ?

mmh, that’s indeed a weird one.
opam info shows the right tag but not the right information.

Could you try opam pin remove rfsm && opam pin add "git+file:///Users/jserot/Dev/ml/rfsm#master" and see if it helps?

If not, what version of opam do you have? If you have the latest stable already 2.1.5, could you try using the latest 2.2.0~alpha3 using the following command:

bash -c "sh <(curl -fsSL https://raw.githubusercontent.com/ocaml/opam/master/shell/install.sh) --dev"

and try the opam pin command above again

$ opam pin remove rfsm
Ok, rfsm is no longer pinned to git+file:///Users/jserot/Dev/ml/rfsm#master (version 1.7.0)
$ opam pin add "git+file:///Users/jserot/Dev/ml/rfsm#master"
rfsm is now pinned to git+file:///Users/jserot/Dev/ml/rfsm#master (version 1.7.0)

The following actions will be performed:
  ∗ install rfsm 1.7.0*
Do you want to continue? [Y/n]

Why is opam insisting on installing 1.7.0 ?

$ cat rfsm.opam
opam-version: "2.0"
...
homepage: "http://github.com/jserot/rfsm"
bug-reports: "jocelyn.serot@uca.fr"
depends: [
  "dune" {>= "3.11"}
  "menhir" {>= "2.0"}
  "ocamlgraph" {>= "2.0"}
  "ocaml" {>= "4.14.0"}
  "odoc" {with-doc}
]
build: [
  ["dune" "subst"] {dev}
  [ "dune"  "build" "-p"
    name
    "-j"
    jobs
    "@install"
    "@runtest" {with-test}
    "@doc" {with-doc}
  ]
]
dev-repo: "git+https://github.com/jserot/rfsm.git"

Au fait, where do i specify that the current package version is 2.0 ?
Is it supposed to be inferred from the tag attached to the master git branch ?

1 Like

Oops. The version field was absent from the .opam file ! Works better now :slight_smile: Sorry for that stupid mistake :frowning: and thanks for your help.

I’m glad it works now but I’m still wondering why it broke in the first place. What version of opam do you have? opam config report

$ opam config report
# opam config report
# opam-version         2.1.4 
# self-upgrade         no
# system               arch=arm64 os=macos os-distribution=homebrew os-version=12.6
# solver               builtin-mccs+glpk
# install-criteria     -removed,-count[avoid-version,changed],-count[version-lag,request],-count[version-lag,changed],-count[missing-depexts,changed],-changed
# upgrade-criteria     -removed,-count[avoid-version,changed],-count[version-lag,solution],-count[missing-depexts,changed],-new
# jobs                 4
# repositories         1 (http) (default repo at 0a297fc9)
# pinned               1 (git), 1 (rsync)
# current-switch       5.0.0
# ocaml:native         true
# ocaml:native-tools   true
# ocaml:native-dynlink true
# ocaml:stubsdir       /Users/jserot/.opam/5.0.0/lib/ocaml/stublibs:/Users/jserot/.opam/5.0.0/lib/ocaml
# ocaml:preinstalled   false
# ocaml:compiler       5.0.

Btw, i’m puzzled by why this field was missing. The .opam file is supposed to be automatically generated from the dune-project one, isn’t it ? But there’s no version field in the latter ??

It is just that, by lack of any precise information, Opam has assigned an arbitrary version to the package you just pinned, which makes the subsequent installation message confusing. (I have never encountered a case where this feature is actually useful. I would prefer if Opam were to assign a specific version to the pin, e.g., “unknown”, instead of a version conflicting with an already existing one.) You can force the version by using

opam pin add rfsm.2.0.0 "git+file://..."

Thanks for the explanation.
Another solution would be for opam to emit a warning in no explicit version can be found.

That sounds reasonable, could you open a ticket in the opam bugtracker?

Yes, will do that.

There must be sth weird here anyway.
When trying opam publish (after a, now sucessful, opam install .), i got strange error messages from the PR interface (Package rfsm.2.0 by jserot · Pull Request #24879 · ocaml/opam-repository · GitHub) : compilation seems to fail because of files which are not present in the source tree (nor in the GH .tar.gz release). I suspect, again, the CI scripts to use an old version…

Unfortunately the opam.ci.ocaml.org seems to be down this morning :confused: