- Tutorial context
- Use-case for
opam pin
- Dig into opam pin, find spicy features
- Conclusion
Opam 102: Pinning Packages
Welcome, dear reader, to a new opam blog post!
Today we take an additional step down the metaphorical rabbit hole with opam pin
, the easiest way to catch a ride on the development version of a package
in opam
.
We are aware that our readers are eager to see these blog posts venture on the
developer side of the opam
experience, and so are we, but we need to spend
just a bit little more time on the beginner and user-side of it for now so
please, bear with us! 🐻
This tutorial is the second one in this on-going series about the OCaml package manager
opam
. Be sure to read the first one to get up to speed. Also, check out each article'stags
to get an idea of the entry level required for the smoothest read possible!
New to the expansive OCaml sphere? As said on the official opam website,
opam
has been a game changer for the OCaml distribution, since it first saw the day of light here, almost a decade ago.
- Tutorial context
- Use-case for
opam pin
- Dig into opam pin, find spicy features
- Conclusion
Tutorial context and basis
As far as context goes for this article, we will consider that you already are familiar with the concepts introduced in our tutorial opam 101.
Your current environment should thus be somewhat similar to the one we had by
the end of that tutorial. Meaning: your version of opam
is a least 2.1.5
(all outputs were generated with this version), you have already launched opam init
, created a global switch my-switch
and, possibly, you have even
populated it with a few packages with a few calls to the opam install
command.
Furthermore, keep in mind that, in this blog post, we are approaching this subject from the perspective of a developer who is looking into integrating new packages to his current workload, not from the perspective of someone who is looking into sharing a project or publishing a new software.
opam pin
is a feature that will quickly become necessary for you to use as
you continue your exploration of opam
. It allows for the user to pin a
given package to a specific version, or even change the source from which said
package is pulled, installed, and synchronised with from within your currently
active switch
.
This feature shines the most in contexts such as:
- when doing ordinary
switch
management; - for incorporating external, still under-construction, libraries to your own current workload;
- when designing a specific
switch
: pinning a specific package version will make it the main compatibility constraint for that switch, thus tailoring the environment around it in the process.
Reminder
Remember that
opam
's command-line interface is beginner friendly. You can, at any point of your exploration, use the--help
option to have every command and subcommand explained. You may also check out the opam cheat-sheet that was released a while ago and still holds some precious insights on opam's CLI.
Use-case for opam pin
Now onto today's use-cases for opam pin
, the premise is as follows:
The package on which your current development depends on has just had a major
update on its development branch. This package is available on the opam repository
and its name is hc
.
That update introduced a new feature that you would very much like to experiment with for your own on-going project.
However, that feature is still very much a work-in-progress and the
maintainers of hc
are not about to release their package anytime soon...
That's when opam pin
comes in. In this article, we will cover two similar
use-cases for opam pin
, namely the one dealing with pinning a version of a
package that is already available on the opam repository
, and that of pinning
a version of an unreleased package, directly from its public URL.
After all the basics have been laid out, we will eventually cover some of the more underground ⛏ and dangerous 🔥 features available when pinning packages.
Important Notice
For the sake of convenience and brevity, we will breakdown the
opam pin
command, and some of its options, by only dealing with addresses that obey the classic definition of the word URL.However do keep in mind that
opam
uses a broader definition for that word, going as far as to consider a filesystem path to be a valid string for a URL argument, thus allowing allopam pin
calls and options to be valid when manipulatingopam
packages inside a local filesystem or local network instead of just on the web.
Pinning the dev version of a released package: opam pin add --dev-repo
Picking up from the base context: our project depends on hc
, and hc
has
just received an update. The first option available for us to access this fresh
update on the hc
repository is to use opam pin add --dev-repo <pkg>
command.
$ opam pin add --dev-repo hc
[hc.0.3] synchronised (git+https://git.zapashcanon.fr/zapashcanon/hc.git)
hc is now pinned to git+https://git.zapashcanon.fr/zapashcanon/hc.git (version 0.3)
The following actions will be performed:
∗ install dune 3.14.0 [required by hc]
∗ install hc 0.3*
===== ∗ 2 =====
Do you want to continue? [Y/n] y
<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><>
⬇ retrieved hc.0.3 (no changes)
⬇ retrieved dune.3.14.0 (https://opam.ocaml.org/cache)
∗ installed dune.3.14.0
∗ installed hc.0.3
Done.
So what exactly did opam pin
do here?
$ opam pin add --dev-repo hc
[hc.0.3] synchronised (git+https://git.zapashcanon.fr/zapashcanon/hc.git)
When you feed a package name to the opam pin add --dev-repo
command, it will
first retrieve the package definition found inside the opam file
in the directory of the corresponding package on the the Official OCaml opam
repository
or any other opam
repositories
that your local opam
installation happens to be synchronised
with.
You can inspect said package definition directly yourself with the opam show <pkg>
command.
Let's take a look at the package definition for hc
:
$ opam show hc
<><> hc: information on all versions ><><><><><><><><><><><><><><><><>
name hc
all-versions 0.0.1 0.2 0.3
<><> Version-specific details <><><><><><><><><><><><><><><><><><><><>
version 0.3
repository default
url.src "https://git.zapashcanon.fr/zapashcanon/hc/archive/0.3.tar.gz"
url.checksum
"sha256=61b443056adec3f71904c5775b8521b3ac8487df618a8dcea3f4b2c91bedc314"
"sha512=a1d213971230e9c7362749d20d1bec6f5e23af191522a65577db7c0f9123ea4c0fc678e5f768418d6dd88c1f3689a49cf564b5c744995a9db9a304f4b6d2c68a"
homepage "https://git.zapashcanon.fr/zapashcanon/hc"
doc "https://doc.zapashcanon.fr/hc/"
bug-reports "https://git.zapashcanon.fr/zapashcanon/hc/issues"
dev-repo "git+https://git.zapashcanon.fr/zapashcanon/hc.git"
authors "Léo Andrès <contact@ndrs.fr>"
maintainer "Léo Andrès <contact@ndrs.fr>"
license "ISC"
depends "dune" {>= "3.0"} "ocaml" {>= "4.14"} "odoc" {with-doc}
synopsis Hashconsing library
description hc is an OCaml library for hashconsing. It provides
easy ways to use hashconsing, in a type-safe and
modular way and the ability to get forgetful
memoïzation.
Here, you can see the dev-repo
field which contains the URL of the
development repository of that package. Opam will use that information to
retrieve package sources for you.
hc is now pinned to git+https://git.zapashcanon.fr/zapashcanon/hc.git (version 0.3)
Once it has retrieved hc
sources, opam will then store the status of the pin
internally, which is that hc
is git pinned to url
git.zapashcanon.fr/zapashcanon/hc
at version 0.3
.
$ opam pin list
hc.0.3 git git+https://git.zapashcanon.fr/zapashcanon/hc.git
Did you know? The default behaviour for
opam pin
is thelist
option. The option to see all pinned packages in the current active switch.On the other hand, the default behaviour for
opam pin <target>
command is theadd
option. Keep it in mind if you happen to grow tired of typingopam pin add <target>
every time.
Opam will then analyse hc
dependencies and compute a solution that respects
the dependencies constraints and state of your current switch (i.e. the
compatibility constraints between the packages currently installed in your
switch).
If it manages to do so, it will come forth with a prompt to install the pinned package and its dependencies.
The following actions will be performed:
∗ install dune 3.14.0 [required by hc]
∗ install hc 0.3*
===== ∗ 2 =====
Do you want to continue? [Y/n] y
Pressing Enter
or y + Enter
will perform the installation.
Notice that sometimes a
*
character is found next to some package actions? It's the shorthand signal that the package is pinned, you can get that information at a quick glance whenopam
outputs the actions to perform for you if you know what to look for.
<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><>
⬇ retrieved hc.0.3 (no changes)
⬇ retrieved dune.3.14.0 (https://opam.ocaml.org/cache)
∗ installed dune.3.14.0
∗ installed hc.0.3
Done.
Congratulations, you now have a pinned development version of the hc
package. You
can now start exploring the neat feature you have been looking forward to!
Pinning the dev version of an unreleased package: opam pin add <url>
Every once in a while on your OCaml journey, you will come across unreleased software.
These OCaml programs and libraries can still very much have active repositories
but their maintainers have not yet gone as far as to release them in order to
distribute their work through opam
to the rest of the OCaml ecosystem.
Yet, you might still want to have seamless access to these software solutions
on your local opam
installation for your own personal enjoyment and
developments. That's when opam pin add <url>
comes in handy.
Modern OCaml projects will most often have one or several opam files
in their
tree which opam
can operate with.
$ opam pin git+https://github.com/rjbou/opam-otopop
Package opam-otopop does not exist, create as a NEW package? [Y/n] y
opam-otopop is now pinned to git+https://github.com/rjbou/opam-otopop (version 0.1)
The following actions will be performed:
∗ install opam-client 2.0.10 [required by opam-otopop]
∗ install opam-otopop 0.1*
===== ∗ 2 =====
Do you want to continue? [Y/n] y
<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><>
⬇ retrieved opam-client.2.0.10 (https://opam.ocaml.org/cache)
∗ installed opam-client.2.0.10
∗ installed opam-otopop.0.1
Done.
As you can see, the course of an opam pin add <url>
call is very close to
that of an opam pin add --dev-repo <pkg>
, the only exception being the
following line:
Package opam-otopop does not exist, create as a NEW package? [Y/n] y
Since the package is unavailable on the opam repositories
that your opam
installation is synchronised with, opam
doesn't know about it.
That's why it will ask you if you want to create it as a NEW package
.
Once pinned, that package is available in your switch as any other ordinarily
available repository
package.
You can see here that opam
has pinned the opam-otopop
package to a specific
0.1
version.
opam-otopop is now pinned to git+https://github.com/rjbou/opam-otopop (version 0.1)
The reason for that is found inside the opam file
at
the root of the source repository for that package:
version: "0.1"
In any instance where this specific field is not found in the opam file
, the
version name would then be pinned to the verbatim ~dev
version.
Dig into opam pin, find spicy features
Add a pin without installing with --no-action
Here are the two main use-cases for a call to opam pin
with the --no-action
option:
- You don't want to install a package immediately, but do want to
inform
opam
of its existence to allowopam
to keep the compatibility constraints of that specific package in the equation whenever you are undertaking operations that would require such calculations; - You just want to be assured that your package will be synchronised with the right sources;
--no-action
will only perform the first actions of an opam pin
call and
will quit before installing the package, it can be used with all pin
subcommands.
$ opam pin add hc --dev-repo --no-action
[hc.0.3] synchronised (git+https://git.zapashcanon.fr/zapashcanon/hc.git)
hc is now pinned to git+https://git.zapashcanon.fr/zapashcanon/hc.git (version 0.3)
$
Update your pinned packages
There are two ways to go about updating and upgrading your pinned packages.
They are the same no matter if you used the --dev-repo
option, or <url>
argument, or any other method for pinning them.
The first one you may consider is to either install, or reinstall the specific
package(s). The reason is that opam
will always first synchronise with the
linked source, and then proceed to recompiling.
$ opam install opam-otopop
<><> Synchronising pinned packages ><><><><><><><><><><><><><><><><><><><><><><>
[opam-otopop.0.1] synchronised (git+https://github.com/rjbou/opam-otopop#master)
The following actions will be performed:
↻ recompile opam-otopop 0.1*
<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><><><>
⊘ removed opam-otopop.0.1
∗ installed opam-otopop.0.1
Done.
In the above code block, opam-otopop
has been upgraded by that opam install
call.
The second method is to use the specific opam update
and opam upgrade
mechanisms. These commands are very common in an opam
abiding workflow. Their
general usage was briefly mentioned in our article opam
101.
By default, opam update
updates the state of your opam repositories
, for
you to have access to the most recent version of your packages. If you add the
--development
flag to it, it will also update the source code of your pinned
packages internally.
$ opam update --development
<><> Synchronising development packages <><><><><><><><><><><><><><><><><><><><>
[opam-otopop.0.1] synchronised (git+https://github.com/rjbou/opam-otopop#master)
Now run 'opam upgrade' to apply any package updates.
Then you run upgrade
as you would in any other package upgrade scenario.
$ opam upgrade
The following actions will be performed:
↻ recompile opam-otopop 0.1* [upstream or system changes]
<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><><><>
⊘ removed opam-otopop.0.1
∗ installed opam-otopop.0.1
Done.
Unpin packages
When you are done with your experimentation and wish to remove a pinned
package, you can simply call the remove
subcommand.
Keep in mind that
opam unpin
is an alias foropam pin remove
.
The behaviour of opam unpin
is slightly different between released and
unreleased packages.
Released packages
If the pinned package is released, by default, opam
will retrieve and install
the released version of the package instead of removing that package
altogether.
$ opam pin list
hc.0.3 git git+https://git.zapashcanon.fr/zapashcanon/hc.git
$ opam list hc
# Packages matching: name-match(hc) & (installed | available)
# Package # Installed # Synopsis
hc.0.3 0.3 pinned to version 0.3 at git+https://git.zapashcanon.fr/zapashcanon/hc.git
$ opam pin remove hc
Ok, hc is no longer pinned to git+https://git.zapashcanon.fr/zapashcanon/hc.git (version 0.3)
The following actions will be performed:
↻ recompile hc 0.3
Do you want to continue? [Y/n] y
<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><><><>
⬇ retrieved hc.0.3 (https://opam.ocaml.org/cache)
⊘ removed hc.0.3
∗ installed hc.0.3
Done.
$ opam list hc
# Packages matching: name-match(hc) & (installed | available)
# Package # Installed # Synopsis
hc.0.3 0.3 Hashconsing library
As we can see in the details:
⬇ retrieved hc.0.3 (https://opam.ocaml.org/cache)
opam
has retrieved the sources from the archive that is specified in the
opam file
of the relevant opam repository
, thus pulling hc
back down to
its latest available, current-switch compatible, release.
Notice the absence of the
*
character next to the package action? It means the package is no longer pinned.
Unreleased packages
On the other hand, an unreleased package, since its only definition
source—meaning both the location of its source code as well as all
information required for opam
to operate, found in the corresponding opam file
—is the pin itself, opam
will have no other choice than to offer to
remove it for you.
$ opam pin list
opam-otopop.0.1 git git+https://github.com/rjbou/opam-otopop#master
In this case, opam unpin <package-name>
(or idempotently: opam pin remove <package-name>
) launches an opam remove
action:
$ opam pin remove opam-otopop
Ok, opam-otopop is no longer pinned to git+https://github.com/rjbou/opam-otopop#master (version 0.1)
The following actions will be performed:
⊘ remove opam-otopop 0.1
Do you want to continue? [Y/n] y
<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><><><>
⊘ removed opam-otopop.0.1
Done.
Unpin but do no action
Just like with the opam pin add
command, the --no-action
option is
available when removing pins. It will only unpin the package, without
removing it, or recompiling it.
$ opam pin remove opam-otopop --no-action
Ok, opam-otopop is no longer pinned to git+https://github.com/rjbou/opam-otopop#master (version 0.1)
$ opam list opam-otopop
# Packages matching: name-match(opam-otopop) & (installed | available)
# Package # Installed # Synopsis
opam-otopop.0.1 0.1 An opam-otopop package
You may use it for removing the pin
from a package while still keeping it
installed in your switch
, or replacing it by its opam repository
definition
version.
The resulting package remains linked to its URL, but it is not considered as pinned, so there will be no update or automatic syncing to follow the changes of the upstream branch.
You may also consider this feature to prepare a specific action, say, as a temporary state. For example, you could unpin several packages in a row, and then proceed to recompiling the whole batch in one go.
One URL to pin them all: handling a multi-package repository
Every example seen so far had but one opam file
at the root of their
respective work tree (sometimes in a specific opam/
directory).
Yet it is possible for some projects to have several packages distributed by a single repository. An example of this would be the opam project source repository itself. If that is the case, and you pin that URL, the default behaviour is that all the packages defined at that address will be pinned.
Let's take this project.
You can see that several packages are defined: ocp-index
and ocp-browser
.
Here's how a pin
action behaves when given that URL:
$ opam pin add git+https://github.com/OCamlPro/ocp-index
This will pin the following packages: ocp-browser, ocp-index.
Continue? [Y/n] y
ocp-browser is now pinned to git+https://github.com/OCamlPro/ocp-index (version 1.3.6)
ocp-index is now pinned to git+https://github.com/OCamlPro/ocp-index (version 1.3.6)
The following actions will be performed:
∗ install ocp-indent 1.8.1 [required by ocp-index]
∗ install ocp-index 1.3.6*
∗ install ocp-browser 1.3.6*
===== ∗ 3 =====
Do you want to continue? [Y/n] y
<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><>
⬇ retrieved ocp-indent.1.8.1 (https://opam.ocaml.org/cache)
∗ installed ocp-indent.1.8.1
∗ installed ocp-index.1.3.6
∗ installed ocp-browser.1.3.6
Done.
As you can see, this process is exactly the same as before, but with 3 packages in one go.
What if I do not want to pin every package in that repository?
Easy: if you just need one of the packages found at that URL, you can just feed
that package name to the opam pin add <package-name> <url>
CLI call, just
like we did at the beginning of this tutorial!
$ opam pin add ocp-index git+https://github.com/OCamlPro/ocp-index
[ocp-index.1.3.6] synchronised (git+https://github.com/OCamlPro/ocp-index)
ocp-index is now pinned to git+https://github.com/OCamlPro/ocp-index (version 1.3.6)
The following actions will be performed:
∗ install ocp-indent 1.8.1 [required by ocp-index]
∗ install ocp-index 1.3.6*
===== ∗ 2 =====
Do you want to continue? [Y/n] y
<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><>
⬇ retrieved ocp-indent.1.8.1 (cached)
∗ installed ocp-indent.1.8.1
∗ installed ocp-index.1.3.6
Done.
If you do not know the exact names of these different packages, you may also
consider using the very handy opam pin scan
command which will lookup the
contents repository at the URL and list its opam
packages for you:
$ opam pin scan git+https://github.com/OCamlPro/ocp-index
# Name # Version # Url
ocp-index 1.3.6 git+https://github.com/OCamlPro/ocp-index
ocp-browser 1.3.6 git+https://github.com/OCamlPro/ocp-index
Setting arbitrary version numbers, toying with fire
As demonstrated earlier, opam
will choose a version of the
pinned package according to the contents of the opam file
.
The important thing to take away from that is, in most usual scenarios, the
contents of the opam file
are paramount to how opam
will calculate
compatibility constraints in a given switch
.
It is from the information that is hardcoded inside the opam file
that opam
will be able to take educated decisions whenever changes to the
state of your current switch
are to be made. There is a way, however, to
circumvent that behaviour, that we want to inform you of, even if it entails a
bit of precaution.
Naturally, directly tinkering with such a key stability feature like
compatibility constraints solving
does require you to tread carefully. We will see together some of the pitfalls and things to do that will keep you from finding yourself in confusing situations in regards to the state of yourswitch
and the dependencies within it.
Ready? Lets get acquainted with our first slightly dangerous opam
feature:
You are allowed to append an arbitrary version number to the name of the
pinned package for opam
to incorporate in its calculations, as seen in the
following code block:
$ opam pin add directories.1.0 git+https://github.com/ocamlpro/directories --no-action
[directories.1.0] synchronised (git+https://github.com/ocamlpro/directories)
directories is now pinned to git+https://github.com/ocamlpro/directories (version 1.0)
In this specific example, package
directories
is available in the opam
repository
, that our opam
installation is synchronised with. However, there is no such 1.0
version in
that repository
. Not a single reference to such a version number can be found
at that address, neither in the tags
, nor releases
of the repository, and
not even in the opam file
.
$ opam show directories --field all-versions
0.1 0.2 0.3 0.4 0.5
What we have done here is effectively telling opam
that directories
is at
a different version number than it actually is in the most purely technical
aspect...
But why would we want to do such a thing?
Let's consider a reasonable use-case for opam pin add <package>.<my-version-number> <url>
:
You have been working on a project called my-project
for some time and you
are using a package named fst-dep
for your development.
Below, you will find an excerpt of the fst-dep.opam
file, specifically its
dependencies:
depends: [
"dep-to-try" { <= "3.0.0" }
"other-dep"
]
All three packages (fst-dep
,dep-to-try
and other-dep
) are
installed in your current switch and are available on your favourite opam
repository
.
One day you go about checking the repository for each dependency, and you find
that dep-to-try
has just had one of its main features reimplemented,
improved and optimised, they are preparing to release a 4.0.0
version soon.
See, these changes would have been available for you to fetch directly from
it's development repository had you been working with it directly, but you
are not. It is up to the maintainers of fst-dep
to do that work.
Since you have no ownership over any of these dependencies. You have no way of
changing any of the version constraints in this tiny dependency tree that
ranges from fst-dep
and upwards.
Here are the three mainstream solutions to this problem:
- Wait for both packages to publish new releases. A new official release from
the
dep-to-try
team, which would ship said reimplementation, and another from thefst-dep
team which would update its dependency tree to includedep-to-try
's latest version. Needless to say that this could take an arbitrary amount of time which is unsatisfying at best. - Another suboptimal solution would be to copy the current state of the
entire opam
repository
relevant to your package distribution, go to the corresponding directory forfst-dep
inside thatrepository
, relax the hard dependency"dep-to-try" { <= "3.0.0" }
and reinstall all the packages that are directly or indirectly affected by that change. A very time consuming task for such a small edit to the global dependency tree. - Last option would be to pin
fst-dep
, then go about manually editing the dependencies offst-dep
with theopam pin --edit
option to relax the dependency. The only pitfall with this solution is that, in a context wheredep-to-try
is a key package in the OCaml distribution, and many other packages depend on it as well, you might have to do a lot of editing to make yourswitch
a stable environment with all dependency constraints met...
So neither of these solutions fit our needs. They are all unsatisfactory at best and even counter-productive at worst.
That's when arbitrary version pinning
shines.
The main benefit of this feature is that it allows for added flexibility in
navigating and tweaking the compatibility tree of any opam repository
at the
switch
-level. It provides the user with ways to circumvent all tasks
pertaining to a larger operation on the global graph of packages.
$ opam pin dep-to-try.3.0.0 git+https://github.com/OCamlPro/dep-to-try
[dep-to-try.3.0.0] synchronised (file:///home/rjbou/ocamlpro/opam_bps_examples/dep-to-try)
dep-to-try is now pinned to git+https://github.com/OCamlPro/dep-to-try#master (version 3.0.0)
opam
will still think that dep-to-try
's version is valid ({ <= "3.0.0"}
),
even if you are synchronised with the state of its development branch, thus giving
you access to the latest changes with the minimal amount of manual editing
required. Pretty neat, right?
Now, onto the pitfalls that you should keep in mind when tinkering with your dependencies like that.
What kind of predicament awaits you?
- You could introduce unforeseen behaviours. This could be anything from
errors at compile-time, if
dep-to-try
's interfaces have changed significantly, to runtime crashes if you're unlucky. - Another source of confusion could arise if you happen to use the
opam unpin dep-to-try --no-action
command on such a package. After unpinning it, there's a chance that you would later forget it used to be pinned to a development version. There would be little to no way for you to remember which package it was that you had experimented with at some point. You would either have to inspect all you installed packages or even remake aswitch
from scratch which would not be affected by your recklessarbitrary version pinning
and would work just fine after that.
Our advice is rather simple: use this feature with discretion and try to avoid unpinning packages if it's not to reinstall or remove them altogether. If you follow these instructions, you should be safe...
Setting multiple arbitrary version numbers
One last bit of black magic for you to play around with.
Instead of pinning package-name.my-version-number
, you may use the
--with-version
option to pin packages at that URL to an arbitrary version. A
key detail is that it is compatible with multiple opam file pinning... Just
keep in mind that all the pitfalls mentioned previously apply here too, only
with multiple packages at once, which could make it more confusing.
Below, you can see that we are setting all the packages found in that repository to the same version:
$ opam pin add git+https://github.com/OCamlPro/ocp-index --with-version 2.0.0
This will pin the following packages: ocp-browser, ocp-index.
Continue? [Y/n] y
ocp-browser is now pinned to git+https://github.com/OCamlPro/ocp-index (version 2.0.0)
ocp-index is now pinned to git+https://github.com/OCamlPro/ocp-index (version 2.0.0)
The following actions will be performed:
∗ install ocp-indent 1.8.1 [required by ocp-index]
∗ install ocp-index 2.0.0*
∗ install ocp-browser 2.0.0*
===== ∗ 3 =====
Do you want to continue? [Y/n] y
<><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><>
⬇ retrieved ocp-indent.1.8.1 (cached)
⬇ retrieved ocp-index.2.0.0 (no changes)
⬇ retrieved ocp-browser.2.0.0 (no changes)
∗ installed ocp-indent.1.8.1
∗ installed ocp-index.2.0.0
∗ installed ocp-browser.2.0.0
Done.
You can see that all these packages are pinned to 2.0.0
now.
$ opam pin list
ocp-browser.2.0.0 git git+https://github.com/OCamlPro/ocp-index
ocp-index.2.0.0 git git+https://github.com/OCamlPro/ocp-index
Conclusion
Here it is, the opam pin
command in most of its glory.
If you have managed to stick this long to read this article, you should no
longer feel confused about pinning projects and should now have another of
opam
's most commonly used feature in your arsenal when tackling your own
development challenges!
So it is that we have learned about pinning both released and unreleased
packages. Additionally, we showcased several features for orthogonal use-cases:
from the more quality of life-oriented calls such as opam show
and opam pin scan
, to obscure features like arbitrary version pinning as well as
ordinary options like --no-action
, --dev-repo
and subcommands like opam unpin
.
We are steadily approaching a level of familiarity with opam
that will
allow us to get into some really neat features soon.
Be sure to stay tuned with our blog, the journey into the rabbit hole has only
started and opam
is a deep one indeed!
Thank you for reading,
From 2011, with love,
The OCamlPro Team
About OCamlPro:
OCamlPro is a R&D lab founded in 2011, with the mission to help industrial users benefit from experts with a state-of-the-art knowledge of programming languages theory and practice.
- We provide audit, support, custom developer tools and training for both the most modern languages, such as Rust, Wasm and OCaml, and for legacy languages, such as COBOL or even home-made domain-specific languages;
- We design, create and implement software with great added-value for our clients. High complexity is not a problem for our PhD-level experts. For example, we helped the French Income Tax Administration re-adapt and improve their internally kept M language, we designed a DSL to model and express revenue streams in the Cinema Industry, codename Niagara, and we also developed the prototype of the Tezos proof-of-stake blockchain from 2014 to 2018.
- We have a long history of creating open-source projects, such as the Opam package manager, the LearnOCaml web platform, and contributing to other ones, such as the Flambda optimizing compiler, or the GnuCOBOL compiler.
- We are also experts of Formal Methods, developing tools such as our SMT Solver Alt-Ergo (check our Alt-Ergo Users' Club) and using them to prove safety or security properties of programs.
Please reach out, we'll be delighted to discuss your challenges: contact@ocamlpro.com or book a quick discussion.
Most Recent Articles
2024
- Optimisation de Geneweb, 1er logiciel français de Généalogie depuis près de 30 ans
- Alt-Ergo 2.6 is Out!
- Flambda2 Ep. 3: Speculative Inlining
- opam 2.2.0 release!
- Flambda2 Ep. 2: Loopifying Tail-Recursive Functions
- Fixing and Optimizing the GnuCOBOL Preprocessor
- OCaml Backtraces on Uncaught Exceptions
- Opam 102: Pinning Packages
- Flambda2 Ep. 1: Foundational Design Decisions
- Behind the Scenes of the OCaml Optimising Compiler Flambda2: Introduction and Roadmap
- Lean 4: When Sound Programs become a Choice
- Opam 101: The First Steps
2023
- Maturing Learn-OCaml to version 1.0: Gateway to the OCaml World
- The latest release of Alt-Ergo version 2.5.1 is out, with improved SMT-LIB and bitvector support!
- 2022 at OCamlPro
- Autofonce, GNU Autotests Revisited
- Sub-single-instruction Peano to machine integer conversion
- Statically guaranteeing security properties on Java bytecode: Paper presentation at VMCAI 23
- Release of ocplib-simplex, version 0.5
- The Growth of the OCaml Distribution