subverting Elm packaging since 2019
status: works for me, might eat your files
shelm
is a bash wrapper around the elm
tool that allows bypassing
the Elm packaging infrastructure.
It allows you to
- depend on Elm packages that have not been published to package.elm-lang.org, such as versioned Github releases, local paths or arbitrary git urls.
- work with native Javascript code: Depend on modified versions of core
Elm modules or write your own kernel modules by placing a package within
the
elm/
orelm-explorations/
package namespace.
Note: Best not talk about this on the offical Elm channels unless you're trolling.
shelm
expects to be called from the top level directory of an Elm project,
which contains an elm.json
file. The basic workflow is: First call
shelm fetch
to download dependencies into the local package cache. Then
call shelm make
as you would usually call elm make
. (Other elm
subcommands
are passed through, too, but might not work.)
With a regular elm.json
, there should be no functional difference to normal
elm
tool use. To make use of shelm
's extra features, you might:
-
Add dependencies for a packages that have not been released to the Elm package repository. Suppose you have an Elm package in a GitHub repository
me/elm-experiment
that you haven't published usingelm publish
. Then if you tag a commit as "1.0.0", depending on"dependencies": { "direct": { ... "me/elm-experiment": "1.0.0", ...
in
elm.json
as usual will makeshelm
download the 1.0.0 release. -
Specify alternative locations for dependencies. E.g., to use a patched version of the
elm/time
package that's published atgithub.com/me/elm-time
, you would change the dependency section ofelm.json
to read"dependencies": { "direct": { ... "elm/time": "1.0.0" }, "indirect": { ... }, "locations": { "elm/time": { "method": "github", "name": "me/elm-time" } } }
See below for full documentation of the
"locations"
field.
shelm
currently supports the following location types:
github
Parameters: name
as "author/project".
Tagged GitHub releases, as used by regular elm
packages. Downloads the
source archive for the release specified by the dependency version.
See above for an example.
file
Parameters: path
as a local directory.
Copies over the given path as the source.
E.g., if you're developing my-fancy-gui-toolkit
and want to test
it in my-flashy-app
before publishing, you might tweak my-flashy-app
's
elm.json
to include
"locations": {
"me/my-fancy-gui-toolkit": {
"method": "file",
"path": "../my-fancy-gui-toolkit"
}
}
git
Parameters: url
as a git url, ref
as a branch/tag/commit (defaults to version).
Checks out the given reference from the given git repository.
E.g., to build your application against the upstream development version
of elm/time
,
"locations": {
"elm/time": {
"method": "git",
"url": "https://github.com/elm/time.git",
"ref": "master"
}
}
The elm
tool error messages are explicitly unhelpful if something goes wrong
compiling dependencies. If you get some complaints about corruption or version
conflicts, chances are that shelm
or your elm.json
setup is at fault. Wiping
elm-stuff
and calling shelm fetch
again is a good first try.
It's important that both elm make
and elm make --docs=docs.json
works for
each dependency.
It's your responsibility to make sure that the source archive pointed at by a location actually has the same version as listed in the dependencies. Things are likely to go wrong if those don't align.
Elm compiler
The elm
tool should be in the path. Versions 0.19.0 and 0.19.1 are supported.
jq
The jq JSON processor is used to read elm.json
.
curl, git, tar
git
is required for the "git" location method, curl
and tar
for the default
"github" archive method.
shelm manages its own local copy of the Elm package database in
elm-stuff/home/.elm
, by downloading source archives using a variety
of measures, and generating a matching package registry.
It calls elm
with $HOME
pointed at this directory and networking
disabled by setting an invalid $HTTP_PROXY
variable.
The following two articles go into this with a bit more detail:
- https://vllmrt.net/spam/guix-elm-2.html describes a Guix build system for Elm applications that uses the same techniques.
- https://vllmrt.net/spam/subverting-elm.html shows how shelm came about when figuring out how to build an Elm app with native code.