# Mostly clueless

but curious to find out
Jun 03, 2015

# Managing Local and Project-wide Development Parameters in Leiningen

Little tip. Long headline.

In any project there are often settings that are specific to the context the project is run in (think of an `environment` parameter) and then there are parameters that are specifc to the developer/workstation they're run on. This is a guide to separate these two things nicely in Leiningen-based Clojure projects.

So you have a project setup that uses environ to determine the context the project is run in (`development` vs. `production`).

    ; in project.clj:
    (defproject your-app "0.1.0-SNAPSHOT"
      ; ...
      :profiles {:dev {:env {:environment "development"}}})

Now you also want to use environment variables (or anything else thats supported by environ) to store AWS credentials to access Amazon S3. You don't want to commit these credentials into version control, therefore you can't add them to `project.clj`. The way to go is to create a file `profiles.clj` in your project to store workstation specific information. Naively this could look something like this

    {:dev {:env {:aws-access-key "abc"
                 :aws-secret-key "xyz"
                 :s3-bucket "mybucket"}}}

If you run your project with this `profiles.clj` you will be able to access your AWS credentials. You might also notice that `(environ/env :environment)` is nil. That wasn't intended.

The problem here is that Leiningen will override keys in profiles defined in `project.clj` if the same profile has also been defined in `profiles.clj`. To recursively merge Leiningen profiles combine them like so:

    ;; in project.clj:
    (defproject your-app "0.1.0-SNAPSHOT"
      ;; ...
      :profiles {:dev [:project/dev :local/dev]
                 :project/dev {:env {:environment "development"}}})

    ;; in profiles.clj
    {:local/dev {:env {:secret-key "xyz"}}}

Now both, `:envrionment` and `:secret-key` should be defined when you retrieve them using environ.

This is largely inspired by James Reeves' duct Leiningen template.