49495e9b06
By recording each package's archive-entry separately we are able to build each recipe independently and then compile the archive contents afterwards. |
||
---|---|---|
etc | ||
features | ||
html | ||
packages | ||
recipes | ||
resources | ||
scripts | ||
service | ||
working | ||
.gitignore | ||
.travis.yml | ||
Cask | ||
json-fix.el | ||
LICENSE.md | ||
Makefile | ||
melpa.el | ||
migrate | ||
package-build.el | ||
README.md | ||
run-travis-ci.sh |
MELPA
MELPA is a growing collection of package.el
-compatible Emacs Lisp
packages built automatically on our server from the upstream source
code using simple recipes. (Think of it as a server-side version of
el-get, or even
homebrew.)
Packages are updated at intervals throughout the day.
To browse available packages, check out the archive index page.
Adding packages is as simple as submitting a pull request; read on for details.
Table of Contents
Usage
To use the MELPA repository, add it to package-archives
after
(require 'package)
and before the call to package-initialize
in
your init.el
file.
(add-to-list 'package-archives
'("melpa" . "http://melpa.milkbox.net/packages/") t)
In Emacs < 24, you'll also need to explicitly include the GNU ELPA
archive, which provides important compatibility libraries like
cl-lib
:
(when (< emacs-major-version 24)
(add-to-list 'package-archives '("gnu" . "http://elpa.gnu.org/packages/")))
A complete minimal example for MELPA,
(require 'package)
(add-to-list 'package-archives
'("melpa" . "http://melpa.milkbox.net/packages/") t)
(when (< emacs-major-version 24)
(add-to-list 'package-archives '("gnu" . "http://elpa.gnu.org/packages/")))
(package-initialize)
Since package.el
doesn't allow locking packages to certain version, MELPA packages
will override those available from any other package source, so
we also provide a package melpa.el
which contains code to allow
restricting packages to specific repositories. This allows someone to
blacklist packages that come from a specific repository, or blacklist
all packages from a repository and only whitelist certain packages.
See the MELPA Package section below if you think you might want that.
Contributing New Recipes
New recipe submissions should adhere to the following guidelines,
-
One pull request per recipe. You can create multiple branches and create a pull request for each branch.
-
Upstream source must be stored in an authoritative SCM repository. Emacswiki recipes are discouraged but can be accepted.
-
Packages should be built from the official package repository. Forks of the official repository will not be accepted except in extreme circumstances.
-
The package name should match the name of the feature provided. See the
package
function for more information. -
Packages should adhere to the
package.el
format as specified by(info "(elisp) Packaging")
. More information on this format is provided by the marmalade package manual. -
Recipes should try to minimize the size of the resulting package by specifying only files relevant to the package. See the Recipe Format section for more information on specifying package files.
Expediting Recipe Reviews
Because we care about the quality of packages that are part of MELPA we review all submissions. The following steps can help us with this process and expedite the recipe review process,
-
Include the following information in the pull request:
-
A brief summary of what the package does.
-
Your association with the package (e.g., are you the maintainer? have you contributed? do you just like the package a lot?).
-
A direct link to the package repository.
-
Relevant communications with the package maintainer (e.g.,
package.el
compatibility changes that you have submitted).
-
-
Test that the package builds properly via
make recipes/<recipe>
. -
Test that the package installs properly via
package-install-file
.
Testing
Let <NAME>
denote the name of the recipe to submit.
-
Fork the MELPA repository.
-
Add your new file under the directory specified by
package-build-recipes-dir
(default:recipes/
directory wherepackage-build
was loaded). -
Confirm your package built properly by running
make recipes/<NAME>
(Be sure that the emacs
on your path is at least version 23, or
set $EMACS
to the location of a suitable binary.)
- Install the file you built by running
package-install-file
from within Emacs and specifying the newly built package in the directory specified bypackage-build-archive-dir
(default:packages/
directory wherepackage-build
was loaded).
Submitting
After verifying the entry works properly please open a pull request on Github. Consider the hub command-line utility by defunkt which helps simplify this process.
Recipe Format
Packages are specified by files in the recipes
directory. You can
contribute a new package by adding a new file under recipes
using
the following form ([...]
denotes optional or conditional values),
(<package-name>
:fetcher [git|github|bzr|hg|darcs|svn|cvs|wiki]
[:url "<repo url>"]
[:repo "github-user/repo-name"]
[:module "cvs-module"]
[:files ("<file1>" ...)])
-
package-name
a lisp symbol that has the same name as the package being specified. -
:fetcher
(one ofgit, github, bzr, hg, darcs, svn, cvs, wiki
) specifies the type of repository that:url
points to. Right now package-build supports git, github, bazaar (bzr), mercurial (hg), subversion (svn), cvs, darcs, and Emacs Wiki (wiki) as possible mechanisms for checking out the repository.package-build uses the corresponding application to update files before building the package. In the case of the
github
fetcher, use:repo
instead of:url
; the git URL will then be deduced.The Emacs Wiki fetcher gets the latest version of the package from
http://www.emacswiki.org/emacs/download/<NAME>.el
whereNAME
is the package name. Note that the:url
property is not needed for thewiki
engine unless the name of the package file on the EmacsWiki differs from the package name being built. -
:url
specifies the URL of the version control repository. required for thegit
,bzr
,hg
,darcs
,svn
andcvs
fetchers. -
:repo
specifies the github repository and is of the formgithub-user/repo-name
. required for thegithub
fetcher. -
:commit
specifies the commit or branch of the git repo to checkout. The value will be passed togit reset
in a repo whereupstream
is the original repository. Can therefore be either a sha, if pointing at a specific commit, or a branch (prefixed with "origin/"). Only used by thegit
andgithub
fetchers. -
:module
specifies the module of a CVS repository to check out. Defaults to topackage-name
. Only used with:fetcher cvs
, and otherwise ignored. -
:files
[default:(*.el *.info dir)
] optional property specifying the elisp and info files used to build the package. Automatically populated by matching all.el
,.info
anddir
files in the root of the repository.This option is necessary when there are multiple packages in the repository and thus the package should only be built from a subset of
.el
files. For example, elisp test files should not normally be packaged. Any file specified at any path in the repository is copied to the root of the package. More complex options are available, submit an Issue if the specified package requires more complex file specification.
Example: Single File Repository
ido-ubiquitous is a repository that contains two files:
README.md
ido-ubiquitous.el
Since there is only one .el
file, this package only needs the :url
and :fetcher
specified,
(ido-ubiquitous
:url "https://github.com/DarwinAwardWinner/ido-ubiquitous.git"
:fetcher git)
Example: Multiple Packages in one Repository
The
emacs-starter-kit
contains the starter-kit package along with extra packages in the
modules
directory; starter-kit-bindings, starter-kit-lisp, etc.
(starter-kit
:url "https://github.com/technomancy/emacs-starter-kit.git"
:fetcher git)
(starter-kit-bindings
:url "https://github.com/technomancy/emacs-starter-kit.git"
:fetcher git
:files ("modules/starter-kit-bindings.el"))
Notice that :files
is not specified for starter-kit
since
package-build will automatically add all .el
files in the root
directory of the repository. The starter-kit-bindings
repository is
contained in the modules/
subdirectory and thus needs the packages
files specified explicitly.
Example: Multiple Files in Multiple Directories
There are special cases when we need There are special cases where creation of the package comes from many different sub-directories in the repository and the destination sub-directories need to be explicitly set.
Consider the flymake-perlcritic
recipe,
(flymake-perlcritic :repo "illusori/emacs-flymake-perlcritic"
:fetcher github
:files ("*.el" ("bin" "bin/flymake_perlcritic")))
which will result in a package structure of,
flymake-perlcritic-YYYMMDD
|-- bin
| `-- flymake_perlcritic
|-- flymake-perlcritic-pkg.el
`-- flymake-perlcritic.el
Notice that specifying an entry in :files
that is a list takes the
first element to be the destination directory. These can be embedded
further, such as the following---hypothetical---entry for :files
,
("*.el" ("snippets"
("html-mode" "snippets/html-mode/*")
("python-mode" "snippets/python-mode/*")))
which would result in a package with *.el
in something like,
package-YYYYMMDD
|-- snippets
| |-- html-mode
| | |-- div
| | `-- html
| `-- python-mode
| |-- for
| `-- main
`-- package.el
But a better solution, given that we probably want to copy the
entire snippets
directory to the root of the package, we could
just specify that directory. Consider the pony-mode
recipe,
(pony-mode
:repo "davidmiller/pony-mode"
:fetcher github
:files ("src/*.el" "snippets"))
which generates the package,
pony-mode-YYYYMMDD
|-- pony-mode-pkg.el
|-- pony-mode.el
|-- pony-tpl.el
`-- snippets
|-- html-mode
| |-- bl
| |-- ex
| |-- for
| |-- if
| |-- loa
| |-- sup
| |-- testc
| `-- {{
`-- python-mode
|-- auth-view
|-- bn
|-- model
|-- modelform
|-- render-to
|-- testc
`-- view
Build Scripts
Building MELPA is all based around using the Makefile
included in
the root repository directory. Described below are the actions that
accepted by the Makefile
.
-
all
-- Builds all packages under therecipes/
directory and compiles theindex.html
file for the melpa website. -
recipes/<NAME>
-- Build individual recipe<NAME>
. Built packages are put in thepackages/
folder with version corresponding to the newest HEAD revision available; given according to the%Y%m%d
format. -
json
-- build all JSON files. -
archive.json
-- construct thearchive.json
file that will contain a JSON object of all compiled packages. -
recipes.json
-- construct therecipes.json
file containing a JSON object of all packages available for building. -
clean
-- clean everything. -
html
-- buildindex.html
. -
clean-working
-- remove all repositories that have been checked out to theworking/
directory. -
clean-packages
-- remove all compiled packages from thepackages
directory. -
clean-json
-- remove all JSON files.
Note that these scripts require an Emacs with package.el
installed,
such as Emacs 24. If you have an older version of Emacs, you can get a
suitable package.el
here.
API
All repository code is contained in the package-build.el
.
Functions
-
(package-build-all)
: build packages for all recipes in the directory specified bypackage-build-recipes-dir
. -
(package-build-archive NAME)
: interactive elisp function to build a single archive. NAME is a symbol for the package to be built. Packages are staged in the directory specified bypackage-build-working-dir
and built packages are placed in the directory specified bypackage-build-archive-dir
. Packages are versioned based on the most recent commit date to package files based on commits to upstream package repository. For multi-file packages, the file<NAME>-pkg.el
is automatically generated and contains description, version, and requires information determined by searching<NAME>-pkg.el
,<NAME>.el
, and<NAME>-pkg.el.in
, if they exist in the repository.
Variables
-
package-build-working-dir
: Staging area containing package repositories and package directories being built. -
package-build-archive-dir
: Location to storearchive-contents
and any built packages. -
package-build-recipes-dir
: Directory containing MELPA compatible recipes. See Recipe Format section for more details.
Configuration
Packages end up in the packages/
directory by default.
This can be configured using the package-build-archive-dir
variable.
Repositories are checked out to the working/
directory by default.
This can be configured using the package-build-working-dir
variable.
MELPA Package
The melpa.el
package---available in MELPA--allows creating a
whitelist or blacklist of packages for a specific repository. This
allows for disabling all packages from a specific repository and only
enabling certain packages, or simply blacklist a certain subset of packages.
Configuring
By default there are two variables that can be customized to specify which packages will be enabled (whitelist packages only) or excluded (blacklist of packages)
-
package-archive-enable-alist
: Optional Alist of enabled packages used bypackage-filter
. The format is (ARCHIVE . PACKAGE ...), where ARCHIVE is a string matching an archive name inpackage-archives
, PACKAGE is a symbol of a package in ARCHIVE to enable. If no ARCHIVE exists in the alist, all packages are enabled.If no ARCHIVE exists in the alist, all packages are enabled.
-
package-archive-exclude-alist
: Alist of packages excluded bypackage-filter
. The format is (ARCHIVE . PACKAGE ...), where ARCHIVE is a string matching an archive name inpackage-archives
, PACKAGE is a symbol of a package in that archive to exclude. Any specified package is excluded regardless of the value ofpackage-archive-enable-alist
If a particular ARCHIVE has an entry in
package-archive-enable-alist
then only packages
Manual Installation
You can install the package manually by pasting this into your *scratch*
buffer and evaluating it.
(progn
(switch-to-buffer
(url-retrieve-synchronously
"https://raw.github.com/milkypostman/melpa/master/melpa.el"))
(package-install-from-buffer (package-buffer-info) 'single))
About
MELPA is Milkypostman's ELPA or Milkypostman's Experimental Lisp Package Archive if you're not into the whole brevity thing.