Skip to content

Commit 9f49ea3

Browse files
Refactored config to not use viper singleton instance (#1027)
Co-authored-by: Cristian Maglie <[email protected]>
1 parent 457c66f commit 9f49ea3

File tree

24 files changed

+491
-205
lines changed

24 files changed

+491
-205
lines changed

Diff for: arduino/cores/packagemanager/loader.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,12 @@ import (
3030

3131
// LoadHardware read all plaforms from the configured paths
3232
func (pm *PackageManager) LoadHardware() error {
33-
dirs := configuration.HardwareDirectories()
33+
dirs := configuration.HardwareDirectories(configuration.Settings)
3434
if err := pm.LoadHardwareFromDirectories(dirs); err != nil {
3535
return err
3636
}
3737

38-
dirs = configuration.BundleToolsDirectories()
38+
dirs = configuration.BundleToolsDirectories(configuration.Settings)
3939
return pm.LoadToolsFromBundleDirectories(dirs)
4040
}
4141

Diff for: arduino/cores/packagemanager/package_manager_test.go

+3-4
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ import (
2626
"github.com/arduino/arduino-cli/configuration"
2727
"github.com/arduino/go-paths-helper"
2828
"github.com/arduino/go-properties-orderedmap"
29-
"github.com/spf13/viper"
3029
"github.com/stretchr/testify/require"
3130
semver "go.bug.st/relaxed-semver"
3231
)
@@ -213,11 +212,11 @@ func TestBoardOptionsFunctions(t *testing.T) {
213212

214213
func TestFindToolsRequiredForBoard(t *testing.T) {
215214
os.Setenv("ARDUINO_DATA_DIR", dataDir1.String())
216-
configuration.Init("")
215+
configuration.Settings = configuration.Init("")
217216
pm := packagemanager.NewPackageManager(
218217
dataDir1,
219-
configuration.PackagesDir(),
220-
paths.New(viper.GetString("directories.Downloads")),
218+
configuration.PackagesDir(configuration.Settings),
219+
paths.New(configuration.Settings.GetString("directories.Downloads")),
221220
dataDir1,
222221
)
223222

Diff for: cli/cache/clean.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@ import (
2020

2121
"github.com/arduino/arduino-cli/cli/errorcodes"
2222
"github.com/arduino/arduino-cli/cli/feedback"
23+
"github.com/arduino/arduino-cli/configuration"
2324
"github.com/sirupsen/logrus"
2425
"github.com/spf13/cobra"
25-
"github.com/spf13/viper"
2626
)
2727

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

43-
cachePath := viper.GetString("directories.Downloads")
43+
cachePath := configuration.Settings.GetString("directories.Downloads")
4444
err := os.RemoveAll(cachePath)
4545
if err != nil {
4646
feedback.Errorf("Error cleaning caches: %v", err)

Diff for: cli/cli.go

+8-11
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,13 @@ import (
4242
"github.com/arduino/arduino-cli/cli/upgrade"
4343
"github.com/arduino/arduino-cli/cli/upload"
4444
"github.com/arduino/arduino-cli/cli/version"
45+
"github.com/arduino/arduino-cli/configuration"
4546
"github.com/arduino/arduino-cli/i18n"
4647
"github.com/arduino/arduino-cli/inventory"
4748
"github.com/mattn/go-colorable"
4849
"github.com/rifflock/lfshook"
4950
"github.com/sirupsen/logrus"
5051
"github.com/spf13/cobra"
51-
"github.com/spf13/viper"
5252
)
5353

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

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

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

138135
func preRun(cmd *cobra.Command, args []string) {
139-
configFile := viper.ConfigFileUsed()
136+
configFile := configuration.Settings.ConfigFileUsed()
140137

141138
// initialize inventory
142-
inventory.Init(viper.GetString("directories.Data"))
139+
inventory.Init(configuration.Settings.GetString("directories.Data"))
143140

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

159156
// set the Logger format
160-
logFormat := strings.ToLower(viper.GetString("logging.format"))
157+
logFormat := strings.ToLower(configuration.Settings.GetString("logging.format"))
161158
if logFormat == "json" {
162159
logrus.SetFormatter(&logrus.JSONFormatter{})
163160
}
164161

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

182179
// configure logging filter
183-
if lvl, found := toLogLevel(viper.GetString("logging.level")); !found {
184-
feedback.Errorf("Invalid option for --log-level: %s", viper.GetString("logging.level"))
180+
if lvl, found := toLogLevel(configuration.Settings.GetString("logging.level")); !found {
181+
feedback.Errorf("Invalid option for --log-level: %s", configuration.Settings.GetString("logging.level"))
185182
os.Exit(errorcodes.ErrBadArgument)
186183
} else {
187184
logrus.SetLevel(lvl)

Diff for: cli/compile/compile.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"os"
2121

2222
"github.com/arduino/arduino-cli/cli/feedback"
23+
"github.com/arduino/arduino-cli/configuration"
2324

2425
"github.com/arduino/arduino-cli/cli/errorcodes"
2526
"github.com/arduino/arduino-cli/cli/instance"
@@ -29,7 +30,6 @@ import (
2930
"github.com/arduino/go-paths-helper"
3031
"github.com/sirupsen/logrus"
3132
"github.com/spf13/cobra"
32-
"github.com/spf13/viper"
3333
)
3434

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

129129
if err != nil {
130130
feedback.Errorf("Error during build: %v", err)

Diff for: cli/config/dump.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@ import (
1919
"os"
2020

2121
"github.com/arduino/arduino-cli/cli/feedback"
22+
"github.com/arduino/arduino-cli/configuration"
2223
"github.com/sirupsen/logrus"
2324
"github.com/spf13/cobra"
24-
"github.com/spf13/viper"
2525
"gopkg.in/yaml.v2"
2626
)
2727

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

6060
func runDumpCommand(cmd *cobra.Command, args []string) {
6161
logrus.Info("Executing `arduino config dump`")
62-
feedback.PrintResult(dumpResult{viper.AllSettings()})
62+
feedback.PrintResult(dumpResult{configuration.Settings.AllSettings()})
6363
}

Diff for: cli/config/init.go

+49-12
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,21 @@ package config
1717

1818
import (
1919
"os"
20-
"path/filepath"
2120

2221
"github.com/arduino/arduino-cli/cli/errorcodes"
2322
"github.com/arduino/arduino-cli/cli/feedback"
23+
"github.com/arduino/arduino-cli/configuration"
24+
"github.com/arduino/go-paths-helper"
2425
"github.com/sirupsen/logrus"
2526
"github.com/spf13/cobra"
2627
"github.com/spf13/viper"
2728
)
2829

29-
var destDir string
30+
var (
31+
destDir string
32+
destFile string
33+
overwrite bool
34+
)
3035

3136
const defaultFileName = "arduino-cli.yaml"
3237

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

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

53-
absPath, err := filepath.Abs(destDir)
54-
if err != nil {
55-
feedback.Errorf("Cannot find absolute path: %v", err)
63+
var configFileAbsPath *paths.Path
64+
var absPath *paths.Path
65+
var err error
66+
67+
switch {
68+
case destFile != "":
69+
configFileAbsPath, err = paths.New(destFile).Abs()
70+
if err != nil {
71+
feedback.Errorf("Cannot find absolute path: %v", err)
72+
os.Exit(errorcodes.ErrGeneric)
73+
}
74+
75+
absPath = configFileAbsPath.Parent()
76+
case destDir == "":
77+
destDir = configuration.Settings.GetString("directories.Data")
78+
fallthrough
79+
default:
80+
absPath, err = paths.New(destDir).Abs()
81+
if err != nil {
82+
feedback.Errorf("Cannot find absolute path: %v", err)
83+
os.Exit(errorcodes.ErrGeneric)
84+
}
85+
configFileAbsPath = absPath.Join(defaultFileName)
86+
}
87+
88+
if !overwrite && configFileAbsPath.Exist() {
89+
feedback.Error("Config file already exists, use --overwrite to discard the existing one.")
5690
os.Exit(errorcodes.ErrGeneric)
5791
}
58-
configFileAbsPath := filepath.Join(absPath, defaultFileName)
5992

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

62-
if err := os.MkdirAll(absPath, os.FileMode(0755)); err != nil {
95+
if err := absPath.MkdirAll(); err != nil {
6396
feedback.Errorf("Cannot create config file directory: %v", err)
6497
os.Exit(errorcodes.ErrGeneric)
6598
}
6699

67-
if err := viper.WriteConfigAs(configFileAbsPath); err != nil {
100+
newSettings := viper.New()
101+
configuration.SetDefaults(newSettings)
102+
configuration.BindFlags(cmd, newSettings)
103+
104+
if err := newSettings.WriteConfigAs(configFileAbsPath.String()); err != nil {
68105
feedback.Errorf("Cannot create config file: %v", err)
69106
os.Exit(errorcodes.ErrGeneric)
70107
}
71108

72-
msg := "Config file written to: " + configFileAbsPath
109+
msg := "Config file written to: " + configFileAbsPath.String()
73110
logrus.Info(msg)
74111
feedback.Print(msg)
75112
}

Diff for: cli/daemon/daemon.go

+6-6
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828
"github.com/arduino/arduino-cli/cli/feedback"
2929
"github.com/arduino/arduino-cli/cli/globals"
3030
"github.com/arduino/arduino-cli/commands/daemon"
31+
"github.com/arduino/arduino-cli/configuration"
3132
srv_commands "github.com/arduino/arduino-cli/rpc/commands"
3233
srv_debug "github.com/arduino/arduino-cli/rpc/debug"
3334
srv_monitor "github.com/arduino/arduino-cli/rpc/monitor"
@@ -36,22 +37,21 @@ import (
3637
"github.com/segmentio/stats/v4"
3738
"github.com/sirupsen/logrus"
3839
"github.com/spf13/cobra"
39-
"github.com/spf13/viper"
4040
"google.golang.org/grpc"
4141
)
4242

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

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

63-
if viper.GetBool("telemetry.enabled") {
63+
if configuration.Settings.GetBool("telemetry.enabled") {
6464
telemetry.Activate("daemon")
6565
stats.Incr("daemon", stats.T("success", "true"))
6666
defer stats.Flush()
6767
}
68-
port := viper.GetString("daemon.port")
68+
port := configuration.Settings.GetString("daemon.port")
6969
s := grpc.NewServer()
7070

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

7474
// register the commands service
7575
srv_commands.RegisterArduinoCoreServer(s, &daemon.ArduinoCoreServerImpl{

Diff for: commands/board/list_test.go

+5
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,15 @@ import (
2222
"testing"
2323

2424
"github.com/arduino/arduino-cli/commands"
25+
"github.com/arduino/arduino-cli/configuration"
2526
"github.com/arduino/go-properties-orderedmap"
2627
"github.com/stretchr/testify/require"
2728
)
2829

30+
func init() {
31+
configuration.Settings = configuration.Init("")
32+
}
33+
2934
func TestGetByVidPid(t *testing.T) {
3035
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
3136
fmt.Fprintln(w, `

Diff for: commands/compile/compile.go

+4-5
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ import (
3939
"github.com/pkg/errors"
4040
"github.com/segmentio/stats/v4"
4141
"github.com/sirupsen/logrus"
42-
"github.com/spf13/viper"
4342
)
4443

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

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

128127
builderCtx.OtherLibrariesDirs = paths.NewPathList(req.GetLibraries()...)
129-
builderCtx.OtherLibrariesDirs.Add(configuration.LibrariesDir())
128+
builderCtx.OtherLibrariesDirs.Add(configuration.LibrariesDir(configuration.Settings))
130129

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

170169
// Check if Arduino IDE is installed and get it's libraries location.
171-
dataDir := paths.New(viper.GetString("directories.Data"))
170+
dataDir := paths.New(configuration.Settings.GetString("directories.Data"))
172171
preferencesTxt := dataDir.Join("preferences.txt")
173172
ideProperties, err := properties.LoadFromPath(preferencesTxt)
174173
if err == nil {

Diff for: commands/core/search_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ func TestPlatformSearch(t *testing.T) {
4646
err := paths.New("testdata").Join("package_index.json").CopyTo(dataDir.Join("package_index.json"))
4747
require.Nil(t, err)
4848

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

5151
inst, err := instance.CreateInstance()
5252
require.Nil(t, err)

0 commit comments

Comments
 (0)