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

feat: Allow to include files for RR root configuration #38

Merged
merged 8 commits into from
Nov 8, 2023

Conversation

cv65kr
Copy link
Member

@cv65kr cv65kr commented Nov 7, 2023

Reason for This PR

closes: roadrunner-server/roadrunner#935

Description of Changes

Merging configurations from multiple files by include property

License Acceptance

By submitting this pull request, I confirm that my contribution is made under
the terms of the MIT license.

PR Checklist

[Author TODO: Meet these criteria.]
[Reviewer TODO: Verify that these criteria are met. Request changes if not]

  • All commits in this PR are signed (git commit -s).
  • The reason for this PR is clearly provided (issue no. or explanation).
  • The description of changes is clear and encompassing.
  • Any required documentation changes (code and docs) are included in this PR.
  • Any user-facing changes are mentioned in CHANGELOG.md.
  • All added/changed functionality is tested.

Summary by CodeRabbit

  • New Features
    • Introduced a new configuration reading function that supports file and environment variables.
    • Added support for including additional configuration files.
    • Implemented automatic injection of environment variables into configurations.
  • Bug Fixes
    • Removed duplicate code for retrieving configuration version.
  • Tests
    • Added new tests for configuration loading and version consistency.
  • Refactor
    • Improved comments and error messages for better clarity and consistency.

@cv65kr cv65kr requested a review from rustatian November 7, 2023 18:23
Copy link

coderabbitai bot commented Nov 7, 2023

Walkthrough

The changes introduced in this diff primarily focus on enhancing the configuration management of the application. A new function getConfiguration is added to read configuration settings from a file and environment variables. The handling of included configuration files is improved, and the configuration version is now retrieved and validated. New test functions are introduced to validate these changes. Additionally, new configuration files are added for server, HTTP settings, and logging.

Changes

File Change Summary
configuration.go
plugin.go
Introduced a new function getConfiguration to read configuration settings from a file and environment variables. Added logic to handle included configuration files and retrieve the configuration version.
tests/configs/... Introduced new configuration files for server, HTTP settings, and logging.
tests/plugin_test.go Added new test functions to validate the loading of configurations from multiple files and checking for version consistency.

Poem

🍂 As the leaves fall this November day, 🍁

Code changes dance in a ballet. 🩰

Configurations read, versions checked, 📜

In our codebase, beautifully decked. 💻

Tests ensure all is right, 🧪

As we code into the night. 🌙

Celebrating this day in history, 🎉

Our code changes remain no mystery. 🕵️‍♀️

So here's to the coders, steady and bold, 💪

Crafting stories in the code they've told. 📖


Tips

