This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-09-26
Channels
- # arachne (4)
- # beginners (70)
- # bigdata (1)
- # boot (373)
- # braid-chat (3)
- # cider (4)
- # cljs-dev (10)
- # cljsjs (6)
- # cljsrn (27)
- # clojars (11)
- # clojure (114)
- # clojure-austria (1)
- # clojure-czech (2)
- # clojure-dusseldorf (2)
- # clojure-greece (7)
- # clojure-italy (2)
- # clojure-nl (6)
- # clojure-russia (15)
- # clojure-serbia (11)
- # clojure-spec (92)
- # clojure-uk (5)
- # clojurescript (183)
- # component (9)
- # cursive (28)
- # datomic (36)
- # editors (4)
- # emacs (1)
- # garden (11)
- # hoplon (155)
- # lein-figwheel (7)
- # mount (47)
- # om (97)
- # onyx (25)
- # proton (3)
- # rdf (3)
- # re-frame (80)
- # reagent (9)
- # ring-swagger (9)
- # spacemacs (1)
- # untangled (145)
- # vim (2)
Hello all, I know that the compiler define the order of creation, but is there any way to define the order manually?
you can control the start order by simply starting states explicitly vs. starting all with (mount/start)
yes, if you do (mount/start)
or (mount/start #'app.a #'app.c #'app.b #'app.d)
, it will start all 4 states (given that you only have these four) in the order they were discovered by the compiler
G'day! My apologies if this has been asked before (fwiw I spent a bit of time searching, but didn't find anything that seemed relevant). Is there an established way of having config specified via the command line (come in through -main [& args]
), but be handled from that point onward as "normal" mount state?
@deactivateduser10790 we just pass it in using mount's with-args
in our -main
:
(->
cli-config
mount/with-args
mount/start)
How do I refer to cli-config from other namespaces?
If you want to combine that with a static edn
file or something you can simply merge them in a config
state using mount/args
@deactivateduser10790: there are a few ways
1. mount/args
is one, but this would be "global" per app: i.e. any ns will be able to access it without requiring anything
2. another one would be to use a known config path (or just pass this path via mount/args
), but use it to create a state: https://github.com/tolitius/stater/blob/master/smsio/src/app/conf.clj#L12-L13
3. another would be to use something like cprop: https://github.com/tolitius/cprop where you can use all the -Dconf=config-path
(or any system props), or env vars, or classpath resource, etc..
Nice - thanks @manderson, @tolitius!
Yeah I like the idea of require
as the dependency graph of states, and would like to preserve that if I can.
(also because I want different "components" to be able to define additional state based on this config state)
cprop sounds interesting, though I don't like System properties much - I tend to use tools.cli to handle this kind of thing as "real" CLI parameters.
But great pointers - you've gotten me moving again!
@deactivateduser10790: sure, sys props is just one of many venues to get config(s). I usually just use a single config file (`.edn`) and override props at runtime depending on environment with ENV vars (just one way to do it). there are also cursors in cprop that I use a bit to not have to destructure very nested configs in multiple places: https://github.com/tolitius/cprop#cursors
Ah ok - and yeah my plan is to have a single central config file, with a single CLI arg that points to it at runtime.
configuring apps is an interesting subject, and also quite opinionated in our community 🙂 I prefer to use whatever makes sense for a given problem with no ground rules like 12 factor and others..
Bootstrapping is one place where things get squirrelly, I've found. 😉
right, just try several different approaches, see what works best, I found just slurping .edn
works great for little apps, whereas a config lib (i.e. cprop) comes very handy for larger apps: different modules, dockerized and overriden by envs, etc..
So am I right in thinking I could do something like (defstate config :start (load-config))
? Could this be done within a (def -main ...
, so that I can set the :file
based on CLI opts?
e.g. something like (not code checked, so probably contains syntax errors):
(defn -main [& args]
(let [config-file (parse-args args)]
(defstate config :start (load-config :file config-file))))
Ok. I guess I'm still not clear on how I can parse the args passed to -main, then put them in a mount state (which can be depended upon by other states via standard require
).
https://github.com/tolitius/mount#be-composing says you need to
(defstate config :start (load-config :file (mount/args)))
(defn -main [& args]
(-> (parse-args args)
(mount/with-args)
(mount/start)))
or something like that@deactivateduser10790: is (load-config)
your function or is it coming from a library (i.e. cprop
)?
If it is coming from cprop, it would work without needing to pass runtime mount/args, as cprop would look in two places for configuration files:
* classpath: for the config.edn
resource
* file system: for a path identified by the conf
system property (i.e. the one you can pass via -Dconf=[path]
)
in case the (load-config)
is your function, you could just access the system property directly:
(defn load-config [path]
(info "loading config from" path)
(-> path
slurp
edn/read-string))
(defstate config
:start (load-config (System/getProperty "conf")))
given that conf
is your property with a path to the your-config.edn
file (i.e. -Dconf=/opt/app/yourapp/conf/app-conf.edn
<< an example path)
Yeah the challenge is that I need to parse the args
passed into -main
in order to know what path to call load-config
with. It looks like mount's with-args
fn might be the missing link I'm looking for though (thanks @dm3!).