Configuration switcher by an environment variable inspired by Perl's Config::ENV.
(defpackage :myapp.config
(:use :cl
:envy))
(in-package :myapp.config)
(setf (config-env-var) "APP_ENV")
(defconfig :common
`(:application-root ,(asdf:component-pathname (asdf:find-system :myapp))))
(defconfig |development|
'(:debug T
:database-type :sqlite3
:database-connection-spec (:database-name "sqlite3.db")))
(defconfig |production|
'(:database-type :mysql
:database-connection-spec (:database-name "test"
:usename "whoami"
:password "1234")))
(defconfig |staging|
`(:debug T
,@|production|))
(defpackage :myapp
(:use :cl)
(:import-from :envy
:config)
(in-package :myapp)
(getf (config :myapp.config) :database-type)
For example, APP_ENV=development sbcl
runs a REPL process that uses development config values.
Envy is a configuration manager for various applications.
Envy uses an environment variable to determine a configuration to use. I'm not sure this is ideal even for Common Lisp applications, but this can separate configuration system from an implementation.
ENVY:DEFCONFIG
is a macro for defining a named configuration.
Don't forget to set (ENVY:CONFIG-ENV-VAR)
which is a name of environment variable to determine a configuration.
(setf (config-env-var) "APP_ENV")
;; Use SQLite3 for development
(defconfig |development|
'(:server :hunchentoot
:database-type :sqlite3
:database-connection-spec (:database-name "sqlite3.db")))
;; Use MySQL in production environment
(defconfig |production|
'(:server :fcgi
:database-type :mysql
:database-connection-spec (:database-name "test"
:usename "whoami"
:password "1234")))
Each configurations are represented as property lists. It means you can merge them by the default way of merging lists -- cons, append or/and splicing unquote.
(defconfig |staging|
`(:server :hunchentoot
,@|production|))
You can also define a common configuration which will be used by all configurations.
(defconfig :common
`(:application-root ,(asdf:component-pathname (asdf:find-system :myapp))))
ENVY:CONFIG
is an accessor to get the current configuration.
(config :<configuration-package-name>)
(config :myapp.config)
;=> '(:server :hunchentoot
:database-type :sqlite3
:database-connection-spec (:database-name "sqlite3.db")
:application-root #P"/path/to/application/")
(getf (config :myapp.config) :database-type)
;=> :sqlite3
(defpackage myapp.config
(:use :cl
:envy)
(:shadow :envy
:config)
(:export :config))
(in-package :myapp.config)
(defconfig :common
...)
;;
;; ... Configurations ...
;;
(defun config ()
(envy:config #.(package-name *package*)))
Thank cho45 for the great product. I feel envy to you :)
- Eitarow Fukamachi (e.arrows@gmail.com)
Copyright (c) 2013 Eitarow Fukamachi (e.arrows@gmail.com)
Licensed under the BSD 2-Clause License.