OCaml Changelog

RSS

Read the latest releases and updates from the OCaml ecosystem.

UPDATE (2017-02-14): A beta2 is online, which fixes issues and performance of the opam build command. Get the new binaries, or recompile the opam-devel package and replace the previous binary.

We are pleased to announce that the beta release of opam 2.0 is now live! You can try it already, bootstrapping from a working 1.2 opam installation, with:

opam update; opam install opam-devel

With about a thousand patches since the last stable release, we took the time to gather feedback after our last announcement and implemented a couple of additional, most-wanted features:

  • An opam build command that, from the root of a source tree containing one or more package definitions, can automatically handle initialisation and building of the sources in a local switch.
  • Support for repository signing through the external Conex tool, being developed in parallel.

There are many more features, like the new opam clean and opam admin commands, a new archive caching system, etc., but we'll let you check the full changelog.

We also improved still on the already announced features, including compilers as packages, local switches, per-switch repository configuration, package file tracking, etc.

The updated documentation is at https://opam.ocaml.org/doc/2.0/. If you are developing in opam-related tools, you may also want to browse the new APIs.

Try it out

Please try out the beta, and report any issues or missing features. You can:

  • Build it from source in opam, as shown above (opam install opam-devel)
  • Use the pre-built binaries.
  • Building from the source tarball: download here and build using ./configure && make lib-ext && make if you have OCaml >= 4.01 already available; make cold otherwise
  • Or directly from the git tree, following the instructions included in the README. Some files have been moved around, so if your build fails after you updated an existing git clone, try to clean it up (git clean -dx).

Some users have been using the alpha for the past months without problems, but you may want to keep your opam 1.2 installation intact until the release is out. An easy way to do this is with an alias:

alias opam2="OPAMROOT=~/.opam2 path/to/opam-2-binary"

Changes to be aware of

Command-line interface

  • opam switch create is now needed to create new switches, and opam switch is now much more expressive
  • opam list is also much more expressive, but be aware that the output may have changed if you used it in scripts
  • new commands:
    • opam build: setup and build a local source tree
    • opam clean: various cleanup operations (wiping caches, etc.)
    • opam admin: manage software repositories, including upgrading them to opam 2.0 format (replaces the opam-admin tool)
    • opam env, opam exec, opam var: shortcuts for the opam config subcommands
  • opam repository add will now setup the new repository for the current switch only, unless you specify --all
  • Some flags, like --test, now apply to the packages listed on the command-line only. For example, opam install lwt --test will build and install lwt and all its dependencies, but only build/run the tests of the lwt package. Test-dependencies of its dependencies are also ignored
  • The new opam install --soft-request is useful for batch runs, it will maximise the installed packages among the requested ones, but won't fail if all can't be installed

As before, opam is self-documenting, so be sure to check opam COMMAND --help first when in doubt. The bash completion scripts have also been thoroughly improved, and may help navigating the new options.

Metadata

There are both a few changes (extensions, mostly) to the package description format, and more drastic changes to the repository format, mainly related to translating the old compiler definitions into packages.

  • opam will automatically update, internally, definitions of pinned packages as well as repositories in the 1.2 format
  • however, it is faster to use repositories in the 2.0 format directly. To that end, please use the opam admin upgrade command on your repositories. The --mirror option will create a 2.0 mirror and put in place proper redirections, allowing your original repository to retain the old format

The official opam repository at https://opam.ocaml.org remains in 1.2 format for now, but has a live-updated 2.0 mirror to which you should be automatically redirected. It cannot yet accept package definitions in 2.0 format.

