Skip to content

Allow to specify the config file through ARDUINO_CONFIG_FILE env #2488

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
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
1 change: 1 addition & 0 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ The configuration file must be named `arduino-cli`, with the appropriate file ex
Configuration files in the following locations are recognized by Arduino CLI:

1. Location specified by the [`--config-file`][arduino cli command reference] command line flag
1. Location specified by the `ARDUINO_CONFIG_FILE` environment variable
1. Arduino CLI data directory (as configured by `directories.data`)

If multiple configuration files are present, the one highest on the above list is used. Configuration files are not
Expand Down
9 changes: 5 additions & 4 deletions internal/cli/configuration/configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,10 @@ func GetDefaultBuiltinLibrariesDir() string {
return filepath.Join(getDefaultArduinoDataDir(), "libraries")
}

// FindConfigFileInArgs returns the config file path using the
// argument '--config-file' (if specified) or looking in the current working dir
func FindConfigFileInArgs(args []string) string {
// FindConfigFileInArgsFallbackOnEnv returns the config file path using the
// argument '--config-file' (if specified), if empty looks for the ARDUINO_CONFIG_FILE env,
// or looking in the current working dir
func FindConfigFileInArgsFallbackOnEnv(args []string) string {
// Look for '--config-file' argument
for i, arg := range args {
if arg == "--config-file" {
Expand All @@ -144,5 +145,5 @@ func FindConfigFileInArgs(args []string) string {
}
}
}
return ""
return os.Getenv("ARDUINO_CONFIG_FILE")
}
16 changes: 12 additions & 4 deletions internal/cli/configuration/configuration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,15 +60,23 @@ func TestInit(t *testing.T) {
}

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

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

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

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

t.Setenv("ARDUINO_CONFIG_FILE", "some/path/to/config")
configFile = FindConfigFileInArgsFallbackOnEnv([]string{})
require.Equal(t, "some/path/to/config", configFile)

// when both env and flag are specified flag takes precedence
configFile = FindConfigFileInArgsFallbackOnEnv([]string{"--config-file", "flag/path"})
require.Equal(t, "flag/path", configFile)
}
2 changes: 1 addition & 1 deletion internal/docsgen/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func main() {

os.MkdirAll(os.Args[1], 0755) // Create the output folder if it doesn't already exist

configuration.Settings = configuration.Init(configuration.FindConfigFileInArgs(os.Args))
configuration.Settings = configuration.Init(configuration.FindConfigFileInArgsFallbackOnEnv(os.Args))
cli := cli.NewCommand()
cli.DisableAutoGenTag = true // Disable addition of auto-generated date stamp
err := doc.GenMarkdownTree(cli, os.Args[1])
Expand Down
39 changes: 39 additions & 0 deletions internal/integrationtest/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@
package config_test

import (
"path/filepath"
"testing"

"github.com/arduino/arduino-cli/internal/integrationtest"
"github.com/arduino/go-paths-helper"
"github.com/stretchr/testify/require"
"go.bug.st/testifyjson/requirejson"
"gopkg.in/yaml.v3"
Expand Down Expand Up @@ -815,3 +817,40 @@ func TestDelete(t *testing.T) {
require.NotContains(t, configLines, "additional_urls")
require.NotContains(t, configLines, "board_manager")
}

func TestInitializationOrderOfConfigThroughFlagAndEnv(t *testing.T) {
env, cli := integrationtest.CreateArduinoCLIWithEnvironment(t)
defer env.CleanUp()

createConfig := func(path *paths.Path, content string) {
f, err := path.Create()
require.NoError(t, err)
_, err = f.WriteString(content)
require.NoError(t, err)
}
tmp := t.TempDir()
cliConfig, envConfig := paths.New(filepath.Join(tmp, "cli.yaml")), paths.New(filepath.Join(tmp, "env.yaml"))
createConfig(cliConfig, `cli-test: "test"`)
createConfig(envConfig, `env-test: "test"`)

// No flag nor env specified.
stdout, _, err := cli.Run("config", "dump", "--format", "json")
require.NoError(t, err)
requirejson.NotEmpty(t, stdout)

// Flag specified
stdout, _, err = cli.Run("config", "dump", "--config-file", cliConfig.String(), "--format", "json")
require.NoError(t, err)
requirejson.Contains(t, stdout, `{"config":{ "cli-test": "test" }}`)

// Env specified
customEnv := map[string]string{"ARDUINO_CONFIG_FILE": envConfig.String()}
stdout, _, err = cli.RunWithCustomEnv(customEnv, "config", "dump", "--format", "json")
require.NoError(t, err)
requirejson.Contains(t, stdout, `{"config":{ "env-test": "test" }}`)

// Flag and env specified, flag takes precedence
stdout, _, err = cli.RunWithCustomEnv(customEnv, "config", "dump", "--config-file", cliConfig.String(), "--format", "json")
require.NoError(t, err)
requirejson.Contains(t, stdout, `{"config":{ "cli-test": "test" }}`)
}
4 changes: 2 additions & 2 deletions internal/integrationtest/monitor/monitor_grpc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func TestMonitorGRPCClose(t *testing.T) {
tmpFileMatcher := regexp.MustCompile("Tmpfile: (.*)\n")
{
ctx, cancel := context.WithTimeout(context.Background(), time.Second*3)
mon, err := grpcInst.Monitor(ctx, ports[0].Port)
mon, err := grpcInst.Monitor(ctx, ports[0].GetPort())
var tmpFile *paths.Path
for {
monResp, err := mon.Recv()
Expand All @@ -85,7 +85,7 @@ func TestMonitorGRPCClose(t *testing.T) {
{
// Keep a timeout to allow the test to exit in any case
ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
mon, err := grpcInst.Monitor(ctx, ports[0].Port)
mon, err := grpcInst.Monitor(ctx, ports[0].GetPort())
var tmpFile *paths.Path
for {
monResp, err := mon.Recv()
Expand Down
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.Settings = configuration.Init(configuration.FindConfigFileInArgs(os.Args))
configuration.Settings = configuration.Init(configuration.FindConfigFileInArgsFallbackOnEnv(os.Args))
i18n.Init(configuration.Settings.GetString("locale"))
arduinoCmd := cli.NewCommand()
if err := arduinoCmd.Execute(); err != nil {
Expand Down