How do I get the environment name when using environ in Clojure? - clojure

How do I get the environment name when using environ in Clojure? I mean, :dev, :test, etc. The reason for wanting this is to pass it to Yeller so when it displays errors it can tell me which environment they happened into. Errors in staging are treated differently than errors in production.

Environ only provides access to environment variables, you need to set them yourself. You can use lein-environ to set environment variables in your project.clj in different profiles. These profiles will be picked by leiningen and merged together, which you can then access from your code. For example, we have:
:profiles {:dev {:resource-paths ["test-resources"]
:env {:environment "development"
:db-host "localhost"
:port 5000}}}
In production we provide actual environment variables instead.

Just the same as you want to "Tell, don't ask" in your code, you need to just use the config options and let environ figure out what the right one is based on the environment. In the rare event that you actually need the environment name itself just put it in the :env map for each environment.

Related

EmberJS change environment variables (e.g. rootURL) at runtime

I need to change the environment variable rootURL at loading time, depending on some global js variable (_ENV), which denotes Symfony's current environment.
So, if accessing the app via http://somedomain.com/app/ it should be rootURL = '/app/'.
If accessing via http://somedomain/app_dev.php/app/ it should be rootURL = '/app_dev.php/app/'.
Many thanks!
It's impossible to change environment.js variables at runtime, because they are for building an app. At runtime you can only access them. You may set them different for different environments - use app_dev for development and app for production, for example. And you don't need to change rootURL, you need to change adapter's config (host and prefix) depending on environment.

Where should I save simple configuration settings?

In my clojure Luminus/Compojure app I have this in routes.clj:
(def page-size 12)
(def images-path "/public/images/.....")
I need to move them to a config of some sort. Where is the best place? I'd like something simple and not to use any additional library on top on the ones that I'm already using which come with Luminus.
Luminus uses it's config library for configuration. You can put your configuration variables into appropriate config.edn files (per environment). Config values are available as a map stored in config.core/env. You can see an example in your <app>.core namespace:
(defn http-port [port]
;;default production port is set in
;;env/prod/resources/config.edn
(parse-port (or port (env :port))))
Ask yourself this question:
Would I ever want multiple deployments of my application where this setting differs?
If the answer to that question is "yes" then the configuration should be dictated by the environment running you application either by an edn file, Environ or other means.
If not... then you are talking about something I would categorize as an application constant, which helps avoiding magic numbers. In some situations it can improve readability by placing these in specific namespaces like so.
Constants namespace:
(ns my.app.constants)
(def page-size 12)
(def images-path "/public/images/.....")
Application:
(ns my.app.core
(:require [my.app.constants :as const)
;; now access the application constant like this
;; const/page-size
(defn image-url [image-name]
(str const/images-path "/" image-name))

Accessing profiles.clj data from within project.clj

I am trying to use Joplin and was thinking about tackling the issue hinted at in this issue.
Well, I want to store sensitive information outside of version control. I was thinking of using a profiles.clj file with environment information for each database. So, I could make a dev profile with an SQL database username and a password. So inside profiles.clj:
{:dev {:db {:user "dirtymike" :password "secret"}}}
But then in project.clj, I have to pass this to the :joplin map entry of defproject. Is that even possible?
You may want to look into environ. It does pretty much what you want to do in a slightly different way.
Maybe this blog post will help you http://blog.martinhynar.cz/2014/10/14/Project-clj-data-into-runtime.html

Clojure REPL and workflow

Coming from Haskell, my usual workflow would be to :l <file name.hs> on ghci and use the functions and ADT that I have there.
Right now I am using lein repl on a typical lein new app project context. I have created a testing.clj file next to my core.clj. There I defined a couple of functions, a protocol and a record implementing the protocol. I was able to use the function by (use 'testing.testing :reload) the problem is that I am not able to use the actual record:
(def c (Something. 0))
I get:
CompilerException java.lang.IllegalArgumentException: Unable to resolve classname: Something
So, what would be the a "better" workflow in this case? Where I don't want to set the functions, protocols, records directly on the REPL, but also I don't want to rely on my core.cls file? I just want a file where I can dump a bunch of stuff and play with it.
PS: My env is Mac OSX Terminal + Sublime
Edit: After a couple of minutes I was able to load the record by:
(load-file <file name>)
(import 'testing.testing.Something)
I mean, for sure there is a better way than this... :/ I just want to load everything. On the other hand I am able to use the protocol methods the record implements.
Have you tried using the convenience function that is automatically defined for creating records? In this example it would be (->Something 0).
(Something. 0) is using the Java constructor, which requires importing the Java class separately. The Java class is created automatically when you define a record to allow Java interop with things you've defined in Clojure.
Using the (->Something 0) syntax is the correct way to go and should be possible after you (use 'testing.testing :reload).
Edit Given the above didn't seem to help, here's some step-by-step instructions to get a minimal working example
You have an app directory testing created with lein new app testing
In testing/src/testing you create testing.clj containing the following two lines
(ns testing.testing)
(defrecord Something [n])
Run lein repl from within your project directory
Use the namespace with (use 'testing.testing :reload)
(:n (->Something 42)) will create an instance of Something and retrieve the value of its n member - in this case 42.

What is the variable that indicates the environment in Django?

In Rails, there's an environments variable called RAILS_ENV that tells you which environment you're in. Other than creating my own environment variable, is there a default one that tells you which environment you are in in Django?
As mipadi said, there's no "official" variable like Rails has. There's nothing to stop you from creating your own though. You could use the method S. Lott suggested to separate your settings out into separate files and inside each one have a line like:
DJANGO_ENV = 'Production'
Then you could easily access it anywhere:
from django.conf import settings
if settings.DJANGO_ENV == 'Production':
print "I'm in production!"
Django doesn't have quite the same concept of "environment" like Rails' "production", "development", and "test". The closest thing is the DEBUG variable (set your Django project's settings.py file), which should be True for development and False for production. Outside of settings.py, you can obtain it with:
from django.conf import settings
print settings.DEBUG
Often, many things change between "environments".
We have separate settings files for each environment.
Each environment-specific file starts with
from settings import *
To bring in the default settings for the application as a whole.
We have settings_dev, settings_checkout, settings_qa, settings_prod, etc.