Package format

  • Any available: constraints based on the OCaml compiler version should be rewritten into dependencies to the ocaml package
  • Separate build: and install: instructions are now required
  • It is now preferred to include the old url and descr files (containing the archive URL and package description) in the opam file itself: (see the new synopsis: and description: fields, and the url {} file section)
  • Building tests and documentation should now be part of the main build: instructions, using the {test} and {doc} filters. The build-test: and build-doc: fields are still supported.
  • It is now possible to use opam variables within dependencies, for example depends: [ "foo" {= version} ], for a dependency to package foo at the same version as the package being defined, or depends: [ "bar" {os = "linux"} ] for a dependency that only applies on Linux.
  • The new conflict-class: field allows mutual conflicts among a set of packages to be declared. Useful, for example, when there are many concurrent, incompatible implementations.
  • The ocaml-version: field has been deprecated for a long time and is no longer accepted. This should now be a dependency on the ocaml package
  • Three types of checksums are now accepted: you should use md5=<hex-value>, sha256=<hex-value> or sha512=<hex-value>. We'll be gradually deprecating md5 in favour of the more secure algorithms; multiple checksums are allowed
  • Patches supplied in the patches: field must apply with patch -p1
  • The new setenv: field allows packages to export updates to environment variables;
  • Custom fields x-foo: can be used for extensions and external tools
  • """ delimiters allow unescaped strings
  • & has now the customary higher precedence than | in formulas
  • Installed files are now automatically tracked meaning that the remove: field is usually no longer required.

The full, up-to-date specification of the format can be browsed in the manual.

Repository format

In the official, default repository, and also when migrating repositories from older format versions, there are:

  • A virtual ocaml package, that depends on any implementation of the OCaml compiler. This is what packages should depend on, and the version is the corresponding base OCaml version (e.g. 4.04.0 for the 4.04.0+fp compiler). It also defines various configuration variables, see opam config list ocaml.
  • Three mutually-exclusive packages providing actual implementations of the OCaml toolchain:
    • ocaml-base-compiler is the official releases
    • ocaml-variants.<base-version>+<variant-name> contains all the other variants
    • ocaml-system-compiler maps to a compiler installed on the system outside of opam

The layout is otherwise the same, apart from:

  • The compilers/ directory is ignored
  • A repo file should be present, containing at least the line opam-version: "2.0"
  • The indexes for serving over HTTP have been simplified, and urls.txt is no longer needed. See opam admin index --help
  • The archives/ directory is no longer used. The cache now uses a different format and is configured through the repo file, defaulting to cache/ on the same server. See opam admin cache --help

Feedback

Thanks for trying out the beta! Please let us have feedback, preferably to the opam tracker; other options include the opam-devel list and #opam IRC channel on Freenode.

opam-lib 1.3

The package for opam-lib version 1.3 has just been released in the official opam repository. There is no release of opam with version 1.3, but this is an intermediate version of the library that retains compatibility of the file formats with 1.2.2.

The purpose of this release is twofold:

  • provide some fixes and enhancements over opam-lib 1.2.2. For example, 1.3 has an enhanced lint function
  • be a step towards migration to opam-lib 2.0.

This version is compatible with the current stable release of opam (1.2.2), but dependencies have been updated so that you are not (e.g.) stuck on an old version of ocamlgraph.

Therefore, I encourage all maintainers of tools based on opam-lib to migrate to 1.3.

The respective APIs are available in HTML for 1.2 and 1.3.

A note on plugins: when you write opam-related tools, remember that by setting flags: plugin in their definition and installing a binary named opam-toolname, you will enable the users to install package toolname and run your tool with a single opam toolname command.

Architectural changes

If you need to migrate from 1.2 to 1.3, these tips may help:

  • there are now 6 different ocamlfind sub-libraries instead of just 4: format contains the handlers for opam types and file formats, has been split out from the core library, while state handles the state of a given opam root and switch and has been split from the client library.

  • OpamMisc is gone and moved into the better organised OpamStd, with submodules for String, List, etc.

  • OpamGlobals is gone too, and its contents have been moved to:

    • OpamConsole for the printing, logging, and shell interface handling part
    • OpamXxxConfig modules for each of the libraries for handling the global configuration variables. You should call the respective init functions, with the options you want to set, for proper initialisation of the lib options (and handling the OPAMXXX environment variables)
  • OpamPath.Repository is now OpamRepositoryPath, and part of the repository sub-library.

opam-lib 2.0 ?

The development version of the opam-lib (2.0~alpha5 as of writing) is already available on opam. The name has been changed to provide a finer granularity, so it can actually be installed concurrently -- but be careful not to confuse the ocamlfind package names (opam-lib.format for 1.3 vs opam-format for 2.0).

The provided packages are:

  • opam-file-format: now separated from the opam source tree, this has no dependencies and can be used to parse and print the raw opam syntax.
  • opam-core: the basic toolbox used by opam, which actually doesn't include the opam specific part. Includes a tiny extra stdlib, the engine for running a graph of processes in parallel, some system handling functions, etc. Depends on ocamlgraph and re only.
  • opam-format: defines opam data types and their file i/o functions. Depends just on the two above.
  • opam-solver: opam's interface with the dose3 library and external solvers.
  • opam-repository: fetching repositories and package sources from all handled remote types.
  • opam-state: handling of the opam states, at the global, repository and switch levels.
  • opam-client: the client library, providing the top-level operations (installing packages...), and CLI.
  • opam-devel: this packages the development version of the opam tool itself, for bootstrapping. You can install it safely as it doesn't install the new opam in the PATH.

The new API can be also be browsed ; please get in touch if you have trouble migrating.

We are pleased to announce a preview release for opam 2.0, with over 700 patches since 1.2.2. Version 2.0~alpha4 has just been released, and is ready to be more widely tested.

This version brings many new features and changes, the most notable one being that OCaml compiler packages are no longer special entities, and are replaced by standard package definition files. This in turn means that opam users have more flexibility in how switches are managed, including for managing non-OCaml environments such as Coq using the same familiar tools.

A Few Highlights

This is just a sample, see the full changelog for more:

  • Sandboxed builds: Command wrappers can be configured to, for example, restrict permissions of the build and install processes using Linux namespaces, or run the builds within Docker containers.

  • Compilers as packages: This brings many advantages for opam workflows, such as being able to upgrade the compiler in a given switch, better tooling for local compilers, and the possibility to define coq as a compiler or even use opam as a generic shell scripting engine with dependency tracking.

  • Local switches: Create switches within your projects for easier management. Simply run opam switch create <directory> <compiler> to get started.

  • Inplace build: Use opam to build directly from your source directory. Ensure the package is pinned locally then run opam install --inplace-build.

  • Automatic file tracking:: opam now tracks the files installed by packages and is able to cleanly remove them when no existing files were modified. The remove: field is now optional as a result.

  • Configuration file: This can be used to direct choices at opam init automatically (e.g. specific repositories, wrappers, variables, fetch commands, or the external solver). This can be used to override all of opam's OCaml-related settings.

  • Simpler library: the OCaml API is completely rewritten and should make it much easier to write external tools and plugins. Existing tools will need to be ported.

  • Better error mitigation: Through clever ordering of the shell actions and separation of build and install, most build failures can keep your current installation intact, not resulting in removed packages anymore.

Roll out

You are very welcome to try out the alpha, and report any issues. The repository at opam.ocaml.org will remain in 1.2 format (with a 2.0 mirror at opam.ocaml.org/2.0~dev in sync) until after the release is out, which means the extensions can not be used there yet, but you are welcome to test on local or custom repositories, or package pinnings. The reverse translation (2.0 to 1.2) is planned, to keep supporting 1.2 installations after that date.

The documentation for the new version is available at https://opam.ocaml.org/doc/2.0/. This is still work in progress, so please do ask if anything is unclear.

Interface changes

Commands opam switch and opam list have been rehauled for more consistency and flexibility: the former won't implicitly create new switches unless called with the create subcommand, and opam list now allows to combine filters and finely specify the output format. They may not be fully backwards compatible, so please check your scripts.

Most other commands have also seen fixes or improvements. For example, opam doesn't forget about your set of installed packages on the first error, and the new opam install --restore can be used to reinstall your selection after a failed upgrade.

Repository changes

While users of opam 1.2 should feel at home with the changes, the 2.0 repository and package formats are not compatible. Indeed, the move of the compilers to standard packages implies some conversions, and updates to the relationships between packages and their compiler. For example, package constraints like

available: [ ocaml-version >= "4.02" ]

are now written as normal package dependencies:

depends: [ "ocaml" {>= "4.02"} ]

To make the transition easier,

  • upgrade of a custom repository is simply a matter of running opam-admin upgrade-format at its root;
  • the official repository at opam.ocaml.org already has a 2.0 mirror, to which you will be automatically redirected;
  • packages definition are automatically converted when you pin a package.

Note that the ocaml package on the official repository is actually a wrapper that depends on one of ocaml-base-compiler, ocaml-system or ocaml-variants, which contain the different flavours of the actual compiler. It is expected that it may only get picked up when requested by package dependencies.

Package format changes

The opam package definition format is very similar to before, but there are quite a few extensions and some changes:

  • it is now mandatory to separate the build: and install: steps (this allows tracking of installed files, better error recovery, and some optional security features);
  • the url and description can now optionally be included in the opam file using the section url {} and fields synopsis: and description:;
  • it is now possible to have dependencies toggled by globally-defined opam variables (e.g. for a dependency needed on some OS only), or even rely on the package information (e.g. have a dependency at the same version);
  • the new setenv: field allows packages to export updates to environment variables;
  • custom fields x-foo: can be used for extensions and external tools;
  • allow """ delimiters around unescaped strings
  • & is now parsed with higher priority than |
  • field ocaml-version: can no longer be used
  • the remove: field should not be used anymore for simple cases (just removing files)

Let's go then -- how to try it ?

First, be aware that you'll be prompted to update your ~/.opam to 2.0 format before anything else, so if you value it, make a backup. Or just export OPAMROOT to test the alpha on a temporary opam root.

Packages for opam 2.0 are already in the opam repository, so if you have a working opam installation of opam (at least 1.2.1), you can bootstrap as easily as:

opam install opam-devel

This doesn't install the new opam to your PATH within the current opam root for obvious reasons, so you can manually install it as e.g. "opam2" using:

sudo cp $(opam config var "opam-devel:lib")/opam /usr/local/bin/opam2

You can otherwise install as usual:

  • Using pre-built binaries (available for OSX and Linux x86, x86_64, armhf) and our install script:

    wget https://raw.github.com/ocaml/opam/2.0-alpha4-devel/shell/opam_installer.sh -O - | sh -s /usr/local/bin

    Equivalently, pick your version and download it to your PATH;

  • Building from our inclusive source tarball: download here and build using ./configure && make lib-ext && make && make install if you have OCaml >= 4.01 already available, make cold && make install otherwise;

  • Or from source, following the included instructions from the README. Some files have been moved around, so if your build fails after you updated an existing git clone, try to clean it up (git clean -fdx).

OPAM 1.2.2 has just been released. This fixes a few issues over 1.2.1 and brings a couple of improvements, in particular better use of the solver to keep the installation as up-to-date as possible even when the latest version of a package can not be installed.

Upgrade from 1.2.1 (or earlier)

See the normal installation instructions: you should generally pick up the packages from the same origin as you did for the last version -- possibly switching from the official repository packages to the ones we provide for your distribution, in case the former are lagging behind.

There are no changes in repository format, and you can roll back to earlier versions in the 1.2 branch if needed.

Improvements

  • Conflict messages now report the original version constraints without translation, and they have been made more concise in some cases
  • Some new opam lint checks, opam lint now numbers its warnings and may provide script-friendly output
  • Feature to automatically install plugins, e.g. opam depext will prompt to install depext if available and not already installed
  • Priority to newer versions even when the latest can't be installed (with a recent solver only. Before, all non-latest versions were equivalent to the solver)
  • Added opam list --resolve to list a consistent installation scenario
  • Be cool by default on errors in OPAM files, these don't concern end-users and packagers and CI now have opam lint to check them.

Fixes

  • OSX: state cache got broken in 1.2.1, which could induce longer startup times. This is now fixed
  • opam config report has been fixed to report the external solver properly
  • --dry-run --verbose properly outputs all commands that would be run again
  • Providing a simple path to an aspcud executable as external solver (through options or environment) works again, for backwards-compatibility
  • Fixed a fd leak on solver calls (thanks Ivan Gotovchits)
  • opam list now returns 0 when no packages match but no pattern was supplied, which is more helpful in scripts relying on it to check dependencies.

OPAM 1.2.1 has just been released. This patch version brings a number of fixes and improvements over 1.2.0, without breaking compatibility.

Upgrade from 1.2.0 (or earlier)

See the normal installation instructions: you should generally pick up the packages from the same origin as you did for the last version -- possibly switching from the official repository packages to the ones we provide for your distribution, in case the former are lagging behind.

What's new

No huge new features in this point release -- which means you can roll back to 1.2.0 in case of problems -- but lots going on under the hood, and quite a few visible changes nonetheless:

  • The engine that processes package builds and other commands in parallel has been rewritten. You'll notice the cool new display but it's also much more reliable and efficient. Make sure to set jobs: to a value greater than 1 in ~/.opam/config in case you updated from an older version.
  • The install/upgrade/downgrade/remove/reinstall actions are also processed in a better way: the consequences of a failed actions are minimised, when it used to abort the full command.
  • When using version control to pin a package to a local directory without specifying a branch, only the tracked files are used by OPAM, but their changes don't need to be checked in. This was found to be the most convenient compromise.
  • Sources used for several OPAM packages may use <name>.opam files for package pinning. URLs of the form git+ssh:// or hg+https:// are now allowed.
  • opam lint has been vastly improved.

... and much more

There is also a new manual documenting the file and repository formats.

Fixes

See the changelog for a summary or closed issues in the bug-tracker for an overview.

Experimental features

These are mostly improvements to the file formats. You are welcome to use them, but they won't be accepted into the official repository until the next release.

  • New field features: in opam files, to help with ./configure scripts and documenting the specific features enabled in a given build. See the original proposal and the section in the new manual
  • The "filter" language in opam files is now well defined, and documented in the manual. In particular, undefined variables are consistently handled, as well as conversions between string and boolean values, with new syntax for converting bools to strings.
  • New package flag "verbose" in opam files, that outputs the package's build script to stdout
  • New field libexec: in <name>.install files, to install into the package's lib dir with the execution bit set.
  • Compilers can now be defined without source nor build instructions, and the base packages defined in the packages: field are now resolved and then locked. In practice, this means that repository maintainers can move the compiler itself to a package, giving a lot more flexibility.

We are very proud to announce the availability of OPAM 1.2.0.

Upgrade from 1.1

Simply follow the usual instructions, using your preferred method (package from your distribution, binary, source, etc.) as documented on the homepage.

NOTE: There are small changes to the internal repository format (~/.opam). It will be transparently updated on first run, but in case you might want to go back and have anything precious there, you're advised to back it up.

Usability

Lot of work has been put into providing a cleaner interface, with helpful behaviour and messages in case of errors.

The documentation pages also have been largely rewritten for consistency and clarity.

New features

This is just the top of the list:

  • A extended and versatile opam pin command. See the Simplified packaging workflow
  • More expressive queries, see for example opam source
  • New metadata fields, including source repositories, bug-trackers, and finer control of package behaviour
  • An opam lint command to check the quality of packages

For more detail, see the announcement for the beta, the full changelog, and the bug-tracker.

Package format

The package format has been extended to the benefit of both packagers and users. The repository already accepts packages in the 1.2 format, and this won't affect 1.1 users as a rewrite is done on the server for compatibility with 1.1.

If you are hosting a repository, you may be interested in these administration scripts to quickly take advantage of the new features or retain compatibility.

Most package managers support some pin functionality to ensure that a given package remains at a particular version without being upgraded. The stable OPAM 1.1 already supported this by allowing any existing package to be pinned to a target, which could be a specific released version, a local filesystem path, or a remote version-controlled repository.

However, the OPAM 1.1 pinning workflow only lets you pin packages that already exist in your OPAM repositories. To declare a new package, you had to go through creating a local repository, registering it in OPAM, and adding your package definition there. That workflow, while reasonably clear, required the user to know about the repository format and the configuration of an internal repository in OPAM before actually getting to writing a package. Besides, you were on your own for writing the package definition, and the edit-test loop wasn't as friendly as it could have been.

A natural, simpler workflow emerged from allowing users to pin new package names that don't yet exist in an OPAM repository:

  1. choose a name for your new package
  2. opam pin add in the development source tree
  3. the package is created on-the-fly and registered locally.

To make it even easier, OPAM can now interactively help you write the package definition, and you can test your updates with a single command. This blog post explains this new OPAM 1.2 functionality in more detail; you may also want to check out the new Packaging tutorial relying on this workflow.

From source to package

For illustration purposes in this post I'll use a tiny tool that I wrote some time ago and never released: ocp-reloc. It's a simple binary that fixes up the headers of OCaml bytecode files to make them relocatable, which I'd like to release into the public OPAM repository.

"opam pin add"

The command opam pin add <name> <target> pins package <name> to <target>. We're interested in pinning the ocp-reloc package name to the project's source directory.

cd ocp-reloc
opam pin add ocp-reloc .

If ocp-reloc were an existing package, the metadata would be fetched from the package description in the OPAM repositories. Since the package doesn't yet exist, OPAM 1.2 will instead prompt for on-the-fly creation:

Package ocp-reloc does not exist, create as a NEW package ? [Y/n] y
ocp-reloc is now path-pinned to ~/src/ocp-reloc

