How to access values on leiningen profiles?
Asked Answered
N

2

14

I've got a two profiles defined in project.clj, one locally, one for testing on travis:

:profiles {:dev {:dependencies [[midje "1.6.0"]
                                [mysql/mysql-connector-java "5.1.25"]]
                 :plugins [[lein-midje "3.1.3"]]
                 :user "root" :pass "root"}
           :travis {:user "travis" :pass ""}}

I'm hoping to be able to get access to the :user and :pass values in my projects. How can this be done?

Update:

I also want to be able to use the lein with-profile command... so my tests would have:

lein with-profile dev test

-> would use "root", "root" credentials

lein with-profile dev,travis test

-> would use "travis", "" credentials

Norton answered 9/12, 2013 at 11:4 Comment(1)
I think this problem it's resolved here #16271305Toponymy
B
15

If you don't need the values defined in project.clj for anything else (IE, you're free to choose the representation) consider Environ.

You can then define the following in your project.clj

:profiles {:dev {:env {:user "root" :pass "root"}}}

and read the values:

(use 'environ.core)

(def creds
  {:user (env :user)
   :pass (env :pass)})

This has the advantage that you can also specify the values using environment variables and system properties.

Bengal answered 9/12, 2013 at 14:6 Comment(0)
S
7

Leiningen's build file is Clojure code so you can just read it in:

(->> "project.clj" slurp read-string (drop 3) (partition 2) (map vec) (into {})
     :profiles :dev)
; => {:dependencies [[midje "1.5.1"] [ring-server "0.2.8"]], :plugins [[lein-midje "3.1.0"]]}

If you need heavier functionalities (such as access to the final project map) then something like configleaf might be better suited.

Another way to manage this (which I've utilized quite often) is to have a separate config file for profile specific data:

example/profiles/travis/example/config.clj:

(ns example.config)

(def user "travis")
(def pass "")

example/dev-resources/example/config.clj:

(ns example.config)

(def user "root")
(def pass "root")

example/src/example/core.clj:

(ns example.core
  (:require [example.config :as config]))

(println config/user)

And you need to add the profile specific resource path to your project.clj:

:profiles {:travis {:resource-paths ["profiles/travis/"]}}
Skyway answered 9/12, 2013 at 11:19 Comment(4)
I've updated my question. it is dependent on the chosen profileNorton
@zcaudate, then you could try configleaf, it provides access to the final project map which has the selected profile merged in.Skyway
@zcaudate, I added another way to handle your use case, this does not require additional dependencies.Skyway
thanks for the two ways of configuring profiles. I'm going to select the eniron answer as that was the one that I used to implement the travis ci - github.com/zcaudate/manas but I upvoted and will definitely be using your approach on bigger projects.Norton

© 2022 - 2024 — McMap. All rights reserved.