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

Allow custom system-wide defaults to be configured for all component dirs #162

Merged
merged 9 commits into from
Apr 19, 2021

Conversation

timriley
Copy link
Member

@timriley timriley commented Mar 10, 2021

This PR rounds out the work done in #155, #157, and #158, and makes it possible to configure default values for all component dir settings directly on the container's config.component_dirs. For example:

config.component_dirs.loader = MyCustomLoader
config.component_dirs.default_namespace = "my_app"

# This dir will have the above values applied as defaults
config.component_dirs.add "lib"

This will be particularly useful e.g. for users configuring dry-system to work with an class autoloader like Zeitwerk, which would require the following defaults to be applied:

config.component_dirs.loader = Dry::System::Loader::Autoloading
config.component_dirs.add_to_load_path = false

Having to configure these manually for every added component dir would be a suboptimal configuration experience. Further, the existence of these default settings will make it possible for us to create a plugin to enable a simple use :zeitwerk one-liner in the future.

It should be noted that the order of configuring the defaults and adding component dirs does not matter. The defaults will be applied to added component dirs regardless of whether they have been configured before or after the dirs are added.

Along with this, this PR fleshes out the API documentation for Dry::System::Config::ComponentDirs and Dry::System::Config::ComponentDir.

This introduces one more BREAKING CHANGE for the upcoming release: the top-level loader setting has been removed, with a system-wide loader now possible to configure via component_dirs.loader.

FYI, I plan to squash all commits here when merging.

@timriley timriley force-pushed the default-settings-for-component-dirs branch 3 times, most recently from ca46b86 to e49c6f6 Compare March 16, 2021 12:04
Comment on lines +165 to +168
def configured?(key)
config._settings[key].input_defined?
end
Copy link
Member Author

@timriley timriley Mar 16, 2021

Choose a reason for hiding this comment

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

I had to dig into some dry-system internals here, but it vastly simplifies the logic of apply_defaults_to_dir above.

Previously I was having to inspect the current values for both the system-wide and individual dir settings, the compare them to the setting's own intrinsic default value, and then try and work out from those whether or not to apply the system-wide default. But this would fall down in the case of having a system-wide default that you want to opt out of by explicitly configuring your individual dir to use the intrinsic default value again.

For example:

component_dirs.default_namespace = "my_app"

component_dirs.add do |dir|
  # Explicitly provide nil here, even though it is already the "natural" default for this
  # setting, to opt out of the system-wide default configured above
  dir.default_namespace = nil
end

IMO, this is a reasonable behavior to support (really, I would consider our implementation buggy without supporting this), and without #configured? that I added to ComponentDirs and ComponentDir, it would not be possible to achieve this.

And really, the best case to make for this approach is that #apply_defaults_to_dir is just so easy to read now! if configured?(key) && !dir.configured?(key) – simple!

I'm pretty confident this aspect of dry-configurable will not change, but I wanted to flag it here for you to consider too. If anything, we could consider making a few more parts of it true public API, since this usage here shows that it's valuable.

Copy link
Member

Choose a reason for hiding this comment

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

I had to dig into some dry-system internals here

@timriley you mean dry-configurable internals, right?

Copy link
Member Author

Choose a reason for hiding this comment

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

@solnic Oops, yes, you're right, I did mean dry-configurable internals :)

@timriley timriley changed the title Allow defaults to be configured for component dirs Allow custom system-wide defaults to be configured for all component dirs Mar 16, 2021
@timriley timriley marked this pull request as ready for review March 16, 2021 12:57
@timriley timriley requested a review from solnic as a code owner March 16, 2021 12:57
@timriley timriley force-pushed the default-settings-for-component-dirs branch from 3f2d147 to aa46b3d Compare March 16, 2021 12:58
@timriley
Copy link
Member Author

timriley commented Mar 16, 2021

@solnic @flash-gordon @jodosha — this is done and ready for review! And with this, the new component_dirs feature is finally done done 😅

@timriley timriley force-pushed the default-settings-for-component-dirs branch from aa46b3d to e7612e3 Compare March 16, 2021 13:04
Copy link
Member

@jodosha jodosha left a comment

Choose a reason for hiding this comment

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

@timriley Nice one! 💯 I assume this would simplify a lot the internals of Hanami 2. 👍

Copy link
Member

@solnic solnic left a comment

Choose a reason for hiding this comment

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

Approved but I've got a couple of minor comments 🙂

Comment on lines +165 to +168
def configured?(key)
config._settings[key].input_defined?
end
Copy link
Member

Choose a reason for hiding this comment

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

I had to dig into some dry-system internals here

@timriley you mean dry-configurable internals, right?

lib/dry/system/config/component_dirs.rb Outdated Show resolved Hide resolved
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.

3 participants