Skip to content

Refactor config init command #68

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 10 commits into from
Nov 26, 2021
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
52 changes: 52 additions & 0 deletions arduino/dir.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// This file is part of arduino-cloud-cli.
//
// Copyright (C) 2021 ARDUINO SA (http://www.arduino.cc/)
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.

package arduino

import (
"fmt"
"os"
"path/filepath"
"runtime"

"github.com/arduino/go-paths-helper"
"github.com/arduino/go-win32-utils"
)

// DataDir returns the Arduino default data directory (arduino15)
func DataDir() (*paths.Path, error) {
userHomeDir, err := os.UserHomeDir()
if err != nil {
return nil, fmt.Errorf("unable to get user home dir: %w", err)
}

var path *paths.Path
switch runtime.GOOS {
case "darwin":
path = paths.New(filepath.Join(userHomeDir, "Library", "Arduino15"))
case "windows":
localAppDataPath, err := win32.GetLocalAppDataFolder()
if err != nil {
return nil, fmt.Errorf("unable to get local app data folder: %w", err)
}
path = paths.New(filepath.Join(localAppDataPath, "Arduino15"))
default: // linux, android, *bsd, plan9 and other Unix-like systems
path = paths.New(filepath.Join(userHomeDir, ".arduino15"))
}

return path, nil
}
111 changes: 98 additions & 13 deletions cli/config/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,25 @@
package config

import (
"errors"
"fmt"
"os"
"strings"

"github.com/arduino/arduino-cli/cli/errorcodes"
"github.com/arduino/arduino-cli/cli/feedback"
"github.com/arduino/arduino-cloud-cli/command/config"
"github.com/arduino/arduino-cloud-cli/arduino"
"github.com/arduino/arduino-cloud-cli/internal/config"
"github.com/arduino/go-paths-helper"
"github.com/manifoldco/promptui"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)

const (
clientIDLen = 32
clientSecretLen = 64
)

var initFlags struct {
Expand All @@ -36,32 +48,105 @@ var initFlags struct {
func initInitCommand() *cobra.Command {
initCommand := &cobra.Command{
Use: "init",
Short: "Initialize a configuration file with default values",
Long: "Initialize an Arduino IoT Cloud CLI configuration file with default values",
Short: "Initialize a configuration file",
Long: "Initialize an Arduino IoT Cloud CLI configuration",
Run: runInitCommand,
}

initCommand.Flags().StringVar(&initFlags.destDir, "dest-dir", ".", "Sets where to save the configuration file.")
initCommand.Flags().BoolVar(&initFlags.overwrite, "overwrite", false, "Overwrite existing config file.")
initCommand.Flags().StringVar(&initFlags.destDir, "dest-dir", "", "Sets where to save the configuration file")
initCommand.Flags().BoolVar(&initFlags.overwrite, "overwrite", false, "Overwrite existing config file")

This comment was marked as resolved.

This comment was marked as resolved.

initCommand.Flags().StringVar(&initFlags.format, "config-format", "yaml", "Format of the configuration file, can be {yaml|json}")

return initCommand
}

func runInitCommand(cmd *cobra.Command, args []string) {
logrus.Infof("Initializing a config file in folder: %s", initFlags.destDir)
logrus.Info("Initializing config file")

// Get default destination directory if it's not passed
if initFlags.destDir == "" {
configPath, err := arduino.DataDir()
if err != nil {
feedback.Errorf("Error during config init: cannot retrieve arduino default directory: %v", err)
os.Exit(errorcodes.ErrGeneric)
}
initFlags.destDir = configPath.String()
}

// Validate format flag
initFlags.format = strings.ToLower(initFlags.format)
if initFlags.format != "json" && initFlags.format != "yaml" {
feedback.Error("Error during config init: format is not valid, provide 'json' or 'yaml'")
os.Exit(errorcodes.ErrGeneric)
}

params := &config.InitParams{
DestDir: initFlags.destDir,
Overwrite: initFlags.overwrite,
Format: initFlags.format,
// Check that the destination directory is valid and build the configuration file path
configPath, err := paths.New(initFlags.destDir).Abs()
if err != nil {
feedback.Errorf("Error during config init: cannot retrieve absolute path of %s: %v", initFlags.destDir, err)
os.Exit(errorcodes.ErrGeneric)
}
if !configPath.IsDir() {
feedback.Errorf("Error during config init: %s is not a valid directory", configPath)
os.Exit(errorcodes.ErrGeneric)
}
configFile := configPath.Join(config.Filename + "." + initFlags.format)
if !initFlags.overwrite && configFile.Exist() {
feedback.Errorf("Error during config init: %s already exists, use '--overwrite' to overwrite it",
configFile)
os.Exit(errorcodes.ErrGeneric)
}

err := config.Init(params)
// Take needed configuration parameters starting an interactive mode
feedback.Print("To obtain your API credentials visit https://create.arduino.cc/iot/integrations")
id, key, err := paramsPrompt()
if err != nil {
feedback.Errorf("Error during config init: %v", err)
feedback.Errorf("Error during config init: cannot take config params: %v", err)
os.Exit(errorcodes.ErrGeneric)
}

logrus.Info("Config file successfully initialized")
// Write the configuration file
newSettings := viper.New()
newSettings.SetConfigPermissions(os.FileMode(0600))
newSettings.Set("client", id)
newSettings.Set("secret", key)
if err := newSettings.WriteConfigAs(configFile.String()); err != nil {
feedback.Errorf("Error during config init: cannot create config file: %v", err)
os.Exit(errorcodes.ErrGeneric)
}

feedback.Printf("Config file successfully initialized at: %s", configFile)
}

func paramsPrompt() (id, key string, err error) {
prompt := promptui.Prompt{
Label: "Please enter the Client ID",
Validate: func(s string) error {
if len(s) != clientIDLen {
return errors.New("client-id not valid")
}
return nil
},
}
id, err = prompt.Run()
if err != nil {
return "", "", fmt.Errorf("client prompt fail: %w", err)
}

prompt = promptui.Prompt{
Mask: '*',
Label: "Please enter the Client Secret",
Validate: func(s string) error {
if len(s) != clientSecretLen {
return errors.New("client secret not valid")
}
return nil
},
}
key, err = prompt.Run()
if err != nil {
return "", "", fmt.Errorf("client secret prompt fail: %w", err)
}

return id, key, nil
}
76 changes: 0 additions & 76 deletions command/config/init.go

This file was deleted.

2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ require (
github.com/antihax/optional v1.0.0
github.com/arduino/arduino-cli v0.0.0-20210607095659-16f41352eac3
github.com/arduino/go-paths-helper v1.6.1
github.com/arduino/go-win32-utils v0.0.0-20180330194947-ed041402e83b
github.com/arduino/iot-client-go v1.3.4-0.20211116175324-9a98dd4ad269
github.com/gofrs/uuid v4.0.0+incompatible
github.com/google/go-cmp v0.5.6
github.com/howeyc/crc16 v0.0.0-20171223171357-2b2a61e366a6
github.com/juju/errors v0.0.0-20181118221551-089d3ea4e4d5
github.com/manifoldco/promptui v0.9.0
github.com/sirupsen/logrus v1.8.1
github.com/spf13/cobra v1.1.3
github.com/spf13/viper v1.7.0
Expand Down
12 changes: 6 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,6 @@ github.com/arduino/go-properties-orderedmap v1.3.0/go.mod h1:DKjD2VXY/NZmlingh4l
github.com/arduino/go-timeutils v0.0.0-20171220113728-d1dd9e313b1b/go.mod h1:uwGy5PpN4lqW97FiLnbcx+xx8jly5YuPMJWfVwwjJiQ=
github.com/arduino/go-win32-utils v0.0.0-20180330194947-ed041402e83b h1:3PjgYG5gVPA7cipp7vIR2lF96KkEJIFBJ+ANnuv6J20=
github.com/arduino/go-win32-utils v0.0.0-20180330194947-ed041402e83b/go.mod h1:iIPnclBMYm1g32Q5kXoqng4jLhMStReIP7ZxaoUC2y8=
github.com/arduino/iot-client-go v1.3.4-0.20211103115604-d4d372164262 h1:qVq8cdkaRPaLc9DAjY/6rH3ocs6ZvnEJtD26f5++/RU=
github.com/arduino/iot-client-go v1.3.4-0.20211103115604-d4d372164262/go.mod h1:gYvpMt7Qw+OSScTLyIlCnpbvy9y96ey/2zhB4w6FoK0=
github.com/arduino/iot-client-go v1.3.4-0.20211116175324-9a98dd4ad269 h1:01RHB48b1QRN5viXtdtmSkvyudxHqczDV+OD+1PuE6M=
github.com/arduino/iot-client-go v1.3.4-0.20211116175324-9a98dd4ad269/go.mod h1:gYvpMt7Qw+OSScTLyIlCnpbvy9y96ey/2zhB4w6FoK0=
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
Expand All @@ -76,8 +74,11 @@ github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kB
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/chzyer/logex v1.1.10 h1:Swpa1K6QvQznwJRcfTfQJmTE72DqScAa40E+fbHEXEE=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e h1:fY5BOSpyZCqRo5OhCuC+XN+r/bBCmeuuJtjz+bCNIf8=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 h1:q763qf9huN11kDQavWsoZXJNW3xEE4JJyHa5Q25/sd8=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cmaglie/go.rice v1.0.3 h1:ZBLmBdQp6ejc+n8eMNH0uuRSKkg6kKe6ORjXKnyHBYw=
Expand Down Expand Up @@ -272,6 +273,8 @@ github.com/leonelquinteros/gotext v1.4.0/go.mod h1:yZGXREmoGTtBvZHNcc+Yfug49G/2s
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4=
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYthEiA=
github.com/manifoldco/promptui v0.9.0/go.mod h1:ka04sppxSGFAtxX0qhlYQjISsg9mR4GWtQEhdbn6Pgg=
github.com/marcinbor85/gohex v0.0.0-20210308104911-55fb1c624d84/go.mod h1:Pb6XcsXyropB9LNHhnqaknG/vEwYztLkQzVCHv8sQ3M=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU=
Expand Down Expand Up @@ -499,17 +502,13 @@ golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81R
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
golang.org/x/net v0.0.0-20211101193420-4a448f8816b3 h1:VrJZAjbekhoRn7n5FBujY31gboH+iB3pdLxn3gE9FjU=
golang.org/x/net v0.0.0-20211101193420-4a448f8816b3/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20211028175245-ba495a64dcb5 h1:v79phzBz03tsVCUTbvTBmmC3CUXF5mKYt7DA4ZVldpM=
golang.org/x/oauth2 v0.0.0-20211028175245-ba495a64dcb5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 h1:RerP+noqYHUQ8CMRcPlC2nvTa4dcBIjegkuWdcUDuqg=
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
Expand All @@ -528,6 +527,7 @@ golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
Expand Down