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

Merge config recursively #1176

Merged
merged 1 commit into from May 13, 2017
Merged

Conversation

@gpakosz
Copy link
Member

@gpakosz gpakosz commented May 7, 2017

I faced the following situation:

  • I want nanoc.yaml to only define the rsync deployment url
  • I want a parent nanoc.yaml to define other rsync options

parent.yaml

deploy:
  default:
    kind: rsync
    options:
      - --verbose
      - --progress
      - --recursive
      - --links
      - --chmod=D755,F644
      - --times
      - --partial
      - --progress
      - --compress
      - --delete-during
      - --force
      - --exclude='.git'

nanoc.yaml

deploy:
  default:
    dst: 'example.com:/srv/www'

parent_config_file: _factory/nanoc.yaml

Without merging hashes recursively, parent config gets completely overridden.

@gpakosz
Copy link
Member Author

@gpakosz gpakosz commented May 7, 2017

Please discuss the naming of merge_recursively as well as where it should be defined. At the time of writing this comment, I realize merge_recursively could be added to lib/nanoc/base/core_ext/hash.rb.

Also, I didn't find tests related to parent_config_file in configuration_spec.rb and I didn't know how do write a test that involves an existing parent config file.

Loading

@gpakosz gpakosz force-pushed the merge-config-recursively branch from f5be7aa to 2764c11 May 7, 2017
@ddfreyne
Copy link
Member

@ddfreyne ddfreyne commented May 8, 2017

I’m concerned about this change because it changes existing behavior (“overwrite” becomes “merge”), and the change is therefore not backwards-compatible.

An alternative suggestion would be to qualify how the parent file gets loaded. For instance:

parent_config_file:
  filename: _factory/nanoc.yaml
  method: merge
parent_config_file:
  filename: _factory/nanoc.yaml
  method: overwrite

Loading

@gpakosz
Copy link
Member Author

@gpakosz gpakosz commented May 8, 2017

Although this is a behavior change, I doubt anyone would really expect overwrite instead of merge. I also doubt this feature is widely used :)

See it as bug fix!

Loading

@ddfreyne
Copy link
Member

@ddfreyne ddfreyne commented May 8, 2017

It turns out that parent_config_file is not documented at all.

Loading

@gpakosz
Copy link
Member Author

@gpakosz gpakosz commented May 9, 2017

Writing down here the fact that I scanned ~500 Nanoc sites on GitHub and none uses parent_config_file.

The idea behind parent_config_file is to have inheritable defaults that can be tweaked. I believe the default case is to union hashes but override values which is what #merge_recursively() achieves.

    def merge_recursively(c1, c2)
      c1.merge(c2) { |_, i1, i2| i1.is_a?(Hash) && i2.is_a?(Hash) ? merge_recursively(i1, i2) : i2 }
    end

If you really want to cancel out a hash value that has been populated by a parent config file, you can still do key: nil explicitly:

# this site doesn't want deployment at all
deploy: nil

parent_config_file: _common/nanoc.yaml

In that respect, this PR should be seen as bug fixing rather than enhancement. I don't see any advantage in complexifying parent_config_file's syntax.

Loading

@ddfreyne
Copy link
Member

@ddfreyne ddfreyne commented May 10, 2017

Makes sense! Given that

  • this hasn’t been documented
  • making this change breaks no tests
  • there is no usage of parent_config_file anywhere

… I’m OK with treating this as a bug fix instead.

The config loader specs are in config_loader_spec.rb; could you add relevant tests there?

Loading

@gpakosz
Copy link
Member Author

@gpakosz gpakosz commented May 11, 2017

I added a test for #merge() in configuration_spec.rb. I decided to test in configuration_spec.rb instead of config_loader_spec.rb because the guts of the change are really in Configuration#merge() behavior.

Loading

@gpakosz gpakosz force-pushed the merge-config-recursively branch from 650f83d to ffb56dc May 11, 2017
@ddfreyne
Copy link
Member

@ddfreyne ddfreyne commented May 13, 2017

Looks good!

Loading

@ddfreyne ddfreyne merged commit 182de20 into nanoc:master May 13, 2017
3 checks passed
Loading
@gpakosz
Copy link
Member Author

@gpakosz gpakosz commented May 13, 2017

Thanks

Loading

@gpakosz gpakosz deleted the merge-config-recursively branch Nov 2, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

None yet

2 participants