-
Notifications
You must be signed in to change notification settings - Fork 966
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature request: dynamic includes #122
Comments
This would indeed be nice, but it's a little tricky in practice for a few known reasons and possibly some unknown reasons. See https://github.com/typesafehub/config/blob/master/HOCON.md#includes for spec details. Right now the parameter to Right now Right now files are loaded standalone as their own Config, and then reference.conf gets stuck underneath and system properties stuck on top. if Another idea in the past has been to support only system properties (not references to the config itself) in filenames to include, but that would be confusing. For now, most people use |
For others looking up or wondering about this question, I should mention that there are a couple of ways to support custom include syntax in an application. One is to create a custom The other is to create a custom URL protocol in the usual Java way, see http://stackoverflow.com/questions/2537255/creating-custom-uri-scheme-using-uri-class and http://www.cooljeff.co.uk/2009/12/12/custom-url-protocols-and-multiple-classloaders/ for example. Then use I'm not saying either of these is necessarily worthwhile (they are probably more work than the problem being solved), but maybe someone would find them useful in some circumstances. |
Another idea here could be special-case support only environment variable and/or only system property substitution using a syntax which spelled that out. Something like |
#134 is potentially a different solution, something like:
But I've thought about it for literally 30 seconds so it might have issues. |
I was interested in doing something like this as well. I don't want to have a Procfile for my heroku deployments but i want the heroku server to have an enviornment variable that indicates which config file to use. I was hoping to put include ${?ENV_CONFIG} in my play apps applicaiton.conf and have it conditionally include that file if the EVN_CONFIG env variable was present. Something like this would have gotten me there. For now i'll use a Procfile and pass in the config via java properties |
on Heroku you can also set JAVA_OPTS in many cases (depending on exactly which setup you're using to launch the app). Like JAVA_OPTS='-Dconfig.file='. sbt-native-packager (new enough version) and sbt-start-script plugins support JAVA_OPTS. |
hmm..i tried those a bunch and never could get them to work |
there have been bugs in the past e.g. sbt/sbt-native-packager#47 but it depends on how you are doing things of course. |
not really doing anything special, heroku config:set JAVA_OPTS="-Dconfig.resource=application.qa.conf" and pushing the code, on app startup nothing in JAVA_OPTS appears to take. |
Yup it was java_opts vs JAVA_OPTS. somehow must be ref'ing the older version of native packager. thx |
I just ran into this issue, |
@havocp What do you think about adding special processing for this in To me, it only makes sense when we're talking about including files, not from classpath or URLs. I'm thinking of something like:
|
A few issues are:
Or another option is to follow the existing convention and require Combining those ideas, maybe Before getting bogged down in syntax though what would be helpful I think would be to try to think through the three ideas mentioned so far - env vars in includes (with whatever syntax), What are the new use cases that current mechanisms such as -Dconfig.file don't solve, that we want to address? A thing I think is challenging here is that people clearly expect Anyway the short version: I think the bulk of the work here is to figure out and articulate what makes sense... I hope this comment gives some idea of the considerations, but I don't know the answer yet. Any opinions / pros-and-cons / persuasive arguments ? Don't worry about implementation difficulty. Everything discussed so far I think isn't a big deal to code. |
Our use case is to include additional config from the users home directory. Environment variables and system properties would be sufficient for us. Something like As already mentioned by others, users do expect the In the case of the more regular syntax it will "just work" for maybe half of the users. When a referenced value inside |
I agree that something here would be nice. As the earlier comment notes, if you try implementing to do the full thing people expect (that Implementing it with only env vars / system properties is much easier, because it can be done file-by-file during file load, rather than during the later Anyway, something like this is probably worth pursuing. |
I'm totally in favor of just implementing it with env vars / system properties because it sounds doable and will probably help in many use cases. If we agree on a syntax I could even try to implement it. But I've to warn you in advance - I have no experience with scala yet :-) For me the risk of not being what people expect is worth being taken because:
|
The library is all Java, only the tests are in Scala, which is probably a good way to learn Scala in fact :-) The hardest part is probably to allow a "string concatenation" rather than only strings inside the include(), i.e. it should be If the parser throws an exception on undefined env/system values, then maybe that exception message could say "only env vars and system props are supported here, not values from the config itself" ? I'm not sure what issues you'd encounter but if you give it a shot you can always ask questions as you go either on gitter or here in the issue tracker. Don't be shy about that. |
Oh, i didn't recognize that it is mainly java. Just thought "typesafe ..." must be scala :-)
|
On 2), I would either preserve the whitespace or make it an error ... otherwise it's maybe not consistent. I guess preserving it is the path of least resistance. Does it make sense to support
|
Hey folks! We have a similar use case, where we want to hit a URL to retrieve the config:
Sadly, this doesn't work :-(. Any tips? |
Hi! I tried to make some good defaults by including a credentials file from the users directory, and failed... I understand havocp's point. It would be nice to see the strings within include directives treated specially. Introducing env as wrapper around is acceptable but without would be nicer. Maybe corner cases could occur with file names having $ or { in there names ... if this is possible at all. Environment variables are sufficient for my problem. Could it be a solution to add some more rules on other variables in order to allow those too without sacrificing the simplicity of the parser? (e.g. only variable definitions occured so far are accounted) |
Seems as this feature would be really beneficial to have, voting for it to be implemented asap |
up |
+1 ... also need this feature.. has anything been done in this area or is there a workaround? |
+1 for this feature ! Meanwhile, I use -Dconfig.file=production.conf for this purpose with a common configuration file included in each specific conf file. |
+1, I need it also |
Another need for this feature is :
|
+1 |
+1 |
For anyone wanting this, here's a custom file includer like @havocp talked about: import java.io.File
import com.typesafe.config.{ ConfigIncludeContext, ConfigIncluder, ConfigIncluderFile, ConfigObject }
class ParameterizedFileConfigIncluder private (
_fallback: ConfigIncluderFile with ConfigIncluder,
environment: Map[String, String])
extends ConfigIncluder
with ConfigIncluderFile {
def this() = this(null, sys.env)
def this(environment: Map[String, String]) = this(null, environment)
private val parser = "\\$\\{([^}]*)\\}".r
private def fallback: ConfigIncluderFile with ConfigIncluder = {
if (_fallback == null) {
throw new IllegalStateException("No fallback has been provided")
}
_fallback
}
override def withFallback(fallback: ConfigIncluder): ConfigIncluder = {
if (fallback eq _fallback) this
else
fallback match {
case file: ConfigIncluder with ConfigIncluderFile => new ParameterizedFileConfigIncluder(file, environment)
case _ =>
throw new IllegalArgumentException(
"ParameterizedFileConfigIncluder can only fallback to a ConfigIncluderFile")
}
}
override def include(context: ConfigIncludeContext, what: String): ConfigObject =
fallback.include(context, what)
override def includeFile(context: ConfigIncludeContext, what: File): ConfigObject = {
val substitutedFile = new File(
parser.replaceAllIn(
what.getPath,
regexMatch => {
val varName = regexMatch.group(1)
environment.getOrElse(varName, "")
}))
fallback.includeFile(context, substitutedFile)
}
} That just reads from environment variables but could be trivially modified to read from system properties instead/as well. It can be used like so: ConfigFactory.load(
"application",
ConfigParseOptions.defaults().setIncluder(new ParameterizedFileConfigIncluder()),
ConfigResolveOptions.defaults()
) |
And what about creating a new "include eager ..."? This way you can ignore all the lazy resolutions, etc. The "eager" basically says that "it will be included with whatever values I have up to now, so for env variables and simple things it will work, but don't use messy things". |
+1 |
It will be nice to be able to do this
and somewhere else do
to allow different configuration files to be loaded based on other keys
The text was updated successfully, but these errors were encountered: