MOPI: MATLAB/Octave Package Installer
MOPI provides a useful way to install dependencies for MATLAB and Octave.
There are two methods available to install dependency packages, one is the
mopi.sh, and the other is a MATLAB function
These lightweight utilities can be included in any MATLAB/Octave project which has non-trivial dependencies either by using a submodule of this repository, or including them as a static copy along with the LICENSE file, which can potentially be managed and updated using git subtree.
On *nix, one can download requirements specified in a file named
requirements.txt with the bash script:
On all systems, at the MATLAB or Octave command prompt one can do:
By default, the shell script will download packages into a folder called
external in the present directory, whereas the
.m function will ask for an
installation destination using a command prompt.
To specify a download location at the terminal, one can need only provide it as a second input with
mopi.sh requirements.txt DOWLOAD_FOLDER
Each non-Forge package will be downloaded into a folder within DOWLOAD_FOLDER corresponding to the inferred name of the package.
.m function for MATLAB and Octave can alternatively be given the name of
a single package, or cell array of packages instead of a file listing packages.
.m function can optionally add the downloaded packages to the path
immediately (by default this is enabled).
This package offers three ways to install other MATLAB and Octave packages. These are
- from MATLAB FileExchange
- from Octave Forge
- from generic URL
MATLAB FileExchange (FEX)
Packages on MATLAB FileExchange should preferably be specified with the
This should be followed by the FEX ID of the package.
The FEX ID can be determined from the URL of the package, e.g.
File ID field on this page.
In this case, the FEX ID is
For example, the package can be specified by
or alternatively, the name can be included, such as
which will be stripped out during processing.
Each FEX package will be installed into a folder matching the FEX ID of the
package, such as
55540, with the downloaded contents unzipped into this
If an entry does not have a protocol prefix, but is solely numeric (or numeric and then a hyphen) it is assumed to be a FEX package.
is implicitly a FEX package and will be interpretted as such.
Packages on Octave Forge should preferably be specified with the
This should be followed by the name of the package.
Forge requirements are ignored if the
.m function is run on MATLAB instead
The shell script will install Forge dependencies only if a command
can be found on the system, otherwise Forge dependencies are quietly ignored.
Care should be taken to make sure the packages are installed in the correct order, lest an error be thrown due to a missing dependency of a dependency.
For instance, the
io package, so in a
requirements.txt file one should specify
is implicitly a Forge package and will be interpretted as such.
Uniform Resource Locator (URL)
All other protocols are handled the same way, and will be downloaded with
wget or similar over HTTP, HTTPS, FTP, etc.
The name of the package is inferred from the (extensionless) filename which the URL points to. The package will then be installed into a subfolder matching this inferred package name. If the downloaded file is an archive it will be decompressed, otherwise it will be copied as-is.
would both be decompressed into a folder
Comments can be inserted into requirements files by prepending them with a
Entire lines can be commented out, or inline comments can be used.
Inline comments must have a space separating them from actual content, lest
# be confused with a URL anchor
# This file contains a demo fex://55540 # This is a dummy package
Here is an example file listing package requirements.
# Requirements for package foo forge://control fex://55540-dummy-package http://www.mathworks.com/moler/ncm.zip
If one wishes to only install requirements when they are needed in the code, the following method can be used:
if ~exist('dummy.txt', 'file') mopi('fex://55540'); end
Differences between .sh and .m implementations
There are a small number of differences between the shell and native matlab implementations of MOPI.
- The shell script can infer archives from their MIME type; the matlab function can only use file extensions.
- The shell script can unpack a wider variety of archive file types (provied
an appropriate utility bash command is available);
on MATLAB, the
.mfunction is restricted to only
.tgz); on Octave, the
.mfunction is restricted to
- The shell script can save the downloaded files to a cache directory to use in future; the matlab function always discards downloaded files. This feature should be useful when repeatedly installing dependencies, for unit testing on a continous integration server such as Travis, say.
- The matlab function can optionally add the downloaded packages to the MATLAB/Octave search path; the shell script cannot.
Including MOPI in another git repository
To make dependency installation as easy as possible, it is prudent to ship a copy of MOPI along with any other toolbox or package you are developing which has any dependencies.
To set this up with a git repository, we recommend you use git-subtree. This is recommended over git submodule because submodule will require a deep clone of the repository for all the files to be in place, whereas subtree will include a copy of MOPI with your package even if it is downloaded as a zip file from the repository remote or FEX.
You can add mopi to your repository with the following command:
# Initial commit of MOPI git subtree add --squash --prefix mopi \ https://github.com/mopify/mopi.git master
And this can be kept up-to-date by merging new commits from the MOPI remote into your repository as follows:
# Updating MOPI git pull git subtree pull --squash --prefix mopi \ https://github.com/mopify/mopi.git master git push
Please note that you will need a clean working tree before attempting the subtree command.
Additionally, please note that the commit history cannot be rebased easily when it includes squashed changes.