The following are beyond the scope of the FAQ, but have been found useful for specific use-cases or for advanced users.
Simulate actions from the current switch state (for debugging)
opam upgrade --show-actions
(stop at the action summary dialog)opam upgrade --dry-run
(display only)- if you really want to try out the results:
opam switch export testing-state.export
opam switch create tmp-testing --empty
opam switch import testing-state.export --fake
- try actions with
--fake
(registers them in opam, but doesn't actually run the build/install commands) - revert to normal:
opam switch <previous>; opam switch remove tmp-testing
- Experiment with the solver:
opam <request> --cudf=cudf-file
- or
opam config cudf-universe >cudf-file-1.cudf
- run e.g. aspcud with
aspcud cudf-file-1.cudf /dev/stdout CRITERIA
Install in all switches
Not supported natively at the moment, but it's being considered. Quick hack:
for switch in $(opam switch list -s); do
opam install --switch $switch PACKAGE
done
You may want to add --yes
if you're confident.
Update opam environment within emacs
The best way is to use opam-user-setup
(just run opam user-setup install
),
and that will make the opam-update-env
interactive function available in
emacs.
You could also define the function by hand:
(defun opam-env ()
(interactive nil)
(dolist (var (car (read-from-string (shell-command-to-string "opam config env --sexp"))))
(setenv (car var) (cadr var))))
You may want to run this at emacs startup if it doesn't inherit the proper shell
environment. Be also careful that tuareg-mode
has its own bindings that
override the environment when using the compile
command, so that may get in
the way (see Tuareg issue #94).
Provide a set of packages for a group of users to install
The easiest way is to create a package with your prerequisites as depends
and
have them pin that. A quick way to host the file is to use a
Gist. Create one with minimal contents and listing
your packages as dependencies -- the file name has to be opam
:
opam-version: "2.0"
name: "ocaml101"
version: "0.1"
maintainer: "Louis Gesbert <louis.gesbert@ocamlpro.com>"
depends: [ "menhir" { = "20140422" }
"merlin" { >= "2" }
"ocp-indent"
"ocp-index" ]
Save that and get the HTTPS clone URL
. All that is needed then is to run:
$ opam pin <HTTPS clone URL>
Furthermore, opam update
will then pick up any modification you made to the gist.
These other options may offer more control, with a little more work, depending on the scale you work at:
- distribute an "export" file, as generated by
opam switch export <file>
- define and host your own repository, and use a specific
opamrc
file on the user's systems, to automatically select your repository and defaults onopam init
.
Alternate implementations for a package
opam currently doesn't support a provides:
field that would allow packages to
replace others. If you have two packages a
and b
providing foo
, you need
to:
Define a (virtual) package
foo
, withdepends: ["a" | "b"]
, for any version you want available: so if the versions ofa
,b
andfoo
match you would have e.g.foo.1
withdepends: ["a" {= "1"} | "b" {= "1"}]
. Or, better, using opam 2.0 variables:depends: ["a" {= _:version} | "b" {= _:version}]
, duplicated for any version desired.Make sure
a
andb
conflict with each other. The scalable solution for this is to use theconflict-class:
field: add e.g.conflict-class: "foo-implementation"
to all versions of botha
andb
.
The need to define the virtual package explicitly also ensures that a third
package can't inject a new implementation without that being visible in foo
:
it would otherwise be a security hole when we deploy end-to-end signing of
packages.
How to rename a package
Opam doesn't technically allow packages to be renamed, but you can create a
package with the new name, and a upgrade path between the two. Assuming you want
to rename foo
to bar
:
- Create a new version of
foo
, e.g.foo.transition
, depending onbar
, and with a description mentioning it is a virtual package that can be safely removed. The package shouldn't have a source URL or build, install, etc. instructions. - Create
bar
as a new package. - Add
conflicts: "foo" {!= "transition"}
. Remember to keep that field on any new version ofbar
.
This ensures at the same time that users upgrading will get the new package
bar
, and that the package can't be installed twice under the two names.
Display the current "opam switch" in the prompt ?
This can get quite handy if you have many switches you use in parallel.
You can use e.g. the command opam switch show --safe 2>/dev/null | sed
's|.*/|*|'
to return a (shortened) switch name.
For bash
, just include $(COMMAND)
in your definition of PS1
(making sure the $
is escaped).
For zsh
, use setopt prompt_subst
, and include $(COMMAND)
in the definition of prompt
.
How to install a maximum number of packages ?
The following sequence of commands tries to install as much packages as possible in a local switch with OCaml $(VERSION)
.
opam update
opam switch create . ocaml-base-compiler.$(VERSION)
export OPAMSOLVERTIMEOUT=3600
opam list --available -s | xargs opam install --best-effort --yes
# Be patient