Skip to content
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

Framework: Cascading Configs #876

Merged
merged 17 commits into from
Feb 16, 2016
Merged

Framework: Cascading Configs #876

merged 17 commits into from
Feb 16, 2016

Conversation

mjangda
Copy link
Member

@mjangda mjangda commented Nov 27, 2015

Problem

We have a config file for each environment we support; that's seven different files as of now. More could be added in the future. However, because each config file lives on its own, it means that we need to duplicate entries across each of the files even though in many cases, the values are exactly the same, regardless of the environment.

(Suggested) Solution

We can start with a base config file that will contain all our shared config values. We can then merge in environment-specific config values via ${env}.json files. As an added bonus, we can allow local-only overrides via ${env}.local.json (gitignored) in case developers want to change things locally without touching the main configs.

The PR extracts the config reading bits into a new module to reduce the duplicated bits between the server config and the client config generator.

We use something like this for Mesh and it works really well.

Looking for feedback on this before I expand it any further (tests, etc.).

@mjangda mjangda added [Type] Enhancement Changes to an existing feature — removing, adding, or changing parts of it Framework [Status] In Progress labels Nov 27, 2015
configPaths = [
'__base.json',
opts.env + '.json',
opts.env + '.local.json'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

*.local.json seems to be a nice addition 👍

@gziolo
Copy link
Member

gziolo commented Nov 27, 2015

I really like this PR! Thanks for taking care of it :)

I have one more comment. At the moment we reference config module not only in /server/ and /client/ code where we have respective config modules. The trick is that we reference config module also in /shared/ folder, which enforces to add /client/ folder to NODE_PATH for files that import config and are tested with Mocha. It would be awesome to solve also this issue some day.

Also please note that we duplicated 3 functions in config files on client and server:

  • config
  • isEnabled
  • anyEnabled

Of course this is a scope for another PR, but I couldn't resist to add it here :)

@artpi
Copy link
Contributor

artpi commented Nov 27, 2015

Mo, I really really like this idea and I was arguing for this exact approach and remember @rralian and @gwwar were against it.
As I recall, the biggest concern was that at runtime you are not really sure what is the current config
Right now you just have to look in one file

I like what you did though, but maybe we need a bit more discussion?

@artpi
Copy link
Contributor

artpi commented Nov 27, 2015

And by discussion I mean: waiting a bit until people wake up from food coma / long weekend :)

@gziolo
Copy link
Member

gziolo commented Nov 27, 2015

As I recall, the biggest concern was that at runtime you are not really sure what is the current config
Right now you just have to look in one file

I don't think this is an issue, because client/config/regenerate.js creates one config file for you (look at client/config/index.js) :)

@artpi
Copy link
Contributor

artpi commented Nov 27, 2015

I see it and as I said - I like it, this is awesome!
Just pointing out what I heard :)

@mjangda
Copy link
Member Author

mjangda commented Dec 2, 2015

Also please note that we duplicated 3 functions in config files on client and server

Yep, I resisted that in this PR but was thinking of tackling it if/after this ships :)

@mjangda
Copy link
Member Author

mjangda commented Dec 2, 2015

If we decide that the cascading configs is a no-go, I'll just extract the config/reader bits into a separate PR as I think that's still useful.

@rralian
Copy link
Contributor

rralian commented Dec 2, 2015

I was arguing for this exact approach and remember @rralian and @gwwar were against it.

@artpi I don't remember such a discussion (if you can find it that would be helpful). I think we probably just misunderstood each other one way or another. I don't have any concerns jumping out at me about this. I agree that it would be nice to move reader.js out of /config so /config only contains .json files. I also would like to find a different name for reader.js. Considering the reader is a significant feature of calypso, that's bound to cause confusion. I know my first thought when looking at the list of files was "why would the reader have a separate config file?".

It looks like there are other items we could move into shared.json. Maybe that's what you meant about wanting early feedback before going further @mjangda. But languages is a huge list that could be moved into shared.json. It probably doesn't belong in config at all considering it's not something we're likely to "configure" by environment. Although maybe it makes more sense as a configuration now that Calypso is public and fork-able.

