EPM plugin modules - now pull from anywhere!
Categories: erlang, epm
» http://github.com/JacobVorreuter/epm
Installing EPM
curl "http://github.com/JacobVorreuter/epm/raw/master/epm" > epm
chmod +x epm
Updating to most recent version
If you already have EPM then you will want to update it:
jvorreuter$ epm latest
epm v0.1.1, 2010
+ updated epm (/usr/local/bin/epm) to latest version
Configuring available plugins
First, run the config command to get an idea of what your current config values are:
jvorreuter$ epm config
epm v0.1.1, 2010
install_dir "/Users/jacobvorreuter/dev"
build_dir "/tmp"
Now run the config set command to specify a list of plugin modules to use (noting the absence of a space between module names in the list):
jvorreuter$ epm config --set repo_plugins [github_api,bitbucket_api]
epm v0.1.1, 2010
+ updated .epm config
By default EPM uses [github_api] as the value of repo_plugins
Writing custom plugins
EPM plugins implement the api_behavior that has the following callbacks:
-module(github_api).
-behaviour(api_behavior).
-export([package_deps/3, search/1, info/2, tags/2,
branches/2, download_package/2, default_vsn/0]).
View the entire module here: http://github.com/JacobVorreuter/epm/blob/master/src/github_api.erl
Plugin module callback functions
package_deps/3
The package_deps/3 function returns the list of depedencies specified in an application's epm file. An application with no dependencies does not require an epm file and should return an empty list. For both the GitHub and BitBucket api modules this function is implemented by requesting the application epm file and reading the deps property.
package_deps(User, ProjectName, Vsn) -> Deps
User = string()
ProjectName = string()
Vsn = string()
Deps = [{Project, Args}]
Project = string()
Args = list()
search/1
The search/1 function should return a list of repository records or an error tuple.
search(ProjectName) -> Results
ProjectName = string()
Results = [repository()] | {error, Reason}
info/2
The info/2 function should return a single repository record or an error tuple or undefined if the repository does not exist.
info(User, ProjectName) -> Result
User = string()
ProjectName = string()
Result = repository() | undefined | {error, Reason}
tags/2
The tags/2 function returns a list of tag names as strings.
tags(User, ProjectName) -> Result
User = string()
ProjectName = string()
Result = [Tag]
Tag = string()
branches/2
The branches/2 function returns a list of branch names as strings.
branches(User, ProjectName) -> Result
User = string()
ProjectName = string()
Result = [Branch]
Branch = string()
download_package/2
The download_package/2 function takes a repository record and the vsn (tag/branch/sha) to be downloaded. There is a helper function, epm_package:download_tarball/2, that does most of the work. The plugin module is only responsible for generating the correct url. The return value, LocalProjectDir, is the path to the directory where the tarball was unpacked.
download_package(Repo, Vsn) -> LocalProjectDir
User = string()
ProjectName = string()
Vsn = string()
LocalProjectDir = string()
default_vsn/0
The default_vsn/0 function returns the default branch to use if none is specified on the command line. For a git repo this would be "master" and for a mercurial repo this would be "tip".
default_vsn() -> Result
Result = string()
An example plugin
Let's make an example plugin named foo_api.erl
jvorreuter$ cd /src/
jvorreuter$ mkdir foo_plugin
jvorreuter$ cd foo_plugin
jvorreuter$ touch foo_api.erl
Now we can hard code some return values for our api functions:
And finally we compile the module, add it to our path and set the EPM repo_plugins config value:
jvorreuter$ erlc -pa /src/epm/ebin -I /src/epm/include foo_api.erl
jvorreuter$ echo 'code:add_patha("/src/foo_plugin").' >> ~/.erlang
jvorreuter$ epm config --set repo_plugins [foo_api]
epm v0.1.1, 2010
+ updated .epm config
When we search for a package, the foo_api plugin module gives us back our fixed response!
jvorreuter$ epm search something
epm v0.1.1, 2010
===============================
AVAILABLE
===============================
name: something
owner: jkvor
followers:
pushed:
homepage: http://jkvor.com
description: my fake foo project
repo plugin: foo_api
tags:
v1.0
v1.1
branches:
master
new_features