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

Introduce Viper to manage the configuration file #487

Merged
merged 21 commits into from Dec 11, 2019
Merged

Introduce Viper to manage the configuration file #487

merged 21 commits into from Dec 11, 2019

Conversation

masci
Copy link
Contributor

@masci masci commented Nov 18, 2019

This PR introduces https://github.com/spf13/viper to manage the configuration file in order to:

  • consistently manage config bindings to env vars and command line switches
  • get a more generic, key-value API to store/retrieve options
  • easily get structured config options (see example below)

An example of configuration file would look like this:

board_manager:
  additional_urls:
  - https://raw.githubusercontent.com/ultimachine/ArduinoAddons/master/package_ultimachine_index.json

directories:
  data: /home/massi/.arduino15
  downloads: /home/massi/.arduino15/staging
  libraries: /home/massi/Arduino/libraries
  packages: /home/massi/.arduino15/packages
  sketchbook: /home/massi/Arduino

logging:
  file: ""
  format: text
  level: info

A new package, configuration, has been added to:

  • keep default values definition in one single module
  • provide an init mechanism, useful for testing and to allow user customization
  • wrap common paths definitions

I've left inline comments to ease the review process.

return fmt.Errorf("getting hardware directory: %s", err)
}

dirs = configuration.BundleToolsDirectories()
Copy link
Contributor Author

Choose a reason for hiding this comment

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

the error was removed because these functions always returned nil

cmd.PersistentFlags().StringVar(&globals.LogLevel, "log-level", defaultLogLevel, "Messages with this level and above will be logged.")
cmd.PersistentFlags().StringVar(&logFile, "log-file", "", "Path to the file where logs will be written.")
cmd.PersistentFlags().StringVar(&logFormat, "log-format", "text", "The output format for the logs, can be [text|json].")
cmd.PersistentFlags().String("log-level", "", "Messages with this level and above will be logged.")
Copy link
Contributor Author

Choose a reason for hiding this comment

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

We don't need a var anymore since the flag value is stored in the settings objects directly (this applies to following similar cases)

// configure logging filter
if lvl, found := toLogLevel(globals.LogLevel); !found {
fmt.Printf("Invalid option for --log-level: %s", globals.LogLevel)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

unrelated but we should use feedback instead of fmt across the codebase

* otherwise use the software for commercial activities involving the Arduino
* software without disclosing the source code of your own applications. To purchase
* a commercial license, send an email to license@arduino.cc.
*/
Copy link
Contributor Author

Choose a reason for hiding this comment

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

unrelated but we should uniform license format when we find inconsistencies

Copy link
Contributor

@rsora rsora left a comment

Choose a reason for hiding this comment

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

I like it, a lot.
We did not lose anything in flexibility and cleaned up a lot of boilerplate, while maintaining retrocompatibility.

configuration/configuration.go Show resolved Hide resolved
configuration/configuration.go Show resolved Hide resolved
)

// Navigate FIXMEDOC
func (c *Configuration) Navigate(pwd *paths.Path) {
Copy link
Member

Choose a reason for hiding this comment

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

Does viper provides a Navigate feature already?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You can call viper.AddConfigPath() several times passing the path where Viper should look for a config file


builderCtx.OtherLibrariesDirs = paths.NewPathList()
builderCtx.OtherLibrariesDirs.Add(config.LibrariesDir())
builderCtx.OtherLibrariesDirs.Add(paths.New(viper.GetString("directories.Libraries")))
Copy link
Member

Choose a reason for hiding this comment

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

Why not put viper.GetString("directories.Libraries") into an helper function? like as you did with configuration.HardwareDirectories() for example?

At this point I'd write an helper function for each key we put in viper, doing so will enforce a more strict compile-time checks.

Copy link
Contributor Author

@masci masci Dec 3, 2019

Choose a reason for hiding this comment

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

One of the reasons to switch to Viper was having a generic k/v store that can arbitrarily grow without the need to change the API. I understand the issue of losing the check on the configuration keys at compile time (if you write viper.GetString("directories.Libs") the program will happily compile despite not working as expected) but I think the tradeoff is worth it. We can catch errors on configuration keys at unit test time.

}

// LoadFromDesktopIDEPreferences loads the config from the Desktop IDE preferences.txt file
func (config *Configuration) LoadFromDesktopIDEPreferences() error {
Copy link
Member

Choose a reason for hiding this comment

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

Are we dropping loading/overlaying options from the IDE preferences.txt? (just asking I may be OK with that :-))

Copy link
Contributor Author

Choose a reason for hiding this comment

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

At first I didn't fully get what this was for - I'd say let's get rid of it.
If needed, I'd add a specific command like arduino-cli config import /path/to/preferences.txt so the operation is explicit.

@rsora rsora self-requested a review December 11, 2019 16:50
Copy link
Contributor

@rsora rsora left a comment

Choose a reason for hiding this comment

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

:shipit:

@masci masci merged commit f2df284 into master Dec 11, 2019
@masci masci deleted the massi/viper branch December 11, 2019 16:57
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.

None yet

3 participants