Contributing to devenv
Tags: devenv, nix, elm
Published: 2022-11-21 20:23:00

---
title: Contributing to devenv
published: true
description: A simple guide to make your first contribution to devenv
tags: devenv, nix, elm
# cover_image: https://direct_url_to_image.jpg
# Use a ratio of 100:42 for best results.
published_at: 2022-11-21 20:23 +0000
---

I wanted to contribute a bit to [devenv](https://github.com/cachix/devenv). I consider myself a novice nix user. Anything beyond a couple of recipes I know fall out of my comfort zone. Yet the goals of devenv plus how supportive the maintainers seems to be were enough to do an attempt.

> Build, share, and run your local development environments with a single command. Without containers.
> https://devenv.sh/

I want to cover how you could contribute to add support for the language, or improve an existing one.

There are many options of course, but a workflow that worked for my was

1. Install Nix+Cachix+Devenv as explained in https://devenv.sh/getting-started/
2. (Optional) Install [direnv](https://direnv.net/), most likely you already use this :-)
3. Fork and Clone https://github.com/cachix/devenv

The devenv repo defines both:
- a cli tool that will set up your environment
- a repository of devenv modules

The modules are a description of which nix packages should be downloaded and how they should be setup when devenv options are declared in the `devenv.nix` file of your project.

We are interested in the second aspect: the modules repository.

For contributing to those we actually don't need to build a new version of the cli (as long as we are not changing some core functionality of course).

When you create a new project powered by devenv you will have at least: 

- a `devenv.nix` file where you setup what languages/packages you want
- a `devenv.yaml` file that defines some pinning and source of truth to be used.

In particular `devenv.yaml`  there is a `input.devenv.url` key that points to the modules repository. By default points to `github:cachix/devenv?dir=src/modules` (defined in [flake.nix#L7](https://github.com/cachix/devenv/blob/329935d67aaf2ec75d9326098a749673525138c0/src/flake.nix#L7)), but we can override it! To a local path!

That's what happening in [examples/supported-languages](https://github.com/cachix/devenv/tree/329935d67aaf2ec75d9326098a749673525138c0/examples/supported-languages). The `input.devenv.url`  key points to the working copy `src/modules`. We can use this example as a playground or create a new empty project devenv.

If you choose to work on a new empty project, run `devenv init` in an empty folder and edit `devenv.yaml`:

```yaml
inputs:
  nixpkgs:
    url: github:NixOS/nixpkgs/nixpkgs-unstable
  devenv:
    url: path:/absolute/path/to/src/modules
```

After running `direnv allow`, or `devsenv shell` if you don't use `direnv` you should get the packages and languages defined in `devenv.nix`.

I added `languages.elm.enable = true;` to `devenv.nix` to get elm compiler and it works!

```console
% devenv shell
Building shell ...
Entering shell ...

elm --version
0.19.1
elm2nix --version
/nix/store/3szqhljvvkynvfi5gymfnxsiljpd6hmg-elm2nix-0.3.0/bin/elm2nix
hello from devenv
git version 2.38.1
```

But this does not come with `elm-format`. We want the formatter, always. That's the contribution we want to make. We could make the formatter optional, but it's so widely used in the elm community that I think we can install it always. What could be nice is a pre-commit hook integration to run it. That could be configurable, but let's stick to get the `elm-format` installed for now.

The package already exists in nixpkgs as `elmPackages.elm-format` so this should be easy.

Go to `src/modules/languages/elm.nix`, and add `elm-format` to the package dependency. Additionally add some advertisement you think pertinent. Unfortunately `elm-format`  does not returns it's version with `--version`, so we will just show that elm-format is indeed available.

```diff
--- a/src/modules/languages/elm.nix
+++ b/src/modules/languages/elm.nix
@@ -11,6 +11,7 @@ in
   config = lib.mkIf cfg.enable {
     packages = with pkgs; [
       elmPackages.elm
+      elmPackages.elm-format
       elm2nix
     ];
 
@@ -18,6 +19,8 @@ in
       echo elm --version
       elm --version
 
+      which elm-format
+
       echo elm2nix --version
       which elm2nix
     '';
```

Now, how we check if this changes are good?
If you followed along you should be on a devenv shell (via direnv or explicit `devenv shell` command).

Update the shell by either running `direnv allow` again, or exiting the devenv shell (`ctrl+D`) and entering again.

And that's it. You should have elm-format available.

[Submit a PR](https://github.com/cachix/devenv/pull/104)!

---

**Caveats for aarch64-darwin**

- I needed to comment out `pkgs.python3Packages.cairocffi` in [devenv.nix#L7](https://github.com/cachix/devenv/blob/329935d67aaf2ec75d9326098a749673525138c0/devenv.nix#L7) for devenv source to work on aarch64-darwin, thanks [@domenkozar](https://discord.com/channels/1036369714731036712/1036369758024650792/1043183592165097574)!