Skip to content

Change behaviour of --config-file flag with config commands #957

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

Merged
merged 3 commits into from
Oct 5, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 43 additions & 12 deletions cli/config/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,20 @@ package config

import (
"os"
"path/filepath"

"github.com/arduino/arduino-cli/cli/errorcodes"
"github.com/arduino/arduino-cli/cli/feedback"
paths "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"

Expand All @@ -37,39 +41,66 @@ 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 == "" {
if destFile != "" && destDir != "" {
feedback.Errorf("Can't use both --dest-file and --dest-dir flags at the same time.")
os.Exit(errorcodes.ErrGeneric)
}

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 = viper.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)
}

absPath, err := filepath.Abs(destDir)
if err != nil {
feedback.Errorf("Cannot find absolute path: %v", err)
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 {
if err := viper.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)
}
5 changes: 3 additions & 2 deletions commands/daemon/settings_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package daemon
import (
"context"
"encoding/json"
"path/filepath"
"testing"

"github.com/spf13/viper"
Expand All @@ -30,12 +31,12 @@ import (
var svc = SettingsService{}

func init() {
configuration.Init("testdata")
configuration.Init(filepath.Join("testdata", "arduino-cli.yaml"))
}

func reset() {
viper.Reset()
configuration.Init("testdata")
configuration.Init(filepath.Join("testdata", "arduino-cli.yaml"))
}

func TestGetAll(t *testing.T) {
Expand Down
51 changes: 28 additions & 23 deletions configuration/configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,21 @@ import (
func Init(configPath string) {
// Config file metadata
jww.SetStdoutThreshold(jww.LevelFatal)
viper.SetConfigName("arduino-cli")

configDir := paths.New(configPath)
if configDir != nil && !configDir.IsDir() {
viper.SetConfigName(strings.TrimSuffix(configDir.Base(), configDir.Ext()))
} else {
viper.SetConfigName("arduino-cli")
}

// Get default data path if none was provided
if configPath == "" {
configPath = getDefaultArduinoDataDir()
}

// Add paths where to search for a config file
viper.AddConfigPath(configPath)
viper.AddConfigPath(filepath.Dir(configPath))

// Bind env vars
viper.SetEnvPrefix("ARDUINO")
Expand Down Expand Up @@ -185,30 +191,39 @@ func IsBundledInDesktopIDE() bool {
}

// FindConfigFile returns the config file path using the argument '--config-file' if specified or via the current working dir
func FindConfigFile() string {

func FindConfigFile(args []string) string {
configFile := ""
for i, arg := range os.Args {
for i, arg := range args {
// 0 --config-file ss
if arg == "--config-file" {
if len(os.Args) > i+1 {
configFile = os.Args[i+1]
if len(args) > i+1 {
configFile = args[i+1]
}
}
}

if configFile != "" {
if fi, err := os.Stat(configFile); err == nil {
if fi.IsDir() {
return configFile
}
return filepath.Dir(configFile)
}
return configFile
}

return searchCwdForConfig()
}

func searchCwdForConfig() string {
cwd, err := os.Getwd()

if err != nil {
return ""
}

configFile := searchConfigTree(cwd)
if configFile == "" {
return configFile
}

return configFile + string(os.PathSeparator) + "arduino-cli.yaml"
}

func searchConfigTree(cwd string) string {

// go back up to root and search for the config file
Expand All @@ -230,13 +245,3 @@ func searchConfigTree(cwd string) string {
}

}

func searchCwdForConfig() string {
cwd, err := os.Getwd()

if err != nil {
return ""
}

return searchConfigTree(cwd)
}
43 changes: 43 additions & 0 deletions configuration/configuration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ func tmpDirOrDie() string {
if err != nil {
panic(fmt.Sprintf("error creating tmp dir: %v", err))
}
// Symlinks are evaluated becase the temp folder on Mac OS is inside /var, it's not writable
// and is a symlink to /private/var, we want the full path so we do this
dir, err = filepath.EvalSymlinks(dir)
if err != nil {
panic(fmt.Sprintf("error evaluating tmp dir symlink: %v", err))
}
return dir
}

Expand Down Expand Up @@ -71,3 +77,40 @@ func BenchmarkSearchConfigTree(b *testing.B) {
}
result = s
}

func TestFindConfigFile(t *testing.T) {
configFile := FindConfigFile([]string{"--config-file"})
require.Equal(t, "", configFile)

configFile = FindConfigFile([]string{"--config-file", "some/path/to/config"})
require.Equal(t, "some/path/to/config", configFile)

configFile = FindConfigFile([]string{"--config-file", "some/path/to/config/arduino-cli.yaml"})
require.Equal(t, "some/path/to/config/arduino-cli.yaml", configFile)

configFile = FindConfigFile([]string{})
require.Equal(t, "", configFile)

// Create temporary directories
tmp := tmpDirOrDie()
defer os.RemoveAll(tmp)
target := filepath.Join(tmp, "foo", "bar", "baz")
os.MkdirAll(target, os.ModePerm)
require.Nil(t, os.Chdir(target))

// Create a config file
f, err := os.Create(filepath.Join(target, "..", "..", "arduino-cli.yaml"))
require.Nil(t, err)
f.Close()

configFile = FindConfigFile([]string{})
require.Equal(t, filepath.Join(tmp, "foo", "arduino-cli.yaml"), configFile)

// Create another config file
f, err = os.Create(filepath.Join(target, "arduino-cli.yaml"))
require.Nil(t, err)
f.Close()

configFile = FindConfigFile([]string{})
require.Equal(t, filepath.Join(target, "arduino-cli.yaml"), configFile)
}
2 changes: 1 addition & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import (
)

func main() {
configuration.Init(configuration.FindConfigFile())
configuration.Init(configuration.FindConfigFile(os.Args))
i18n.Init()
arduinoCmd := cli.NewCommand()
if err := arduinoCmd.Execute(); err != nil {
Expand Down
Loading