NOTE: if you are using beta4, you may get a version-control-pin instead, because we added auto-detection of version-controlled repos. This turned out to be confusing (issue #1582), because your changes wouldn't be reflected until you commit, so this has been reverted in favor of a warning. Add the --kind path option to make sure that you get a path-pin.

OPAM Package Template

Now your package still needs some kind of definition for OPAM to acknowledge it; that's where templates kick in, the above triggering an editor with a pre-filled opam file that you just have to complete. This not only saves time in looking up the documentation, it also helps getting consistent package definitions, reduces errors, and promotes filling in optional but recommended fields (homepage, etc.).

opam-version: "1.2"
name: "ocp-reloc"
version: "0.1"
maintainer: "Louis Gesbert <louis.gesbert@ocamlpro.com>"
authors: "Louis Gesbert <louis.gesbert@ocamlpro.com>"
homepage: ""
bug-reports: ""
license: ""
build: [
  ["./configure" "--prefix=%{prefix}%"]
  [make]
]
install: [make "install"]
remove: ["ocamlfind" "remove" "ocp-reloc"]
depends: "ocamlfind" {build}

After adding some details (most importantly the dependencies and build instructions), I can just save and exit. Much like other system tools such as visudo, it checks for syntax errors immediately:

[ERROR] File "/home/lg/.opam/4.01.0/overlay/ocp-reloc/opam", line 13, character 35-36: '.' is not a valid token.
Errors in /home/lg/.opam/4.01.0/overlay/ocp-reloc/opam, retry editing ? [Y/n]

Installation

You probably want to try your brand new package right away, so OPAM's default action is to try and install it (unless you specified -n):

ocp-reloc needs to be installed.
The following actions will be performed:
 - install   cmdliner.0.9.5                        [required by ocp-reloc]
 - install   ocp-reloc.0.1*
=== 1 to install ===
Do you want to continue ? [Y/n]

I usually don't get it working the first time around, but opam pin edit ocp-reloc and opam install ocp-reloc -v can be used to edit and retry until it does.

Package Updates

How do you keep working on your project as you edit the source code, now that you are installing through OPAM? This is as simple as:

opam upgrade ocp-reloc

This will pick up changes from your source repository and reinstall any packages that are dependent on ocp-reloc as well, if any.

So far, we've been dealing with the metadata locally used by your OPAM installation, but you'll probably want to share this among developers of your project even if you're not releasing anything yet. OPAM takes care of this by prompting you to save the opam file back to your source tree, where you can commit it directly into your code repository.

cd ocp-reloc
git add opam
git commit -m 'Add OPAM metadata'
git push

Publishing your New Package

The above information is sufficient to use OPAM locally to integrate new code into an OPAM installation. Let's look at how other developers can share this metadata.

Picking up your development package

If another developer wants to pick up ocp-reloc, they can directly use your existing metadata by cloning a copy of your repository and issuing their own pin.

git clone git://github.com/OCamlPro/ocp-reloc.git
opam pin add ocp-reloc/

Even specifying the package name is optional since this is documented in ocp-reloc/opam. They can start hacking, and if needed use opam pin edit to amend the opam file too. No need for a repository, no need to share anything more than a versioned opam file within your project.

Cloning already existing packages

We have been focusing on an unreleased package, but the same functionality is also of great help in handling existing packages, whether you need to quickly hack into them or are just curious. Let's consider how to modify the omd Markdown library.

opam source omd --pin
cd omd.0.9.7
...patch...
opam upgrade omd

The new opam source command will clone the source code of the library you specify, and the --pin option will also pin it locally to ensure it is used in preference to all other versions. This will also take care of recompiling any installed packages that are dependent on omd using your patched version so that you notice any issues right away.

There's a new OPAM field available in 1.2 called dev-repo. If you specify this in your metadata, you can directly pin to the upstream repository via opam source --dev-repo --pin.

If the upstream repository for the package contains an opam file, that file will be picked up in preference to the one from the OPAM repository as soon as you pin the package. The idea is to have:

  • a development opam file that is versioned along with your source code (and thus accurately tracks the latest dependencies for your package).
  • a release opam file that is published on the OPAM repository and can be updated independently without making a new release of the source code.

How to get from the former to the latter will be the subject of another post! In the meantime, all users of the beta are welcome to share their experience and thoughts on the new workflow on the bug tracker.

It has only been 18 months since the first release of OPAM, but it is already difficult to remember a time when we did OCaml development without it. OPAM has helped bring together much of the open-source code in the OCaml community under a single umbrella, making it easier to discover, depend on, and maintain OCaml applications and libraries. We have seen steady growth in the number of new packages, updates to existing code, and a diverse group of contributors.

OPAM has turned out to be more than just another package manager. It is also increasingly central to the demanding workflow of industrial OCaml development, since it supports multiple simultaneous (patched) compiler installations, sophisticated package version constraints that ensure statically-typed code can be recompiled without conflict, and a distributed workflow that integrates seamlessly with Git, Mercurial or Darcs version control. OPAM tracks multiple revisions of a single package, thereby letting packages rely on older interfaces if they need to for long-term support. It also supports multiple package repositories, letting users blend the global stable package set with their internal revisions, or building completely isolated package universes for closed-source products.

Since its initial release, we have been learning from the extensive feedback from our users about how they use these features as part of their day-to-day workflows. Larger projects like XenAPI, the Ocsigen web suite, and the Mirage OS publish OPAM remotes that build their particular software suites. Complex applications such as the Pfff static analysis tool and Hack language from Facebook, the Frenetic SDN language and the Arakoon distributed key store have all appeared alongside these libraries. Jane Street pushes regular releases of their production Core/Async suite every couple of weeks.

One pleasant side-effect of the growing package database has been the contribution of tools from the community that make the day-to-day use of OCaml easier. These include the utop interactive toplevel, the IOCaml browser notebook, and the Merlin IDE extension. While these tools are an essential first step, there's still some distance to go to make the OCaml development experience feel fully integrated and polished.

Today, we are kicking off the next phase of evolution of OPAM and starting the journey towards building an OCaml Platform that combines the OCaml compiler toolchain with a coherent workflow for build, documentation, testing and IDE integration. As always with OPAM, this effort has been a collaborative effort, coordinated by the OCaml Labs group in Cambridge and OCamlPro in France. The OCaml Platform builds heavily on OPAM, since it forms the substrate that pulls together the tools and facilitates a consistent development workflow. We've therefore created this blog on opam.ocaml.org to chart its progress, announce major milestones, and eventually become a community repository of all significant activity.

Major points:

  • OPAM 1.2 beta available: Firstly, we're announcing the availability of the OPAM 1.2 beta, which includes a number of new features, hundreds of bug fixes, and pretty new colours in the CLI. We really need your feedback to ensure a polished release, so please do read the release notes below.

  • In the coming weeks, we will provide an overview of what the OCaml Platform is (and is not), and describe an example workflow that the Platform can enable.

  • Feedback: If you have questions or comments as you read these posts, then please do join the platform@lists.ocaml.org and make them known to us.

Releasing the OPAM 1.2 beta4

We are proud to announce the latest beta of OPAM 1.2. It comes packed with new features, stability and usability improvements. Here the highlights.

Binary RPMs and DEBs!

We now have binary packages available for Fedora 19/20, CentOS 6/7, RHEL7, Debian Wheezy and Ubuntu! You can see the full set at the OpenSUSE Builder site and download instructions for your particular platform.

An OPAM binary installation doesn't need OCaml to be installed on the system, so you can initialize a fresh, modern version of OCaml on older systems without needing it to be packaged there. On CentOS 6 for example:

cd /etc/yum.repos.d/
wget http://download.opensuse.org/repositories/home:ocaml/CentOS_6/home:ocaml.repo
yum install opam
opam init --comp=4.01.0

Simpler user workflow

For this version, we focused on improving the user interface and workflow. OPAM is a complex piece of software that needs to handle complex development situations. This implies things might go wrong, which is precisely when good support and error messages are essential. OPAM 1.2 has much improved stability and error handling: fewer errors and more helpful messages plus better state backups when they happen.

In particular, a clear and meaningful explanation is extracted from the solver whenever you are attempting an impossible action (unavailable package, conflicts, etc.):

$ opam install mirage-www=0.3.0
The following dependencies couldn't be met:
  - mirage-www -> cstruct < 0.6.0
  - mirage-www -> mirage-fs >= 0.4.0 -> cstruct >= 0.6.0
Your request can't be satisfied:
  - Conflicting version constraints for cstruct

This sets OPAM ahead of many other package managers in terms of user-friendliness. Since this is made possible using the tools from irill (which are also used for Debian), we hope that this work will find its way into other package managers. The extra analyses in the package solver interface are used to improve the health of the central package repository, via the OPAM Weather service.

And in case stuff does go wrong, we added the opam upgrade --fixup command that will get you back to the closest clean state.

The command-line interface is also more detailed and convenient, polishing and documenting the rough areas. Just run opam <subcommand> --help to see the manual page for the below features.

  • More expressive queries based on dependencies.

    $ opam list --depends-on cow --rec
    # Available packages recursively depending on cow.0.10.0 for 4.01.0:
    cowabloga   0.0.7  Simple static blogging support.
    iocaml      0.4.4  A webserver for iocaml-kernel and iocamljs-kernel.
    mirage-www  1.2.0  Mirage website (written in Mirage)
    opam2web    1.3.1 (pinned)  A tool to generate a website from an OPAM repository
    opium       0.9.1  Sinatra like web toolkit based on Async + Cohttp
    stone       0.3.2  Simple static website generator, useful for a portfolio or documentation pages
    
  • Check on existing opam files to base new packages from.

    $ opam show cow --raw
    opam-version: "1"
    name: "cow"
    version: "0.10.0"
    [...]
    
  • Clone the source code for any OPAM package to modify or browse the interfaces.

    $ opam source cow
    Downloading archive of cow.0.10.0...
    [...]
    $ cd cow.0.10.0
    

We've also improved the general speed of the tool to cope with the much bigger size of the central repository, which will be of importance for people building on low-power ARM machines, and added a mechanism that will let you install newer releases of OPAM directly from OPAM if you choose so.

Yet more control for the packagers

Packaging new libraries has been made as straight-forward as possible. Here is a quick overview, you may also want to check the OPAM 1.2 pinning post.

opam pin add <name> <sourcedir>

will generate a new package on the fly by detecting the presence of an opam file within the source repository itself. We'll do a followup post next week with more details of this extended opam pin workflow.

The package description format has also been extended with some new fields:

  • bug-reports: and dev-repo: add useful URLs
  • install: allows build and install commands to be split,
  • flags: is an entry point for several extensions that can affect your package.

Packagers can limit dependencies in scope by adding one of the keywords build, test or doc in front of their constraints:

depends: [
  "ocamlfind" {build & >= 1.4.0}
  "ounit" {test}
]

Here you don't specifically require ocamlfind at runtime, so changing it won't trigger recompilation of your package. ounit is marked as only required for the package's build-test: target, i.e. when installing with opam install -t. This will reduce the amount of (re)compilation required in day-to-day use.

We've also made optional dependencies more consistent by removing version constraints from the depopts: field: their meaning was unclear and confusing. The conflicts field is used to indicate versions of the optional dependencies that are incompatible with your package to remove all ambiguity:

depopts: [ "async" {>= "109.15.00"} & "async_ssl" {>= "111.06.00"} ]

becomes:

depopts: [ "async" "async_ssl" ]
conflicts: [ "async" {< "109.15.00"}
             "async_ssl" {< "111.06.00"} ]

There is an upcoming features field that will give more flexibility in a clearer and consistent way for such complex cases.

Easier to package and install

Efforts were made on the build of OPAM itself as well to make it as easy as possible to compile, bootstrap or install. There is no more dependency on camlp4 (which has been moved out of the core distribution in OCaml 4.02.0), and the build process is more conventional (get the source, run ./configure, make lib-ext to get the few internal dependencies, make and make install). Packagers can use make cold to build OPAM with a locally compiled version of OCaml (useful for platforms where it isn't packaged), and also use make download-ext to store all the external archives within the source tree (for automated builds which forbid external net access).

The whole documentation has been rewritten as well, to be better focused and easier to browse. Please leave any feedback or changes on the documentation on the issue tracker.

Try it out !

The public beta of OPAM 1.2 is just out. You're welcome to give it a try and give us feedback before we roll out the release!

We'd be most interested on feedback on how easily you can work with the new pinning features, on how the new metadata works for you... and on any errors you may trigger that aren't followed by informative messages or clean behaviour.

If you are hosting a repository, the administration scripts may help you quickly update all your packages to benefit from the new features.

We are proud to announce that OPAM 1.1.1 has just been released.

This minor release features mostly stability and UI/doc improvements over OPAM 1.1.0, but also focuses on improving the API and tools to be a better base for the platform (functions for opam-doc, interface with tools like opamfu and opam-installer). Lots of bigger changes are in the works, and will be merged progressively after this release.

Installing

Installation instructions are available on the wiki.

Note that some packages may take a few days until they get out of the pipeline. If you're eager to get 1.1.1, either use our binary installer or compile from source.

The 'official' package repository is now hosted at opam.ocaml.org, synchronised with the Git repository at http://github.com/ocaml/opam-repository, where you can contribute new packages descriptions. Those are under a CC0 license, a.k.a. public domain, to ensure they will always belong to the community.

Thanks to all of you who have helped build this repository and made OPAM such a success.

See full changelog

From the changelog:

  • Fix opam-admin make <packages> -r (#990)
  • Explicitly prettyprint list of lists, to fix opam-admin depexts (#997)
  • Tell the user which fields is invalid in a configuration file (#1016)
  • Add OpamSolver.empty_universe for flexible universe instantiation (#1033)
  • Add OpamFormula.eval_relop and OpamFormula.check_relop (#1042)
  • Change OpamCompiler.compare to match Pervasives.compare (#1042)
  • Add OpamCompiler.eval_relop (#1042)
  • Add OpamPackage.Name.compare (#1046)
  • Add types version_constraint and version_formula to OpamFormula (#1046)
  • Clearer command aliases. Made info an alias for show and added the alias uninstall (#944)
  • Fixed opam init --root=<relative path> (#1047)
  • Display OS constraints in opam info (#1052)
  • Add a new 'opam-installer' script to make .install files usable outside of opam (#1026)
  • Add a --resolve option to opam-admin make that builds just the archives you need for a specific installation (#1031)
  • Fixed handling of spaces in filenames in internal files (#1014)
  • Replace calls to which by a more portable call (#1061)
  • Fixed generation of the init scripts in some cases (#1011)
  • Better reports on package patch errors (#987, #988)
  • More accurate warnings for unknown package dependencies (#1079)
  • Added opam config report to help with bug reports (#1034)
  • Do not reinstall dev packages with opam upgrade <pkg> (#1001)
  • Be more careful with opam init to a non-empty root directory (#974)
  • Cleanup build-dir after successful compiler installation to save on space (#1006)
  • Improved OSX compatibility in the external solver tools (#1074)
  • Fixed messages printed on update that were plain wrong (#1030)
  • Improved detection of meaningful changes from upstream packages to trigger recompilation

After a while staged as RC, we are proud to announce the final release of OPAM 1.1.0!

Thanks again to those who have helped testing and fixing the last few issues.

Important note

The repository format has been improved with incompatible new features; to account for this, the new repository is now hosted at [opam.ocaml.org][], and the legacy repository at [opam.ocamlpro.com][] is kept to support OPAM 1.0 installations, but is unlikely to benefit from many package updates. Migration to [opam.ocaml.org][] will be done automatically as soon as you upgrade your OPAM version.

You're still free, of course, to use any third-party repositories instead or in addition.

Installing

NOTE: When switching from 1.0, the internal state will need to be upgraded. THIS PROCESS CANNOT BE REVERTED. We have tried hard to make it fault- resistant, but failures might happen. In case you have precious data in your ~/.opam folder, it is advised to backup that folder before you upgrade to 1.1.0.

Using the binary installer:

  • download and run http://www.ocamlpro.com/pub/opam_installer.sh

Using the .deb packages from Anil's PPA (binaries are [currently syncing][1]): add-apt-repository ppa:avsm/ppa apt-get update sudo apt-get install opam

For OSX users, the homebrew package will be updated shortly.

or build it from sources at :

  • http://www.ocamlpro.com/pub/opam-full-1.1.0.tar.gz
  • https://github.com/ocaml/opam/releases/tag/1.1.0

For those who haven't been paying attention

OPAM is a source-based package manager for OCaml. It supports multiple simultaneous compiler installations, flexible package constraints, and a Git-friendly development workflow. OPAM is edited and maintained by OCamlPro, with continuous support from OCamlLabs and the community at large (including its main industrial users such as Jane-Street and Citrix).

The 'official' package repository is now hosted at [opam.ocaml.org][], synchronised with the Git repository at [http://github.com/ocaml/opam-repository][repo], where you can contribute new packages descriptions. Those are under a CC0 license, a.k.a. public domain, to ensure they will always belong to the community.

Thanks to all of you who have helped build this repository and made OPAM such a success.

See full changelog

Too many to list here, see https://raw.github.com/OCamlPro/opam/1.1.0/CHANGES

For packagers, some new fields have appeared in the OPAM description format:

  • depexts provides facilities for dealing with system (non ocaml) dependencies
  • messages, post-messages can be used to notify the user eg. of licensing information, or help her troobleshoot at package installation.
  • available supersedes ocaml-version and os constraints, and can contain more expressive formulas

Also, we have integrated the main package repository with Travis, which will help us to improve the quality of contributions (see Anil's post).

OPAM 1.1.0 is ready, and we are shipping a release candidate for packagers and all interested to try it out.

This version features several bug-fixes over the September beta release, and quite a few stability and usability improvements. Thanks to all beta-testers who have taken the time to file reports, and helped a lot tackling the remaining issues.

Repository change to opam.ocaml.org

This release is synchronized with the migration of the main repository from ocamlpro.com to ocaml.org. A redirection has been put in place, so that all up-to-date installation of OPAM should be redirected seamlessly. OPAM 1.0 instances will stay on the old repository, so that they won't be broken by incompatible package updates.

We are very happy to see the impressive amount of contributions to the OPAM repository, and this change, together with the licensing of all metadata under CC0 (almost pubic domain), guarantees that these efforts belong to the community.

If you are upgrading from 1.0

The internal state will need to be upgraded at the first run of OPAM 1.1.0. THIS PROCESS CANNOT BE REVERTED. We have tried hard to make it fault- resistant, but failures might happen. In case you have precious data in your ~/.opam folder, it is advised to backup that folder before you upgrade to 1.1.0.

Installing

Using the binary installer:

  • download and run http://www.ocamlpro.com/pub/opam_installer.sh

You can also get the new version either from Anil's unstable PPA: add-apt-repository ppa:avsm/ppa-testing apt-get update sudo apt-get install opam

or build it from sources at :

  • http://www.ocamlpro.com/pub/opam-full-1.1.0.tar.gz
  • https://github.com/OCamlPro/opam/releases/tag/1.1.0-RC
See full changelog

Too many to list here, see https://raw.github.com/OCamlPro/opam/1.1.0-RC/CHANGES

For packagers, some new fields have appeared in the OPAM description format:

  • depexts provides facilities for dealing with system (non ocaml) dependencies
  • messages, post-messages can be used to notify the user or help her troubleshoot at package installation.
  • available supersedes ocaml-version and os constraints, and can contain more expressive formulas

We are very happy to announce the beta release of OPAM version 1.1.0!

OPAM is a source-based package manager for OCaml. It supports multiple simultaneous compiler installations, flexible package constraints, and a Git-friendly development workflow which. OPAM is edited and maintained by OCamlPro, with continuous support from OCamlLabs and the community at large (including its main industrial users such as Jane-Street and Citrix).

Since its first official release last March, we have fixed many bugs and added lots of new features and stability improvements. New features go from more metadata to the package and compiler descriptions, to improved package pin workflow, through a much faster update algorithm. The full changeset is included below.

We are also delighted to see the growing number of contributions from the community to both OPAM itself (35 contributors) and to its metadata repository (100+ contributors, 500+ unique packages, 1500+ packages). It is really great to also see alternative metadata repositories appearing in the wild (see for instance the repositories for Android, Windows and so on). To be sure that the community efforts will continue to benefit to everyone and to underline our committment to OPAM, we are rehousing it at https://opam.ocaml.org and switching the license to CC0 (see issue #955, where 85 people are commenting on the thread).

The binary installer has been updated for OSX and x86_64:

  • http://www.ocamlpro.com/pub/opam_installer.sh

You can also get the new version either from Anil's unstable PPA: add-apt-repository ppa:avsm/ppa-testing apt-get update sudo apt-get install opam

or build it from sources at :

  • http://www.ocamlpro.com/pub/opam-full-1.1.0-beta.tar.gz
  • https://github.com/OCamlPro/opam/releases/tag/1.1.0-beta

NOTE: If you upgrade from OPAM 1.0, the first time you will run the new opam binary it will upgrade its internal state in an incompatible way: THIS PROCESS CANNOT BE REVERTED. We have tried hard to make this process fault-resistant, but failures might happen. In case you have precious data in your ~/.opam folder, it is advised to backup that folder before you upgrade to 1.1.

See full changelog
  • Automatic backup before any operation which might alter the list of installed packages
  • Support for arbitrary sub-directories for metadata repositories
  • Lots of colors
  • New option opam update -u equivalent to opam update && opam upgrade --yes
  • New opam-admin tool, bundling the features of opam-mk-repo and opam-repo-check + new 'opam-admin stats' tool
  • New available: field in opam files, superseding ocaml-version and os fields
  • Package names specified on the command-line are now understood case-insensitively (#705)
  • Fixed parsing of malformed opam files (#696)
  • Fixed recompilation of a package when uninstalling its optional dependencies (#692)
  • Added conditional post-messages support, to help users when a package fails to install for a known reason (#662)
  • Rewrite the code which updates pin et dev packages to be quicker and more reliable
  • Add {opam,url,desc,files/} overlay for all packages
  • opam config env now detects the current shell and outputs a sensible default if no override is provided.
  • Improve opam pin stability and start display information about dev revisions
  • Add a new man field in .install files
  • Support hierarchical installation in .install files
  • Add a new stublibs field in .install files
  • OPAM works even when the current directory has been deleted
  • speed-up invocation of opam config var VARIABLE when variable is simple (eg. prefix, lib, ...)
  • opam list now display only the installed packages. Use opam list -a to get the previous behavior.
  • Inverse the depext tag selection (useful for ocamlot)
  • Add a --sexp option to opam config env to load the configuration under emacs
  • Purge ~/.opam/log on each invocation of OPAM
  • System compiler with versions such as version+patches are now handled as if this was simply version
  • New OpamVCS functor to generate OPAM backends
  • More efficient opam update
  • Switch license to LGPL with linking exception
  • opam search now also searches through the tags
  • minor API changes for API.list and API.SWITCH.list
  • Improve the syntax of filters
  • Add a messages field
  • Add a --jobs command line option and add %{jobs}% to be used in OPAM files
  • Various improvements in the solver heuristics
  • By default, turn-on checking of certificates for downloaded dependency archives
  • Check the md5sum of downloaded archives when compiling OPAM
  • Improved opam info command (more information, non-zero error code when no patterns match)
  • Display OS and OPAM version on internal errors to ease error reporting
  • Fix opam reinstall when reinstalling a package wich is a dependency of installed packages
  • Export and read OPAMSWITCH to be able to call OPAM in different switches
  • opam-client can now be used in a toplevel
  • -n now means --no-setup and not --no-checksums anymore
  • Fix support of FreeBSD
  • Fix installation of local compilers with local paths endings with ../ocaml/
  • Fix the contents of ~/.opam/opam-init/variable.sh after a switch

I am very happy to announce the first official release of OPAM!

Many of you already know and use OPAM so I won't be long. Please read http://www.ocamlpro.com/blog/2013/01/17/opam-beta.html for a longer description.

1.0.0 fixes many bugs and add few new features to the previously announced beta-release.

The most visible new feature, which should be useful for beginners with OCaml and OPAM, is an auto-configuration tool. This tool easily enables all the features of OPAM (auto-completion, fix the loading of scripts for the toplevel, opam-switch-eval alias, etc). This tool runs interactively on each opam init invocation. If you don't like OPAM to change your configuration files, use opam init --no-setup. If you trust the tool blindly, use opam init --auto-setup. You can later review the setup by doing opam config setup --list and call the tool again using opam config setup (and you can of course manually edit your ~/.profile (or ~/.zshrc for zsh users), ~/.ocamlinit and ~/.opam/opam-init/*).

Please report:

  • Bug reports and feature requests for the OPAM tool: http://github.com/OCamlPro/opam/issues
  • Packaging issues or requests for a new packages: http://github.com/OCamlPro/opam-repository/issues
  • General queries to: https://lists.ocaml.org/listinfo/platform
  • More specific queries about the internals of OPAM to: https://lists.ocaml.org/listinfo/opam-devel

Install

Packages for Debian and OSX (at least homebrew) should follow shortly and I'm looking for volunteers to create and maintain rpm packages. The binary installer is up-to-date for Linux and Darwin 64-bit architectures, the 32-bit version for Linux should arrive shortly.

If you want to build from sources, the full archive (including dependencies) is available here:

http://www.ocamlpro.com/pub/opam-full-latest.tar.gz

Upgrade

If you are upgrading from 0.9.* you won't have anything special to do apart installing the new binary. You can then update your package metadata by running opam update. If you want to use the auto-setup feature, remove the "eval opam config env line you have previously added in your ~/.profile and run opam config setup --all.

So everything should be fine. But you never know ... so if something goes horribly wrong in the upgrade process (of if your are upgrading from an old version of OPAM) you can still trash your ~/.opam, manually remove what OPAM added in your ~/.profile (~/.zshrc for zsh users) and ~/.ocamlinit, and start again from scratch.

Random stats

Great success on github. Thanks everybody for the great contributions!

https://github.com/OCamlPro/opam: +2000 commits, 26 contributors https://github.com/OCamlPro/opam-repository: +1700 commits, 75 contributors, 370+ packages

on http://opam.ocamlpro.com/ +400 unique visitor per week, 15k 'opam update' per week +1300 unique visitor per month, 55k 'opam update' per month 3815 unique visitor since the alpha release

See full changelog

The full change-log since the beta release in January:

1.0.0 [Mar 2013]

  • Improve the lexer performance (thx to @oandrieu)
  • Fix various typos (thx to @chaudhuri)
  • Fix build issue (thx to @avsm)

0.9.6 [Mar 2013]

  • Fix installation of pinned packages on BSD (thx to @smondet)
  • Fix configuration for zsh users (thx to @AltGr)
  • Fix loading of ~/.profile when using dash (eg. in Debian/Ubuntu)
  • Fix installation of packages with symbolic links (regression introduced in 0.9.5)

0.9.5 [Mar 2013]

  • If necessary, apply patches and substitute files before removing a package
  • Fix opam remove <pkg> --keep-build-dir keeps the folder if a source archive is extracted
  • Add build and install rules using ocamlbuild to help distro packagers
  • Support arbitrary level of nested subdirectories in packages repositories
  • Add opam config exec "CMD ARG1 ... ARGn" --switch=SWITCH to execute a command in a subshell
  • Improve the behaviour of opam update wrt. pinned packages
  • Change the default external solver criteria (only useful if you have aspcud installed on your machine)
  • Add support for global and user configuration for OPAM (opam config setup)
  • Stop yelling when OPAM is not up-to-date
  • Update or generate ~/.ocamlinit when running opam init
  • Fix tests on *BSD (thx Arnaud Degroote)
  • Fix compilation for the source archive

0.9.4 [Feb 2013]

  • Disable auto-removal of unused dependencies. This can now be enabled on-demand using -a
  • Fix compilation and basic usage on Cygwin
  • Fix BSD support (use type instead of which to detect existing commands)
  • Add a way to tag external dependencies in OPAM files
  • Better error messages when trying to upgrade pinned packages
  • Display depends and depopts fields in opam info
  • opam info pkg.version shows the metadata for this given package version
  • Add missing doc fields in .install files
  • opam list now only shows installable packages

0.9.3 [Feb 2013]

  • Add system compiler constraints in OPAM files
  • Better error messages in case of conflicts
  • Cleaner API to install/uninstall packages
  • On upgrade, OPAM now perform all the remove action first
  • Use a cache for main storing OPAM metadata: this greatly speed-up OPAM invocations
  • after an upgrade, propose to reinstall a pinned package only if there were some changes
  • improvements to the solver heuristics
  • better error messages on cyclic dependencies

0.9.2 [Jan 2013]

  • Install all the API files
  • Fix opam repo remove repo-name
  • speed-up opam config env
  • support for opam-foo scripts (which can be called using opam foo)
  • 'opam update pinned-package' works
  • Fix 'opam-mk-repo -a'
  • Fix 'opam-mk-repo -i'
  • clean-up pinned cache dir when a pinned package fails to install

0.9.1 [Jan 2013]

  • Use ocaml-re 1.2.0
If you want to contribute to a new release announcement, check out the Contributing Guide on GitHub.