> The following are beyond the scope of the [FAQ](FAQ.html), 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:
```lisp
(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](https://github.com/ocaml/tuareg/issues/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](https://gist.github.com). 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:

```shell
$ 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`](Manual.html#opamrc) file on the user's systems, to automatically
  select your repository and defaults on `opam 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`, with `depends: ["a" | "b"]`, for any version
  you want available: so if the versions of `a`, `b` and `foo` match you would
  have _e.g._ `foo.1` with `depends: ["a" {= "1"} | "b" {= "1"}]`. Or, better,
  using opam 2.0 variables: `depends: ["a" {= _:version} | "b" {= _:version}]`,
  duplicated for any version desired.

- Make sure `a` and `b` conflict with each other. The scalable solution for this
  is to use the `conflict-class:` field: add _e.g._ `conflict-class:
  "foo-implementation"` to all versions of both `a` and `b`.

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`:

1. Create a new version of `foo`, e.g. `foo.transition`, depending on `bar`, 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.
2. Create `bar` as a new package.
3. Add `conflicts: "foo" {!= "transition"}`. Remember to keep that field on any
   new version of `bar`.

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)`.

```shell
opam update
opam switch create . ocaml-base-compiler.$(VERSION)
export OPAMSOLVERTIMEOUT=3600
opam list --available -s | xargs opam install --best-effort --yes
# Be patient
```
