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

Refactored config to not use viper singleton instance #1027

Merged
merged 6 commits into from Oct 14, 2020
@@ -30,12 +30,12 @@ import (

// LoadHardware read all plaforms from the configured paths
func (pm *PackageManager) LoadHardware() error {
dirs := configuration.HardwareDirectories()
dirs := configuration.HardwareDirectories(configuration.Settings)
if err := pm.LoadHardwareFromDirectories(dirs); err != nil {
return err
}

dirs = configuration.BundleToolsDirectories()
dirs = configuration.BundleToolsDirectories(configuration.Settings)
return pm.LoadToolsFromBundleDirectories(dirs)
}

@@ -26,7 +26,6 @@ import (
"github.com/arduino/arduino-cli/configuration"
"github.com/arduino/go-paths-helper"
"github.com/arduino/go-properties-orderedmap"
"github.com/spf13/viper"
"github.com/stretchr/testify/require"
semver "go.bug.st/relaxed-semver"
)
@@ -213,11 +212,11 @@ func TestBoardOptionsFunctions(t *testing.T) {

func TestFindToolsRequiredForBoard(t *testing.T) {
os.Setenv("ARDUINO_DATA_DIR", dataDir1.String())
configuration.Init("")
configuration.Settings = configuration.Init("")
pm := packagemanager.NewPackageManager(
dataDir1,
configuration.PackagesDir(),
paths.New(viper.GetString("directories.Downloads")),
configuration.PackagesDir(configuration.Settings),
paths.New(configuration.Settings.GetString("directories.Downloads")),
dataDir1,
)

@@ -20,9 +20,9 @@ import (

"github.com/arduino/arduino-cli/cli/errorcodes"
"github.com/arduino/arduino-cli/cli/feedback"
"github.com/arduino/arduino-cli/configuration"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)

func initCleanCommand() *cobra.Command {
@@ -40,7 +40,7 @@ func initCleanCommand() *cobra.Command {
func runCleanCommand(cmd *cobra.Command, args []string) {
logrus.Info("Executing `arduino cache clean`")

cachePath := viper.GetString("directories.Downloads")
cachePath := configuration.Settings.GetString("directories.Downloads")
err := os.RemoveAll(cachePath)
if err != nil {
feedback.Errorf("Error cleaning caches: %v", err)
@@ -42,13 +42,13 @@ import (
"github.com/arduino/arduino-cli/cli/upgrade"
"github.com/arduino/arduino-cli/cli/upload"
"github.com/arduino/arduino-cli/cli/version"
"github.com/arduino/arduino-cli/configuration"
"github.com/arduino/arduino-cli/i18n"
"github.com/arduino/arduino-cli/inventory"
"github.com/mattn/go-colorable"
"github.com/rifflock/lfshook"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)

var (
@@ -99,15 +99,12 @@ func createCliCommandTree(cmd *cobra.Command) {

cmd.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "Print the logs on the standard output.")
cmd.PersistentFlags().String("log-level", "", "Messages with this level and above will be logged. Valid levels are: trace, debug, info, warn, error, fatal, panic")
viper.BindPFlag("logging.level", cmd.PersistentFlags().Lookup("log-level"))
cmd.PersistentFlags().String("log-file", "", "Path to the file where logs will be written.")
viper.BindPFlag("logging.file", cmd.PersistentFlags().Lookup("log-file"))
cmd.PersistentFlags().String("log-format", "", "The output format for the logs, can be {text|json}.")
viper.BindPFlag("logging.format", cmd.PersistentFlags().Lookup("log-format"))
cmd.PersistentFlags().StringVar(&outputFormat, "format", "text", "The output format, can be {text|json}.")
cmd.PersistentFlags().StringVar(&configFile, "config-file", "", "The custom config file (if not specified the default will be used).")
cmd.PersistentFlags().StringSlice("additional-urls", []string{}, "Comma-separated list of additional URLs for the Boards Manager.")
viper.BindPFlag("board_manager.additional_urls", cmd.PersistentFlags().Lookup("additional-urls"))
configuration.BindFlags(cmd, configuration.Settings)
}

// convert the string passed to the `--log-level` option to the corresponding
@@ -136,10 +133,10 @@ func parseFormatString(arg string) (feedback.OutputFormat, bool) {
}

func preRun(cmd *cobra.Command, args []string) {
configFile := viper.ConfigFileUsed()
configFile := configuration.Settings.ConfigFileUsed()

// initialize inventory
inventory.Init(viper.GetString("directories.Data"))
inventory.Init(configuration.Settings.GetString("directories.Data"))

//
// Prepare logging
@@ -157,13 +154,13 @@ func preRun(cmd *cobra.Command, args []string) {
}

// set the Logger format
logFormat := strings.ToLower(viper.GetString("logging.format"))
logFormat := strings.ToLower(configuration.Settings.GetString("logging.format"))
if logFormat == "json" {
logrus.SetFormatter(&logrus.JSONFormatter{})
}

// should we log to file?
logFile := viper.GetString("logging.file")
logFile := configuration.Settings.GetString("logging.file")
if logFile != "" {
file, err := os.OpenFile(logFile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
if err != nil {
@@ -180,8 +177,8 @@ func preRun(cmd *cobra.Command, args []string) {
}

// configure logging filter
if lvl, found := toLogLevel(viper.GetString("logging.level")); !found {
feedback.Errorf("Invalid option for --log-level: %s", viper.GetString("logging.level"))
if lvl, found := toLogLevel(configuration.Settings.GetString("logging.level")); !found {
feedback.Errorf("Invalid option for --log-level: %s", configuration.Settings.GetString("logging.level"))
os.Exit(errorcodes.ErrBadArgument)
} else {
logrus.SetLevel(lvl)
@@ -20,6 +20,7 @@ import (
"os"

"github.com/arduino/arduino-cli/cli/feedback"
"github.com/arduino/arduino-cli/configuration"

"github.com/arduino/arduino-cli/cli/errorcodes"
"github.com/arduino/arduino-cli/cli/instance"
@@ -29,7 +30,6 @@ import (
"github.com/arduino/go-paths-helper"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)

var (
@@ -124,7 +124,7 @@ func run(cmd *cobra.Command, args []string) {
Libraries: libraries,
OptimizeForDebug: optimizeForDebug,
Clean: clean,
}, os.Stdout, os.Stderr, viper.GetString("logging.level") == "debug")
}, os.Stdout, os.Stderr, configuration.Settings.GetString("logging.level") == "debug")

if err != nil {
feedback.Errorf("Error during build: %v", err)
@@ -19,9 +19,9 @@ import (
"os"

"github.com/arduino/arduino-cli/cli/feedback"
"github.com/arduino/arduino-cli/configuration"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"gopkg.in/yaml.v2"
)

@@ -59,5 +59,5 @@ func (dr dumpResult) String() string {

func runDumpCommand(cmd *cobra.Command, args []string) {
logrus.Info("Executing `arduino config dump`")
feedback.PrintResult(dumpResult{viper.AllSettings()})
feedback.PrintResult(dumpResult{configuration.Settings.AllSettings()})
}
@@ -17,16 +17,21 @@ package config

import (
"os"
"path/filepath"

"github.com/arduino/arduino-cli/cli/errorcodes"
"github.com/arduino/arduino-cli/cli/feedback"
"github.com/arduino/arduino-cli/configuration"
"github.com/arduino/go-paths-helper"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)

var destDir string
var (
destDir string
destFile string
overwrite bool
)

const defaultFileName = "arduino-cli.yaml"

@@ -37,39 +42,71 @@ func initInitCommand() *cobra.Command {
Long: "Creates or updates the configuration file in the data directory or custom directory with the current configuration settings.",
Example: "" +
" # Writes current configuration to the configuration file in the data directory.\n" +
" " + os.Args[0] + " config init",
" " + os.Args[0] + " config init" +
" " + os.Args[0] + " config init --dest-dir /home/user/MyDirectory" +
" " + os.Args[0] + " config init --dest-file /home/user/MyDirectory/my_settings.yaml",
Args: cobra.NoArgs,
Run: runInitCommand,
}
initCommand.Flags().StringVar(&destDir, "dest-dir", "", "Sets where to save the configuration file.")
initCommand.Flags().StringVar(&destFile, "dest-file", "", "Sets where to save the configuration file.")
initCommand.Flags().BoolVar(&overwrite, "overwrite", false, "Overwrite existing config file.")
return initCommand
}

func runInitCommand(cmd *cobra.Command, args []string) {
if destDir == "" {
destDir = viper.GetString("directories.Data")
if destFile != "" && destDir != "" {
feedback.Errorf("Can't use both --dest-file and --dest-dir flags at the same time.")
os.Exit(errorcodes.ErrGeneric)
}

absPath, err := filepath.Abs(destDir)
if err != nil {
feedback.Errorf("Cannot find absolute path: %v", err)
var configFileAbsPath *paths.Path
var absPath *paths.Path
var err error

switch {
case destFile != "":
configFileAbsPath, err = paths.New(destFile).Abs()
if err != nil {
feedback.Errorf("Cannot find absolute path: %v", err)
os.Exit(errorcodes.ErrGeneric)
}

absPath = configFileAbsPath.Parent()
case destDir == "":
destDir = configuration.Settings.GetString("directories.Data")
fallthrough
default:
absPath, err = paths.New(destDir).Abs()
if err != nil {
feedback.Errorf("Cannot find absolute path: %v", err)
os.Exit(errorcodes.ErrGeneric)
}
configFileAbsPath = absPath.Join(defaultFileName)
}

if !overwrite && configFileAbsPath.Exist() {
feedback.Error("Config file already exists, use --overwrite to discard the existing one.")
os.Exit(errorcodes.ErrGeneric)
}
configFileAbsPath := filepath.Join(absPath, defaultFileName)

logrus.Infof("Writing config file to: %s", absPath)

if err := os.MkdirAll(absPath, os.FileMode(0755)); err != nil {
if err := absPath.MkdirAll(); err != nil {
feedback.Errorf("Cannot create config file directory: %v", err)
os.Exit(errorcodes.ErrGeneric)
}

if err := viper.WriteConfigAs(configFileAbsPath); err != nil {
newSettings := viper.New()
configuration.SetDefaults(newSettings)
configuration.BindFlags(cmd, newSettings)

if err := newSettings.WriteConfigAs(configFileAbsPath.String()); err != nil {
feedback.Errorf("Cannot create config file: %v", err)
os.Exit(errorcodes.ErrGeneric)
}

msg := "Config file written to: " + configFileAbsPath
msg := "Config file written to: " + configFileAbsPath.String()
logrus.Info(msg)
feedback.Print(msg)
}
@@ -28,6 +28,7 @@ import (
"github.com/arduino/arduino-cli/cli/feedback"
"github.com/arduino/arduino-cli/cli/globals"
"github.com/arduino/arduino-cli/commands/daemon"
"github.com/arduino/arduino-cli/configuration"
srv_commands "github.com/arduino/arduino-cli/rpc/commands"
srv_debug "github.com/arduino/arduino-cli/rpc/debug"
srv_monitor "github.com/arduino/arduino-cli/rpc/monitor"
@@ -36,22 +37,21 @@ import (
"github.com/segmentio/stats/v4"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"google.golang.org/grpc"
)

// NewCommand created a new `daemon` command
func NewCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "daemon",
Short: fmt.Sprintf("Run as a daemon on port %s", viper.GetString("daemon.port")),
Short: fmt.Sprintf("Run as a daemon on port %s", configuration.Settings.GetString("daemon.port")),
Long: "Running as a daemon the initialization of cores and libraries is done only once.",
Example: " " + os.Args[0] + " daemon",
Args: cobra.NoArgs,
Run: runDaemonCommand,
}
cmd.PersistentFlags().String("port", "", "The TCP port the daemon will listen to")
viper.BindPFlag("daemon.port", cmd.PersistentFlags().Lookup("port"))
configuration.Settings.BindPFlag("daemon.port", cmd.PersistentFlags().Lookup("port"))
cmd.Flags().BoolVar(&daemonize, "daemonize", false, "Do not terminate daemon process if the parent process dies")
return cmd
}
@@ -60,16 +60,16 @@ var daemonize bool

func runDaemonCommand(cmd *cobra.Command, args []string) {

if viper.GetBool("telemetry.enabled") {
if configuration.Settings.GetBool("telemetry.enabled") {
telemetry.Activate("daemon")
stats.Incr("daemon", stats.T("success", "true"))
defer stats.Flush()
}
port := viper.GetString("daemon.port")
port := configuration.Settings.GetString("daemon.port")
s := grpc.NewServer()

// Set specific user-agent for the daemon
viper.Set("network.user_agent_ext", "daemon")
configuration.Settings.Set("network.user_agent_ext", "daemon")

// register the commands service
srv_commands.RegisterArduinoCoreServer(s, &daemon.ArduinoCoreServerImpl{
@@ -22,10 +22,15 @@ import (
"testing"

"github.com/arduino/arduino-cli/commands"
"github.com/arduino/arduino-cli/configuration"
"github.com/arduino/go-properties-orderedmap"
"github.com/stretchr/testify/require"
)

func init() {
configuration.Settings = configuration.Init("")
}

func TestGetByVidPid(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, `
@@ -39,7 +39,6 @@ import (
"github.com/pkg/errors"
"github.com/segmentio/stats/v4"
"github.com/sirupsen/logrus"
"github.com/spf13/viper"
)

// Compile FIXMEDOC
@@ -122,11 +121,11 @@ func Compile(ctx context.Context, req *rpc.CompileReq, outStream, errStream io.W
builderCtx.SketchLocation = sketch.FullPath

// FIXME: This will be redundant when arduino-builder will be part of the cli
builderCtx.HardwareDirs = configuration.HardwareDirectories()
builderCtx.BuiltInToolsDirs = configuration.BundleToolsDirectories()
builderCtx.HardwareDirs = configuration.HardwareDirectories(configuration.Settings)
builderCtx.BuiltInToolsDirs = configuration.BundleToolsDirectories(configuration.Settings)

builderCtx.OtherLibrariesDirs = paths.NewPathList(req.GetLibraries()...)
builderCtx.OtherLibrariesDirs.Add(configuration.LibrariesDir())
builderCtx.OtherLibrariesDirs.Add(configuration.LibrariesDir(configuration.Settings))

if req.GetBuildPath() != "" {
builderCtx.BuildPath = paths.New(req.GetBuildPath())
@@ -168,7 +167,7 @@ func Compile(ctx context.Context, req *rpc.CompileReq, outStream, errStream io.W
builderCtx.ArduinoAPIVersion = "10607"

// Check if Arduino IDE is installed and get it's libraries location.
dataDir := paths.New(viper.GetString("directories.Data"))
dataDir := paths.New(configuration.Settings.GetString("directories.Data"))
preferencesTxt := dataDir.Join("preferences.txt")
ideProperties, err := properties.LoadFromPath(preferencesTxt)
if err == nil {
@@ -46,7 +46,7 @@ func TestPlatformSearch(t *testing.T) {
err := paths.New("testdata").Join("package_index.json").CopyTo(dataDir.Join("package_index.json"))
require.Nil(t, err)

configuration.Init(paths.TempDir().Join("test", "arduino-cli.yaml").String())
configuration.Settings = configuration.Init(paths.TempDir().Join("test", "arduino-cli.yaml").String())

inst, err := instance.CreateInstance()
require.Nil(t, err)
ProTip! Use n and p to navigate between commits in a pull request.