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

Fix recursive profile merging, particularly for umbrella apps #1606

Merged
merged 2 commits into from
Aug 13, 2017

Conversation

ferd
Copy link
Collaborator

@ferd ferd commented Aug 11, 2017

When a config file exists at the root of a project, defines a given
configuration value for a given profile, and that a sub-application
(umbrella app) also has the same profile defined with the same key (but
different values), the configuration values of the sub-application's
profile would get silently dropped.

The problem being that when the function to merge profiles is applied
recursively, it is applied to each profile (so it will merge on the keys
test, prod, etc.) rather than to each of the values of each profile.

This patch reworks the profile merging so that the current behaviour is
respected overall (a profile cannot be cancelled by a subdep's
non-existant profile since its value should have been ignored), but
ensures that sub-deps' profiles are otherwise applied recursively with
the proper rules:

  • dependencies favor prior values
  • plugins favor new values
  • erl_first_files combine the lists
  • relx uses the tuple merge algorithm
  • erl_opts has its own custom merge as well
  • otherwise the new value takes precedence

A test has also been added.

There is a risk of breakage in some applications that may have relied on
the buggy behaviour to work, though at this time we are aware of none of
them.

This fixes #1566, and possibly #1247, #1477 and #1368


This is kind of a scary change, awaiting reviews before pushing forwards.

When a config file exists at the root of a project, defines a given
configuration value for a given profile, and that a sub-application
(umbrella app) also has the same profile defined with the same key (but
different values), the configuration values of the sub-application's
profile would get silently dropped.

The problem being that when the function to merge profiles is applied
recursively, it is applied to each profile (so it will merge on the keys
test, prod, etc.) rather than to each of the values of each profile.

This patch reworks the profile merging so that the current behaviour is
respected overall (a profile cannot be cancelled by a subdep's
non-existant profile since its value should have been ignored), but
ensures that sub-deps' profiles are otherwise applied recursively with
the proper rules:

- dependencies favor prior values
- plugins favor new values
- erl_first_files combine the lists
- relx uses the tuple merge algorithm
- erl_opts has its own custom merge as well
- otherwise the new value takes precedence

A test has also been added.

There is a risk of breakage in some applications that may have relied on
the buggy behaviour to work, though at this time we are aware of none of
them.
true -> [];
false -> [{d, 'TEST'}]
true -> Opts;
false -> [{d, 'TEST'}|Opts]
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

not sure this changes anything in practice, but felt like a good gotcha

@@ -117,7 +117,10 @@ merge_opt(plugins, NewValue, _OldValue) ->
merge_opt({plugins, _}, NewValue, _OldValue) ->
NewValue;
merge_opt(profiles, NewValue, OldValue) ->
dict:to_list(merge_opts(dict:from_list(NewValue), dict:from_list(OldValue)));
ToMerge = fill_profile_gaps(lists:sort(NewValue),
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can you add a comment on what fill_profile_gaps is doing

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done; renamed, add type specs and comments.

@tsloughter
Copy link
Collaborator

I don't think we have much to worry about with regards to projects that relied on the buggy behaviour. Though I could be wrong about how many projects actually use sub-apps and sub rebar.configs, but I don't think it is that many.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Specifying macros in test profile in umbrella app does not seem to have an effect
2 participants