Chat with CodeRabbit Bot (@coderabbitai)

  • If you reply to a review comment from CodeRabbit, the bot will automatically respond.
  • To engage with CodeRabbit bot directly around the specific lines of code in the PR, mention @coderabbitai in your review comment
  • Note: Review comments are made on code diffs or files, not on the PR overview.
  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Commands (invoked as PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger a review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai help to get help.
  • @coderabbitai resolve to resolve all the CodeRabbit review comments.

Note: For conversation with the bot, please use the review comments on code diffs or files.

CodeRabbit Configration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • The JSON schema for the configuration file is available here.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/coderabbit-overrides.v2.json

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Review Status

Actionable comments generated: 4

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 0c0c6c5 and fe730fb.
Files selected for processing (8)
  • configuration.go (1 hunks)
  • plugin.go (4 hunks)
  • tests/configs/.rr.include1-sub1.yaml (1 hunks)
  • tests/configs/.rr.include1-sub2.yaml (1 hunks)
  • tests/configs/.rr.include1.yaml (1 hunks)
  • tests/configs/.rr.include2-sub1.yaml (1 hunks)
  • tests/configs/.rr.include2.yaml (1 hunks)
  • tests/plugin_test.go (2 hunks)
Files skipped from review due to trivial changes (1)
  • tests/configs/.rr.include2-sub1.yaml
Additional comments: 8
tests/configs/.rr.include1-sub2.yaml (1)
  • 1-6: The new configuration file looks good. It's clear and concise, and it follows the YAML syntax correctly. The logging settings are well defined. Ensure that these settings are appropriate for your application's needs.
tests/configs/.rr.include1-sub1.yaml (1)
  • 1-16: This new configuration file looks good. It specifies the server command, relay method, HTTP address, middleware, pool settings, and a reload interval. Ensure that these settings are appropriate for the intended use case.
tests/configs/.rr.include1.yaml (1)
  • 1-9: The configuration file seems to be correctly formatted and includes the necessary fields. Ensure that the included files ".rr.include1-sub1.yaml" and ".rr.include1-sub2.yaml" exist and are in the correct location. Also, verify that the reload interval and patterns are appropriate for your use case.
tests/configs/.rr.include2.yaml (1)
  • 1-8: The configuration file seems to be correctly formatted and includes another configuration file, .rr.include2-sub1.yaml. Ensure that this included file exists and is in the correct location. The reload interval is set to 1 second and the pattern is set to watch for changes in .php files. This seems reasonable if the server is expected to handle PHP files and needs to reload frequently.
configuration.go (1)
  • 10-29: The function getConfiguration reads configuration settings from a file and environment variables using the viper package. It also retrieves a configuration version from the settings. Error handling is done for configuration reading and version retrieval. Ensure that the function is used correctly throughout the codebase and that the configuration files and environment variables are set up properly.
plugin.go (3)
  • 4-10: The new import "path/filepath" is used for handling file paths in a cross-platform way. This is a good practice.

  • 15-21: The new constant "includeKey" is used to get the "include" key from the configuration. This is a good practice to avoid hardcoding strings.

  • 148-153: The comment explains why the version check is only required for tests. This is a good practice to explain the context and reasoning behind the code.

configuration.go Outdated Show resolved Hide resolved
tests/plugin_test.go Outdated Show resolved Hide resolved
plugin.go Outdated Show resolved Hide resolved
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Review Status

Actionable comments generated: 2

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between fe730fb and 6c259dc.
Files selected for processing (3)
  • configuration.go (1 hunks)
  • plugin.go (5 hunks)
  • tests/plugin_test.go (2 hunks)
Additional comments: 6
configuration.go (1)
  • 10-28: The getConfiguration function is well-structured and follows good practices. It uses the viper package to read configuration settings from a file and environment variables, and it handles errors appropriately. However, as previously mentioned, consider adding additional checks for the version format or range.
ver := viper.Get(versionKey)
if ver == nil {
    return nil, "", errors.Str("rr configuration file should contain a version e.g: version: 2.7")
}
// Add additional checks for version format or range here
tests/plugin_test.go (1)
  • 73-83: The test TestErrorWhenIncludedConfigHaveDifferentVersionThenRoot checks if an error is thrown when an included config has a different version than the root. This is a good practice to ensure version consistency across included files.
plugin.go (4)
  • 4-10: The new import statement for "path/filepath" is added correctly.

  • 15-21: The new constant "includeKey" is added correctly.

  • 70-86: The function handleIncludedConfigurationFiles is called correctly in the Init function. Ensure that all error handling is done correctly.

  • 124-129: The condition for setting the default version is correct.

plugin.go Outdated Show resolved Hide resolved
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Review Status

Actionable comments generated: 0

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 6c259dc and 16a7474.
Files selected for processing (1)
  • plugin.go (5 hunks)
Additional comments: 5
plugin.go (5)
  • 4-10: The path/filepath package is added to handle file paths in a cross-platform manner. This is a good practice for ensuring the code works across different operating systems.

  • 15-21: The includeKey constant is added to handle included configuration files. This is a good practice for code readability and maintainability.

  • 70-86: The handleIncludedConfigurationFiles function is called within the Init function. Ensure that the function is properly handling errors and that the error messages are informative enough for debugging.

  • 198-229: The handleIncludedConfigurationFiles function is added to handle included configuration files. It retrieves the configuration from each included file, validates the version, and merges the configurations. This function should be tested thoroughly to ensure it correctly handles different scenarios, such as missing files, incorrect file formats, version mismatches, and merging conflicts.

  • 124-129: The condition checks for the RoadRunner version and sets it to the default version if it's not provided or if it's "local". This is a good practice for ensuring backward compatibility and handling edge cases.

@rustatian rustatian added the enhancement New feature or request label Nov 7, 2023
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Review Status

Actionable comments generated: 1

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 16a7474 and db72ce9.
Files selected for processing (1)
  • tests/plugin_test.go (2 hunks)
Additional comments: 1
tests/plugin_test.go (1)
  • 73-83: The test TestErrorWhenIncludedConfigHaveDifferentVersionThenRoot checks if an error is thrown when an included configuration file has a different version than the root file. This is a good practice to ensure version consistency across included files.

tests/plugin_test.go Outdated Show resolved Hide resolved
Signed-off-by: Valery Piashchynski <[email protected]>
@rustatian
Copy link
Member

I'll add a few updates on your PR if you don't mind. Just some hidden logic:

  • We can't move version check before overrides, because of Octane which sets the version using overrides.
  • I also think that we should use an absolute path for the included configuration... But let's see how the current relative path will work.
  • I've introduced an experimental flag. I'll put this logic under this flag.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Review Status

Actionable comments generated: 0

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between db72ce9 and 82c0f25.
Files selected for processing (3)
  • include.go (1 hunks)
  • plugin.go (5 hunks)
  • tests/plugin_test.go (3 hunks)
Files not summarized due to errors (3)
  • plugin.go: Error: Server error. Please try again later.
  • tests/plugin_test.go: Error: Server error. Please try again later.
  • include.go: Error: Server error. Please try again later.
Files not reviewed due to errors (2)
  • include.go (Error: Server error. Please try again later.)
  • plugin.go (Error: Server error. Please try again later.)
Additional comments: 2
tests/plugin_test.go (2)
  • 613-635: The test TestIncludingConfigs checks if the configuration values are correctly retrieved from the root and included files. It also verifies if the values are overridden correctly. This is a good practice as it ensures the new feature works as expected.

  • 637-648: The test TestErrorWhenIncludedConfigHaveDifferentVersionThenRoot checks if an error is thrown when the version in the included file is different from the root. This is a good practice as it ensures the system behaves as expected when encountering inconsistencies.

Signed-off-by: Valery Piashchynski <[email protected]>
@rustatian rustatian merged commit f03bb49 into master Nov 8, 2023
6 checks passed
@rustatian
Copy link
Member

Thanks @cv65kr 👍

@rustatian rustatian deleted the feat/multi-configs branch November 8, 2023 14:25
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Review Status

Actionable comments generated: 3

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 82c0f25 and f022c93.
Files selected for processing (3)
  • expand.go (2 hunks)
  • include.go (1 hunks)
  • plugin.go (5 hunks)
Files not reviewed due to errors (2)
  • include.go (Error: Server error. Please try again later.)
  • plugin.go (Error: Server error. Please try again later.)
Additional comments: 1
expand.go (1)
  • 94-94: The function parseEnvDefault is not defined in this file. Ensure that it is imported or defined elsewhere in the codebase.

Comment on lines +88 to +115
func expandEnvViper(v *viper.Viper) {
for _, key := range v.AllKeys() {
val := v.Get(key)
switch t := val.(type) {
case string:
// for string expand it
v.Set(key, parseEnvDefault(t))
case []any:
// for slice -> check if it's a slice of strings
strArr := make([]string, 0, len(t))
for i := 0; i < len(t); i++ {
if valStr, ok := t[i].(string); ok {
strArr = append(strArr, parseEnvDefault(valStr))
continue
}

v.Set(key, val)
}

// we should set the whole array
if len(strArr) > 0 {
v.Set(key, strArr)
}
default:
v.Set(key, val)
}
}
}
Copy link

Choose a reason for hiding this comment

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

The expandEnvViper function iterates over all keys in the viper.Viper instance and expands environment variables in string values. It also handles expansion for slices of strings. However, it doesn't handle nested structures like maps or slices of maps. If your configuration can contain such structures, you might want to enhance this function to handle them.

Comment on lines +96 to +110
// for slice -> check if it's a slice of strings
strArr := make([]string, 0, len(t))
for i := 0; i < len(t); i++ {
if valStr, ok := t[i].(string); ok {
strArr = append(strArr, parseEnvDefault(valStr))
continue
}

v.Set(key, val)
}

// we should set the whole array
if len(strArr) > 0 {
v.Set(key, strArr)
}
Copy link

Choose a reason for hiding this comment

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

This block handles slices, but it assumes that all elements in the slice are of the same type. If a slice contains mixed types (e.g., strings and integers), this could lead to unexpected behavior. Consider adding type checking for each element in the slice.

v.Set(key, strArr)
}
default:
v.Set(key, val)
Copy link

Choose a reason for hiding this comment

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

This line sets the value of the key to its original value, which is unnecessary as it doesn't change anything. Consider removing this line.

- v.Set(key, val)

Commitable suggestion

[!IMPORTANT]
Carefully review the code before committing. Make sure it correctly replaces the highlighted code, has no missing lines and indentaion issues.

Suggested change
v.Set(key, val)

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

Successfully merging this pull request may close these issues.

[💡FEATURE REQUEST]: Allow merging two config files
2 participants