@mjangda
Copy link
Member Author

mjangda commented Dec 2, 2015

It looks like there are other items we could move into shared.json

Yeah, I moved discover_blog_id as an example. Definitely lots more we could move to the shared file like languages, as you mention.

@gziolo
Copy link
Member

gziolo commented Jan 26, 2016

Any progress on this one?

Our config file are getting out sync very quickly. See this: https://github.com/Automattic/wp-calypso/pull/2782/files. Those PR would mitigate most of the issues.

@mjangda
Copy link
Member Author

mjangda commented Jan 29, 2016

Got sidetracked by other stuff but going to pick this up again today.

@mjangda mjangda force-pushed the try/config-overrides branch 2 times, most recently from 86d7782 to f948137 Compare February 2, 2016 02:49
@mjangda
Copy link
Member Author

mjangda commented Feb 2, 2016

Okay, took a another shot at this:

  • Config files live in /config.
  • Config logic now lives entirely in /server/config.
  • /client/config just contains the generated index.js.
  • Renamed reader.js to parser.js to avoid confusion.
  • parser.js is now pretty standalone and all environment-specific stuff has been stripped out to be passed in as args instead.
    • Bonus: duplicate functions between client and server are now not duplicated anymore.
  • Now includes some tests for the parser (not the greatest suite, but better than nothing?).

I have not moved any other config values either. I think that should be left for other PRs.

Plus, the readme files need an update.

/cc @artpi @gziolo @rralian

@mjangda mjangda added [Status] Needs Review The PR is ready for review. This also triggers e2e canary tests and wp-desktop tests automatically. and removed [Status] In Progress labels Feb 2, 2016
@rralian
Copy link
Contributor

rralian commented Feb 15, 2016

@mjangda I'm sorry this has languished for so long. I just walked through everything and I think this is really great. Tests all look good and the logic makes sense. I agree that we'll want some additional documentation to explain the additional features and how to use them. But I wouldn't hold up this PR for the documentation.

One thing though, I think that feature flags should still be set specifically for each environment. I realize your PR would leave this convention in place, but it should probably be called out in the documentation that we would not want "features" to live in the _shared config ever.

Looks like the PR needs a rebase. If that's clean and good I'd give this a 👍. If the rebase is more involved, let me know and I can give this another look when you're done.

@rralian rralian added [Status] Ready to Merge and removed [Status] Needs Review The PR is ready for review. This also triggers e2e canary tests and wp-desktop tests automatically. labels Feb 15, 2016
@rralian
Copy link
Contributor

rralian commented Feb 15, 2016

BTW, one of the reasons I'm eager for this PR is so I can enable the React visualizer for performance tuning via:

ENABLE_FEATURES=render-visualizer make run

And allow for cascading config files. This allows us to start with a
base file shared across all environments, an environment-specific
config file, and then local overrides.
The discover_blog_id is now defined in out base file instead of each
individual config.
shared is a clearer name. We also retain the `_` to sort this file at
the top of most editors / file browsers.
And pass in a config path instead of traversing
Let's keep everything related to reading/parsing/building config in one
place so it's easier to maintain. This way, the client config folder can
just be purely generated.
Previously, we were defining the config functions in both the module and
the regenerate file. We can just reuse the definition from the module.
Since it's necessary for the parser.
Rather than accessing env vars directly in the module. Makes the module
testable and less-env specific.
@mjangda mjangda force-pushed the try/config-overrides branch from f948137 to 8c0fb1c Compare February 16, 2016 17:17
@mjangda
Copy link
Member Author

mjangda commented Feb 16, 2016

Thanks @rralian! The rebase was pretty clean (just small config updates) so going to merge and will look into docs shortly.

mjangda added a commit that referenced this pull request Feb 16, 2016
@mjangda mjangda merged commit f5e708f into master Feb 16, 2016
@mjangda mjangda deleted the try/config-overrides branch February 16, 2016 17:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Framework [Type] Enhancement Changes to an existing feature — removing, adding, or changing parts of it
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants