Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
151 lines (105 sloc) 3.38 KB

Envy

Configuration switcher by an environment variable inspired by Perl's Config::ENV.

Usage

(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)

Description

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.

Configurations

Normal configurations

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")))

Merging

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|))

Common configurations

You can also define a common configuration which will be merged into every configurations.

(defconfig :common
  `(:application-root ,(asdf:component-pathname (asdf:find-system :myapp))))

Accessing to configuration

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

Tips

(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*)))

See Also

Thank cho45 for the great product. I feel envy to you :)

Author

Copyright

Copyright (c) 2013 Eitarow Fukamachi (e.arrows@gmail.com)

License

Licensed under the BSD 2-Clause License.