From b11cb5f95bc17aad9af42174c5f14d021461589b Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Thu, 4 Apr 2024 13:34:11 -0700 Subject: [PATCH 01/86] Move and refactor scaffold logic --- internal/super/scaffolds.go | 159 ++++++++++++++++++++++++++++++++++++ internal/super/setup.go | 139 ++----------------------------- 2 files changed, 168 insertions(+), 130 deletions(-) create mode 100644 internal/super/scaffolds.go diff --git a/internal/super/scaffolds.go b/internal/super/scaffolds.go new file mode 100644 index 000000000..08bd2944f --- /dev/null +++ b/internal/super/scaffolds.go @@ -0,0 +1,159 @@ +/* + * Flow CLI + * + * Copyright 2019 Dapper Labs, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package super + +import ( + "encoding/json" + "fmt" + "github.com/go-git/go-git/v5" + "github.com/go-git/go-git/v5/plumbing" + "github.com/onflow/flow-cli/internal/util" + "github.com/onflow/flowkit/output" + "io" + "net/http" + "os" + "path/filepath" + "time" +) + +const scaffoldListURL = "https://raw.githubusercontent.com/onflow/flow-cli/master/scaffolds.json" + +type scaffold struct { + Repo string `json:"repo"` + Branch string `json:"branch"` + Name string `json:"name"` + Description string `json:"description"` + Commit string `json:"commit"` + Folder string `json:"folder"` + Type string `json:"type"` +} + +func selectScaffold(logger output.Logger) (*scaffold, error) { + scaffolds, err := getScaffolds() + if err != nil { + return nil, err + } + + // default to first scaffold - basic scaffold + pickedScaffold := scaffolds[0] + + if setupFlags.ScaffoldID != 0 { + if setupFlags.ScaffoldID > len(scaffolds) { + return nil, fmt.Errorf("scaffold with id %d does not exist", setupFlags.ScaffoldID) + } + pickedScaffold = scaffolds[setupFlags.ScaffoldID-1] + } + + if setupFlags.Scaffold { + scaffoldItems := make([]util.ScaffoldItem, 0) + for i, s := range scaffolds { + scaffoldItems = append( + scaffoldItems, + util.ScaffoldItem{ + Index: i, + Title: fmt.Sprintf("%s - %s", output.Bold(s.Name), s.Description), + Category: s.Type, + }, + ) + } + + selected := util.ScaffoldPrompt(logger, scaffoldItems) + pickedScaffold = scaffolds[selected] + } + + return &pickedScaffold, nil +} + +func getScaffolds() ([]scaffold, error) { + httpClient := http.Client{ + Timeout: time.Second * 5, + } + + req, err := http.NewRequest(http.MethodGet, scaffoldListURL, nil) + if err != nil { + return nil, fmt.Errorf("failed creating request for scaffold list: %w", err) + } + + res, err := httpClient.Do(req) + if err != nil { + return nil, fmt.Errorf("failed requesting scaffold list: %w", err) + } + if res.Body != nil { + defer res.Body.Close() + } + + body, err := io.ReadAll(res.Body) + if err != nil { + return nil, fmt.Errorf("failed reading scaffold list response: %w", err) + } + + var all []scaffold + err = json.Unmarshal(body, &all) + if err != nil { + return nil, fmt.Errorf("failed parsing scaffold list response: %w", err) + } + + valid := make([]scaffold, 0) + for _, s := range all { + if s.Repo != "" && s.Description != "" && s.Name != "" && s.Commit != "" { + valid = append(valid, s) + } + } + + return valid, nil +} + +func cloneScaffold(targetDir string, conf scaffold) error { + repo, err := git.PlainClone(targetDir, false, &git.CloneOptions{ + URL: conf.Repo, + }) + if err != nil { + return fmt.Errorf("could not download the scaffold: %w", err) + } + + worktree, _ := repo.Worktree() + err = worktree.Checkout(&git.CheckoutOptions{ + Hash: plumbing.NewHash(conf.Commit), + Force: true, + }) + if err != nil { + return fmt.Errorf("could not find the scaffold version") + } + + // if we defined a folder remove everything else + if conf.Folder != "" { + err = os.Rename( + filepath.Join(targetDir, conf.Folder), + filepath.Join(targetDir, "../scaffold-temp"), + ) + if err != nil { + return err + } + + if err = os.RemoveAll(targetDir); err != nil { + return err + } + + if err = os.Rename(filepath.Join(targetDir, "../scaffold-temp"), targetDir); err != nil { + return err + } + } + + return os.RemoveAll(filepath.Join(targetDir, ".git")) +} diff --git a/internal/super/setup.go b/internal/super/setup.go index b44daa6dc..2fa1b991e 100644 --- a/internal/super/setup.go +++ b/internal/super/setup.go @@ -20,23 +20,16 @@ package super import ( "bytes" - "encoding/json" "fmt" + "github.com/spf13/cobra" "io" - "net/http" "os" "path/filepath" - "time" - - "github.com/go-git/go-git/v5" - "github.com/go-git/go-git/v5/plumbing" - "github.com/spf13/cobra" "github.com/onflow/flowkit" "github.com/onflow/flowkit/output" "github.com/onflow/flow-cli/internal/command" - "github.com/onflow/flow-cli/internal/util" ) type flagsSetup struct { @@ -58,18 +51,6 @@ var SetupCommand = &command.Command{ Run: create, } -const scaffoldListURL = "https://raw.githubusercontent.com/onflow/flow-cli/master/scaffolds.json" - -type scaffold struct { - Repo string `json:"repo"` - Branch string `json:"branch"` - Name string `json:"name"` - Description string `json:"description"` - Commit string `json:"commit"` - Folder string `json:"folder"` - Type string `json:"type"` -} - func create( args []string, _ command.GlobalFlags, @@ -82,43 +63,19 @@ func create( return nil, err } - scaffolds, err := getScaffolds() + selectedScaffold, err := selectScaffold(logger) if err != nil { - return nil, err - } - - // default to first scaffold - basic scaffold - pickedScaffold := scaffolds[0] - - if setupFlags.ScaffoldID != 0 { - if setupFlags.ScaffoldID > len(scaffolds) { - return nil, fmt.Errorf("scaffold with id %d does not exist", setupFlags.ScaffoldID) - } - pickedScaffold = scaffolds[setupFlags.ScaffoldID-1] - } - - if setupFlags.Scaffold { - scaffoldItems := make([]util.ScaffoldItem, 0) - for i, s := range scaffolds { - scaffoldItems = append( - scaffoldItems, - util.ScaffoldItem{ - Index: i, - Title: fmt.Sprintf("%s - %s", output.Bold(s.Name), s.Description), - Category: s.Type, - }, - ) - } - - selected := util.ScaffoldPrompt(logger, scaffoldItems) - pickedScaffold = scaffolds[selected] + return nil, fmt.Errorf("error selecting scaffold %w", err) } logger.StartProgress(fmt.Sprintf("Creating your project %s", targetDir)) defer logger.StopProgress() - err = cloneScaffold(targetDir, pickedScaffold) - if err != nil { - return nil, fmt.Errorf("failed creating scaffold %w", err) + + if selectedScaffold != nil { + err = cloneScaffold(targetDir, *selectedScaffold) + if err != nil { + return nil, fmt.Errorf("failed creating scaffold %w", err) + } } return &setupResult{targetDir: targetDir}, nil @@ -151,84 +108,6 @@ func getTargetDirectory(directory string) (string, error) { return target, nil } -func getScaffolds() ([]scaffold, error) { - httpClient := http.Client{ - Timeout: time.Second * 5, - } - - req, err := http.NewRequest(http.MethodGet, scaffoldListURL, nil) - if err != nil { - return nil, fmt.Errorf("failed creating request for scaffold list: %w", err) - } - - res, err := httpClient.Do(req) - if err != nil { - return nil, fmt.Errorf("failed requesting scaffold list: %w", err) - } - if res.Body != nil { - defer res.Body.Close() - } - - body, err := io.ReadAll(res.Body) - if err != nil { - return nil, fmt.Errorf("failed reading scaffold list response: %w", err) - } - - var all []scaffold - err = json.Unmarshal(body, &all) - if err != nil { - return nil, fmt.Errorf("failed parsing scaffold list response: %w", err) - } - - valid := make([]scaffold, 0) - for _, s := range all { - if s.Repo != "" && s.Description != "" && s.Name != "" && s.Commit != "" { - valid = append(valid, s) - } - } - - return valid, nil -} - -func cloneScaffold(targetDir string, conf scaffold) error { - repo, err := git.PlainClone(targetDir, false, &git.CloneOptions{ - URL: conf.Repo, - }) - if err != nil { - return fmt.Errorf("could not download the scaffold: %w", err) - } - - worktree, _ := repo.Worktree() - err = worktree.Checkout(&git.CheckoutOptions{ - Hash: plumbing.NewHash(conf.Commit), - Force: true, - }) - if err != nil { - return fmt.Errorf("could not find the scaffold version") - } - - // if we defined a folder remove everything else - if conf.Folder != "" { - err = os.Rename( - filepath.Join(targetDir, conf.Folder), - filepath.Join(targetDir, "../scaffold-temp"), - ) - if err != nil { - return err - } - - if err = os.RemoveAll(targetDir); err != nil { - return err - } - - if err = os.Rename(filepath.Join(targetDir, "../scaffold-temp"), targetDir); err != nil { - return err - } - } - - return os.RemoveAll(filepath.Join(targetDir, ".git")) -} - type setupResult struct { targetDir string } From 813d1a6c7a3095656341586cbb0928c31e0e24de Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Fri, 5 Apr 2024 13:06:26 -0700 Subject: [PATCH 02/86] Refactor init config function to be separate from command --- internal/config/init.go | 66 ++++++++++++++++++++++++++++------------- 1 file changed, 46 insertions(+), 20 deletions(-) diff --git a/internal/config/init.go b/internal/config/init.go index 68dda9f0c..16642f39a 100644 --- a/internal/config/init.go +++ b/internal/config/init.go @@ -52,23 +52,27 @@ var initCommand = &command.Command{ Run: Initialise, } -func Initialise( - _ []string, - _ command.GlobalFlags, - logger output.Logger, - readerWriter flowkit.ReaderWriter, - _ flowkit.Services, -) (command.Result, error) { +// InitConfigParameters holds all necessary parameters for initializing the configuration. +type InitConfigParameters struct { + ServicePrivateKey string + ServiceKeySigAlgo string + ServiceKeyHashAlgo string + Reset bool + Global bool +} + +// InitializeConfiguration creates the Flow configuration json file based on the provided parameters. +func InitializeConfiguration(params InitConfigParameters, logger output.Logger, readerWriter flowkit.ReaderWriter) (*flowkit.State, error) { logger.Info("⚠️Notice: for starting a new project prefer using 'flow setup'.") - sigAlgo := crypto.StringToSignatureAlgorithm(InitFlag.ServiceKeySigAlgo) + sigAlgo := crypto.StringToSignatureAlgorithm(params.ServiceKeySigAlgo) if sigAlgo == crypto.UnknownSignatureAlgorithm { - return nil, fmt.Errorf("invalid signature algorithm: %s", InitFlag.ServiceKeySigAlgo) + return nil, fmt.Errorf("invalid signature algorithm: %s", params.ServiceKeySigAlgo) } - hashAlgo := crypto.StringToHashAlgorithm(InitFlag.ServiceKeyHashAlgo) + hashAlgo := crypto.StringToHashAlgorithm(params.ServiceKeyHashAlgo) if hashAlgo == crypto.UnknownHashAlgorithm { - return nil, fmt.Errorf("invalid hash algorithm: %s", InitFlag.ServiceKeyHashAlgo) + return nil, fmt.Errorf("invalid hash algorithm: %s", params.ServiceKeyHashAlgo) } state, err := flowkit.Init(readerWriter, sigAlgo, hashAlgo) @@ -76,8 +80,8 @@ func Initialise( return nil, err } - if InitFlag.ServicePrivateKey != "" { - privateKey, err := crypto.DecodePrivateKeyHex(sigAlgo, InitFlag.ServicePrivateKey) + if params.ServicePrivateKey != "" { + privateKey, err := crypto.DecodePrivateKeyHex(sigAlgo, params.ServicePrivateKey) if err != nil { return nil, fmt.Errorf("invalid private key: %w", err) } @@ -86,11 +90,11 @@ func Initialise( } path := config.DefaultPath - if InitFlag.Global { + if params.Global { path = config.GlobalPath() } - if config.Exists(path) && !InitFlag.Reset { + if config.Exists(path) && !params.Reset { return nil, fmt.Errorf( "configuration already exists at: %s, if you want to reset configuration use the reset flag", path, @@ -102,18 +106,40 @@ func Initialise( return nil, err } - return &initResult{State: state}, nil + return state, nil +} + +func Initialise( + _ []string, + _ command.GlobalFlags, + logger output.Logger, + readerWriter flowkit.ReaderWriter, + _ flowkit.Services, +) (command.Result, error) { + params := InitConfigParameters{ + ServicePrivateKey: InitFlag.ServicePrivateKey, + ServiceKeySigAlgo: InitFlag.ServiceKeySigAlgo, + ServiceKeyHashAlgo: InitFlag.ServiceKeyHashAlgo, + Reset: InitFlag.Reset, + Global: InitFlag.Global, + } + state, err := InitializeConfiguration(params, logger, readerWriter) + if err != nil { + return nil, err + } + + return &InitResult{State: state}, nil } -type initResult struct { +type InitResult struct { *flowkit.State } -func (r *initResult) JSON() any { +func (r *InitResult) JSON() any { return r } -func (r *initResult) String() string { +func (r *InitResult) String() string { var b bytes.Buffer writer := util.CreateTabWriter(&b) account, _ := r.State.EmulatorServiceAccount() @@ -130,6 +156,6 @@ func (r *initResult) String() string { return b.String() } -func (r *initResult) Oneliner() string { +func (r *InitResult) Oneliner() string { return "" } From fe4b4e223a6af738dbd3669e6779a805b4eb4e09 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Mon, 8 Apr 2024 14:45:21 -0700 Subject: [PATCH 03/86] Create init in setup --- internal/config/init.go | 22 ++++++++++++++++++---- internal/super/setup.go | 39 +++++++++++++++++++++++++++++---------- 2 files changed, 47 insertions(+), 14 deletions(-) diff --git a/internal/config/init.go b/internal/config/init.go index 16642f39a..651803e87 100644 --- a/internal/config/init.go +++ b/internal/config/init.go @@ -21,9 +21,9 @@ package config import ( "bytes" "fmt" - "github.com/onflow/flow-go-sdk/crypto" "github.com/spf13/cobra" + "os" "github.com/onflow/flowkit" "github.com/onflow/flowkit/config" @@ -59,6 +59,7 @@ type InitConfigParameters struct { ServiceKeyHashAlgo string Reset bool Global bool + TargetDirectory string } // InitializeConfiguration creates the Flow configuration json file based on the provided parameters. @@ -89,9 +90,22 @@ func InitializeConfiguration(params InitConfigParameters, logger output.Logger, state.SetEmulatorKey(privateKey) } - path := config.DefaultPath - if params.Global { - path = config.GlobalPath() + var path string + if params.TargetDirectory != "" { + path = fmt.Sprintf("%s/flow.json", params.TargetDirectory) + + // Create the directory if it doesn't exist + err := state.ReaderWriter().MkdirAll(params.TargetDirectory, os.ModePerm) + if err != nil { + return nil, fmt.Errorf("failed to create target directory: %w", err) + } + } else { + // Otherwise, choose between the default and global paths + if params.Global { + path = config.GlobalPath() + } else { + path = config.DefaultPath + } } if config.Exists(path) && !params.Reset { diff --git a/internal/super/setup.go b/internal/super/setup.go index 2fa1b991e..240f56aec 100644 --- a/internal/super/setup.go +++ b/internal/super/setup.go @@ -21,6 +21,7 @@ package super import ( "bytes" "fmt" + "github.com/onflow/flow-cli/internal/config" "github.com/spf13/cobra" "io" "os" @@ -33,6 +34,7 @@ import ( ) type flagsSetup struct { + ConfigOnly bool `default:"false" flag:"config-only" info:"Only create a flow.json default config"` Scaffold bool `default:"" flag:"scaffold" info:"Interactively select a provided scaffold for project creation"` ScaffoldID int `default:"" flag:"scaffold-id" info:"Use provided scaffold ID for project creation"` } @@ -55,7 +57,7 @@ func create( args []string, _ command.GlobalFlags, logger output.Logger, - _ flowkit.ReaderWriter, + readerWriter flowkit.ReaderWriter, _ flowkit.Services, ) (command.Result, error) { targetDir, err := getTargetDirectory(args[0]) @@ -63,18 +65,35 @@ func create( return nil, err } - selectedScaffold, err := selectScaffold(logger) - if err != nil { - return nil, fmt.Errorf("error selecting scaffold %w", err) - } + if setupFlags.Scaffold || setupFlags.ScaffoldID != 0 { + selectedScaffold, err := selectScaffold(logger) + if err != nil { + return nil, fmt.Errorf("error selecting scaffold %w", err) + } - logger.StartProgress(fmt.Sprintf("Creating your project %s", targetDir)) - defer logger.StopProgress() + logger.StartProgress(fmt.Sprintf("Creating your project %s", targetDir)) + defer logger.StopProgress() - if selectedScaffold != nil { - err = cloneScaffold(targetDir, *selectedScaffold) + if selectedScaffold != nil { + err = cloneScaffold(targetDir, *selectedScaffold) + if err != nil { + return nil, fmt.Errorf("failed creating scaffold %w", err) + } + } + } else { + + // TODO: Ask for project name if not given + + params := config.InitConfigParameters{ + ServiceKeySigAlgo: "ECDSA_P256", + ServiceKeyHashAlgo: "SHA3_256", + Reset: false, + Global: false, + TargetDirectory: targetDir, + } + _, err := config.InitializeConfiguration(params, logger, readerWriter) if err != nil { - return nil, fmt.Errorf("failed creating scaffold %w", err) + return nil, fmt.Errorf("failed to initialize configuration: %w", err) } } From d094f92583a8d120aa73cf2ec99d478e076cab91 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Mon, 8 Apr 2024 15:21:55 -0700 Subject: [PATCH 04/86] Create test --- internal/super/setup_test.go | 50 ++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 internal/super/setup_test.go diff --git a/internal/super/setup_test.go b/internal/super/setup_test.go new file mode 100644 index 000000000..7666159a3 --- /dev/null +++ b/internal/super/setup_test.go @@ -0,0 +1,50 @@ +/* + * Flow CLI + * + * Copyright 2019 Dapper Labs, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package super + +import ( + "fmt" + "github.com/onflow/flow-cli/internal/command" + "github.com/onflow/flow-cli/internal/util" + "github.com/onflow/flowkit/output" + "github.com/stretchr/testify/assert" + "os" + "path/filepath" + "testing" +) + +func TestCreate(t *testing.T) { + logger := output.NewStdoutLogger(output.NoneLog) + _, state, _ := util.TestMocks(t) + + projectName := "foobar" + + // Test project creation + _, err := create([]string{projectName}, command.GlobalFlags{}, logger, state.ReaderWriter(), nil) + assert.NoError(t, err, "Failed to create project") + + // Check project was created in target directory which is in pwd + pwd, err := os.Getwd() + assert.NoError(t, err, "Failed to get working directory") + + target := filepath.Join(pwd, fmt.Sprintf("%s/flow.json", projectName)) + + _, err = state.ReaderWriter().ReadFile(target) + assert.NoError(t, err, "Failed to read generated file") +} From 10c549a649e35e3a4382caba8995877277fc0b1e Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Mon, 8 Apr 2024 15:22:48 -0700 Subject: [PATCH 05/86] Add name prompt --- internal/super/setup.go | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/internal/super/setup.go b/internal/super/setup.go index 240f56aec..5d52d625d 100644 --- a/internal/super/setup.go +++ b/internal/super/setup.go @@ -22,6 +22,7 @@ import ( "bytes" "fmt" "github.com/onflow/flow-cli/internal/config" + "github.com/onflow/flow-cli/internal/util" "github.com/spf13/cobra" "io" "os" @@ -46,7 +47,7 @@ var SetupCommand = &command.Command{ Use: "setup ", Short: "Start a new Flow project", Example: "flow setup my-project", - Args: cobra.ExactArgs(1), + Args: cobra.MaximumNArgs(1), GroupID: "super", }, Flags: &setupFlags, @@ -60,12 +61,15 @@ func create( readerWriter flowkit.ReaderWriter, _ flowkit.Services, ) (command.Result, error) { - targetDir, err := getTargetDirectory(args[0]) - if err != nil { - return nil, err - } + var targetDir string + var err error if setupFlags.Scaffold || setupFlags.ScaffoldID != 0 { + targetDir, err = getTargetDirectory(args[0]) + if err != nil { + return nil, err + } + selectedScaffold, err := selectScaffold(logger) if err != nil { return nil, fmt.Errorf("error selecting scaffold %w", err) @@ -81,8 +85,19 @@ func create( } } } else { - - // TODO: Ask for project name if not given + // Ask for project name if not given + if len(args) < 1 { + name := util.NamePrompt() + targetDir, err = getTargetDirectory(name) + if err != nil { + return nil, err + } + } else { + targetDir, err = getTargetDirectory(args[0]) + if err != nil { + return nil, err + } + } params := config.InitConfigParameters{ ServiceKeySigAlgo: "ECDSA_P256", From c9380a4315ff1ee9a2f8a6fdd8d4822043bae6ce Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Mon, 8 Apr 2024 16:19:49 -0700 Subject: [PATCH 06/86] Refactor to take directory as arg --- internal/super/generate.go | 12 +++++++----- internal/super/generate_test.go | 23 ++++++++++------------- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/internal/super/generate.go b/internal/super/generate.go index ae077220e..87962f347 100644 --- a/internal/super/generate.go +++ b/internal/super/generate.go @@ -102,7 +102,7 @@ func generateContract( flow flowkit.Services, state *flowkit.State, ) (result command.Result, err error) { - return generateNew(args, "contract", logger, state) + return generateNew(args, "contract", generateFlags.Directory, logger, state) } func generateTransaction( @@ -112,7 +112,7 @@ func generateTransaction( flow flowkit.Services, state *flowkit.State, ) (result command.Result, err error) { - return generateNew(args, "transaction", logger, state) + return generateNew(args, "transaction", generateFlags.Directory, logger, state) } func generateScript( @@ -122,7 +122,7 @@ func generateScript( flow flowkit.Services, state *flowkit.State, ) (result command.Result, err error) { - return generateNew(args, "script", logger, state) + return generateNew(args, "script", generateFlags.Directory, logger, state) } func addCDCExtension(name string) string { @@ -161,6 +161,7 @@ func processTemplate(templatePath string, data map[string]interface{}) (string, func generateNew( args []string, templateType string, + directory string, logger output.Logger, state *flowkit.State, ) (result command.Result, err error) { @@ -175,8 +176,9 @@ func generateNew( var testFileToWrite string var basePath string - if generateFlags.Directory != "" { - basePath = generateFlags.Directory + if directory != "" { + basePath = directory + fmt.Println("Directory: ", directory) } else { switch templateType { case "contract": diff --git a/internal/super/generate_test.go b/internal/super/generate_test.go index 8a7a37b12..6a6bc470c 100644 --- a/internal/super/generate_test.go +++ b/internal/super/generate_test.go @@ -33,7 +33,7 @@ func TestGenerateNewContract(t *testing.T) { _, state, _ := util.TestMocks(t) // Test contract generation - _, err := generateNew([]string{"TestContract"}, "contract", logger, state) + _, err := generateNew([]string{"TestContract"}, "contract", "", logger, state) assert.NoError(t, err, "Failed to generate contract") fileContent, err := state.ReaderWriter().ReadFile("cadence/contracts/TestContract.cdc") @@ -68,7 +68,7 @@ access(all) fun testContract() { assert.Equal(t, expectedTestContent, string(testContent)) // Test file already exists scenario - _, err = generateNew([]string{"TestContract"}, "contract", logger, state) + _, err = generateNew([]string{"TestContract"}, "contract", "", logger, state) assert.Error(t, err) assert.Equal(t, "file already exists: cadence/contracts/TestContract.cdc", err.Error()) } @@ -84,7 +84,7 @@ func TestGenerateNewContractSkipTests(t *testing.T) { }) // Test contract generation - _, err := generateNew([]string{"TestContract"}, "contract", logger, state) + _, err := generateNew([]string{"TestContract"}, "contract", "", logger, state) assert.NoError(t, err, "Failed to generate contract") fileContent, err := state.ReaderWriter().ReadFile("cadence/contracts/TestContract.cdc") @@ -101,7 +101,7 @@ func TestGenerateNewContractWithCDCExtension(t *testing.T) { _, state, _ := util.TestMocks(t) // Test contract generation - _, err := generateNew([]string{"Tester.cdc"}, "contract", logger, state) + _, err := generateNew([]string{"Tester.cdc"}, "contract", "", logger, state) assert.NoError(t, err, "Failed to generate contract") fileContent, err := state.ReaderWriter().ReadFile("cadence/contracts/Tester.cdc") @@ -118,7 +118,7 @@ func TestGenerateNewContractFileAlreadyExists(t *testing.T) { _, state, _ := util.TestMocks(t) // Test contract generation - _, err := generateNew([]string{"TestContract"}, "contract", logger, state) + _, err := generateNew([]string{"TestContract"}, "contract", "", logger, state) assert.NoError(t, err, "Failed to generate contract") //// Check if the file exists in the correct directory @@ -127,7 +127,7 @@ func TestGenerateNewContractFileAlreadyExists(t *testing.T) { assert.NotNil(t, content) // Test file already exists scenario - _, err = generateNew([]string{"TestContract"}, "contract", logger, state) + _, err = generateNew([]string{"TestContract"}, "contract", "", logger, state) assert.Error(t, err) assert.Equal(t, "file already exists: cadence/contracts/TestContract.cdc", err.Error()) } @@ -136,7 +136,7 @@ func TestGenerateNewContractWithFileExtension(t *testing.T) { logger := output.NewStdoutLogger(output.NoneLog) _, state, _ := util.TestMocks(t) - _, err := generateNew([]string{"TestContract.cdc"}, "contract", logger, state) + _, err := generateNew([]string{"TestContract.cdc"}, "contract", "", logger, state) assert.NoError(t, err, "Failed to generate contract") // Check file exists @@ -149,7 +149,7 @@ func TestGenerateNewScript(t *testing.T) { logger := output.NewStdoutLogger(output.NoneLog) _, state, _ := util.TestMocks(t) - _, err := generateNew([]string{"TestScript"}, "script", logger, state) + _, err := generateNew([]string{"TestScript"}, "script", "", logger, state) assert.NoError(t, err, "Failed to generate contract") content, err := state.ReaderWriter().ReadFile("cadence/scripts/TestScript.cdc") @@ -167,7 +167,7 @@ func TestGenerateNewTransaction(t *testing.T) { logger := output.NewStdoutLogger(output.NoneLog) _, state, _ := util.TestMocks(t) - _, err := generateNew([]string{"TestTransaction"}, "transaction", logger, state) + _, err := generateNew([]string{"TestTransaction"}, "transaction", "", logger, state) assert.NoError(t, err, "Failed to generate contract") content, err := state.ReaderWriter().ReadFile("cadence/transactions/TestTransaction.cdc") @@ -186,10 +186,7 @@ func TestGenerateNewWithDirFlag(t *testing.T) { logger := output.NewStdoutLogger(output.NoneLog) _, state, _ := util.TestMocks(t) - // Set a custom directory - generateFlags.Directory = "customDir" - - _, err := generateNew([]string{"TestContract"}, "contract", logger, state) + _, err := generateNew([]string{"TestContract"}, "contract", "customDir", logger, state) assert.NoError(t, err, "Failed to generate contract") content, err := state.ReaderWriter().ReadFile("customDir/TestContract.cdc") From 4843b15394fbb67b1d0f5289fa4a3ebaf0f9aff5 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Tue, 9 Apr 2024 13:48:14 -0700 Subject: [PATCH 07/86] Change to fit new definition --- internal/super/setup.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/super/setup.go b/internal/super/setup.go index 5d52d625d..79ebd90e8 100644 --- a/internal/super/setup.go +++ b/internal/super/setup.go @@ -51,15 +51,15 @@ var SetupCommand = &command.Command{ GroupID: "super", }, Flags: &setupFlags, - Run: create, + RunS: create, } func create( args []string, _ command.GlobalFlags, logger output.Logger, - readerWriter flowkit.ReaderWriter, _ flowkit.Services, + state *flowkit.State, ) (command.Result, error) { var targetDir string var err error @@ -106,7 +106,7 @@ func create( Global: false, TargetDirectory: targetDir, } - _, err := config.InitializeConfiguration(params, logger, readerWriter) + _, err := config.InitializeConfiguration(params, logger, state.ReaderWriter()) if err != nil { return nil, fmt.Errorf("failed to initialize configuration: %w", err) } From 591ecbb1aee00220c0b33ea3c5f31a278a2b3d92 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Tue, 9 Apr 2024 14:07:23 -0700 Subject: [PATCH 08/86] Fix test --- internal/super/setup_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/super/setup_test.go b/internal/super/setup_test.go index 7666159a3..761130dcd 100644 --- a/internal/super/setup_test.go +++ b/internal/super/setup_test.go @@ -36,7 +36,7 @@ func TestCreate(t *testing.T) { projectName := "foobar" // Test project creation - _, err := create([]string{projectName}, command.GlobalFlags{}, logger, state.ReaderWriter(), nil) + _, err := create([]string{projectName}, command.GlobalFlags{}, logger, nil, state) assert.NoError(t, err, "Failed to create project") // Check project was created in target directory which is in pwd From 47e5d19f0b4058c143b62a742334fa92d93095ae Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Tue, 9 Apr 2024 14:09:37 -0700 Subject: [PATCH 09/86] Ignore arg --- internal/super/generate.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/super/generate.go b/internal/super/generate.go index 87962f347..dd9948afa 100644 --- a/internal/super/generate.go +++ b/internal/super/generate.go @@ -99,7 +99,7 @@ func generateContract( args []string, _ command.GlobalFlags, logger output.Logger, - flow flowkit.Services, + _ flowkit.Services, state *flowkit.State, ) (result command.Result, err error) { return generateNew(args, "contract", generateFlags.Directory, logger, state) @@ -109,7 +109,7 @@ func generateTransaction( args []string, _ command.GlobalFlags, logger output.Logger, - flow flowkit.Services, + _ flowkit.Services, state *flowkit.State, ) (result command.Result, err error) { return generateNew(args, "transaction", generateFlags.Directory, logger, state) @@ -119,7 +119,7 @@ func generateScript( args []string, _ command.GlobalFlags, logger output.Logger, - flow flowkit.Services, + _ flowkit.Services, state *flowkit.State, ) (result command.Result, err error) { return generateNew(args, "script", generateFlags.Directory, logger, state) From 6c0ff3970f96a614d106352f3343098f74f3fd81 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Tue, 9 Apr 2024 14:15:07 -0700 Subject: [PATCH 10/86] Fix test path --- internal/super/generate.go | 3 ++- internal/super/generate_test.go | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/internal/super/generate.go b/internal/super/generate.go index dd9948afa..ac5e54877 100644 --- a/internal/super/generate.go +++ b/internal/super/generate.go @@ -175,9 +175,11 @@ func generateNew( var fileToWrite string var testFileToWrite string var basePath string + var testsBasePath = "cadence/tests" if directory != "" { basePath = directory + testsBasePath = filepath.Join(directory, "tests") fmt.Println("Directory: ", directory) } else { switch templateType { @@ -239,7 +241,6 @@ func generateNew( logger.Info(fmt.Sprintf("Generated new %s: %s at %s", templateType, name, filenameWithBasePath)) if generateFlags.SkipTests != true && templateType == "contract" { - testsBasePath := "cadence/tests" testFilenameWithBasePath := filepath.Join(testsBasePath, addCDCExtension(fmt.Sprintf("%s_test", name))) if _, err := state.ReaderWriter().ReadFile(testFilenameWithBasePath); err == nil { diff --git a/internal/super/generate_test.go b/internal/super/generate_test.go index 6a6bc470c..8ed4ba731 100644 --- a/internal/super/generate_test.go +++ b/internal/super/generate_test.go @@ -193,6 +193,10 @@ func TestGenerateNewWithDirFlag(t *testing.T) { assert.NoError(t, err, "Failed to read generated file") assert.NotNil(t, content) + testContent, err := state.ReaderWriter().ReadFile("customDir/tests/TestContract_test.cdc") + assert.NoError(t, err, "Failed to read generated file") + assert.NotNil(t, testContent) + expectedContent := `access(all) contract TestContract { init() {} From 5bf6499c753b1bf2adaf206b43b55465f2817ab4 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Tue, 9 Apr 2024 14:38:46 -0700 Subject: [PATCH 11/86] Fix generate custom directory logic --- internal/super/generate.go | 35 +++++++++++++++------------------ internal/super/generate_test.go | 2 +- 2 files changed, 17 insertions(+), 20 deletions(-) diff --git a/internal/super/generate.go b/internal/super/generate.go index ac5e54877..82fd5ff13 100644 --- a/internal/super/generate.go +++ b/internal/super/generate.go @@ -174,28 +174,21 @@ func generateNew( var fileToWrite string var testFileToWrite string + var rootDir = "cadence" var basePath string - var testsBasePath = "cadence/tests" + var testsBasePath = "tests" if directory != "" { - basePath = directory - testsBasePath = filepath.Join(directory, "tests") - fmt.Println("Directory: ", directory) - } else { - switch templateType { - case "contract": - basePath = "cadence/contracts" - case "script": - basePath = "cadence/scripts" - case "transaction": - basePath = "cadence/transactions" - default: - return nil, fmt.Errorf("invalid template type: %s", templateType) - } + fmt.Println("directory: ", directory) + rootDir = directory + fmt.Println("rootDir in scope: ", rootDir) } + fmt.Println("rootDir: ", rootDir) + switch templateType { case "contract": + basePath = "contracts" nameData := map[string]interface{}{"Name": name} fileToWrite, err = processTemplate("templates/contract_init.cdc.tmpl", nameData) if err != nil { @@ -207,11 +200,13 @@ func generateNew( return nil, fmt.Errorf("error generating contract test template: %w", err) } case "script": + basePath = "scripts" fileToWrite, err = processTemplate("templates/script_init.cdc.tmpl", nil) if err != nil { return nil, fmt.Errorf("error generating script template: %w", err) } case "transaction": + basePath = "transactions" fileToWrite, err = processTemplate("templates/transaction_init.cdc.tmpl", nil) if err != nil { return nil, fmt.Errorf("error generating transaction template: %w", err) @@ -220,7 +215,8 @@ func generateNew( return nil, fmt.Errorf("invalid template type: %s", templateType) } - filenameWithBasePath := filepath.Join(basePath, filename) + directoryWithBasePath := filepath.Join(rootDir, basePath) + filenameWithBasePath := filepath.Join(rootDir, basePath, filename) // Check file existence if _, err := state.ReaderWriter().ReadFile(filenameWithBasePath); err == nil { @@ -228,7 +224,7 @@ func generateNew( } // Ensure the directory exists - if err := state.ReaderWriter().MkdirAll(basePath, 0755); err != nil { + if err := state.ReaderWriter().MkdirAll(directoryWithBasePath, 0755); err != nil { return nil, fmt.Errorf("error creating directories: %w", err) } @@ -241,13 +237,14 @@ func generateNew( logger.Info(fmt.Sprintf("Generated new %s: %s at %s", templateType, name, filenameWithBasePath)) if generateFlags.SkipTests != true && templateType == "contract" { - testFilenameWithBasePath := filepath.Join(testsBasePath, addCDCExtension(fmt.Sprintf("%s_test", name))) + testDirectoryWithBasePath := filepath.Join(rootDir, testsBasePath) + testFilenameWithBasePath := filepath.Join(rootDir, testsBasePath, addCDCExtension(fmt.Sprintf("%s_test", name))) if _, err := state.ReaderWriter().ReadFile(testFilenameWithBasePath); err == nil { return nil, fmt.Errorf("file already exists: %s", testFilenameWithBasePath) } - if err := state.ReaderWriter().MkdirAll(testsBasePath, 0755); err != nil { + if err := state.ReaderWriter().MkdirAll(testDirectoryWithBasePath, 0755); err != nil { return nil, fmt.Errorf("error creating test directory: %w", err) } diff --git a/internal/super/generate_test.go b/internal/super/generate_test.go index 8ed4ba731..c21ef688d 100644 --- a/internal/super/generate_test.go +++ b/internal/super/generate_test.go @@ -189,7 +189,7 @@ func TestGenerateNewWithDirFlag(t *testing.T) { _, err := generateNew([]string{"TestContract"}, "contract", "customDir", logger, state) assert.NoError(t, err, "Failed to generate contract") - content, err := state.ReaderWriter().ReadFile("customDir/TestContract.cdc") + content, err := state.ReaderWriter().ReadFile("customDir/contracts/TestContract.cdc") assert.NoError(t, err, "Failed to read generated file") assert.NotNil(t, content) From 4f46a92f3ac2e82ea9816785c253df121408ea26 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Tue, 9 Apr 2024 14:47:01 -0700 Subject: [PATCH 12/86] Remove prints --- internal/super/generate.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/internal/super/generate.go b/internal/super/generate.go index 82fd5ff13..2dee91770 100644 --- a/internal/super/generate.go +++ b/internal/super/generate.go @@ -179,13 +179,9 @@ func generateNew( var testsBasePath = "tests" if directory != "" { - fmt.Println("directory: ", directory) rootDir = directory - fmt.Println("rootDir in scope: ", rootDir) } - fmt.Println("rootDir: ", rootDir) - switch templateType { case "contract": basePath = "contracts" From e50fea576d019e2cfb34d618374cf9374f148f83 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Tue, 9 Apr 2024 14:49:15 -0700 Subject: [PATCH 13/86] Generate files for structure --- internal/super/setup.go | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/internal/super/setup.go b/internal/super/setup.go index 79ebd90e8..d9388442c 100644 --- a/internal/super/setup.go +++ b/internal/super/setup.go @@ -110,6 +110,30 @@ func create( if err != nil { return nil, fmt.Errorf("failed to initialize configuration: %w", err) } + + // Generate standard cadence files + // cadence/contracts/DefaultContract.cdc + // cadence/scripts/DefaultScript.cdc + // cadence/transactions/DefaultTransaction.cdc + // cadence/tests/DefaultContract_test.cdc + + directoryPath := filepath.Join(targetDir, "cadence") + + _, err = generateNew([]string{"DefaultContract"}, "contract", directoryPath, logger, state) + if err != nil { + return nil, err + } + + _, err = generateNew([]string{"DefaultScript"}, "script", directoryPath, logger, state) + if err != nil { + return nil, err + } + + _, err = generateNew([]string{"DefaultTransaction"}, "transaction", directoryPath, logger, state) + if err != nil { + return nil, err + } + } return &setupResult{targetDir: targetDir}, nil From 360c4d502931ce525eb271ccd2efa83bc4111bf3 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Tue, 9 Apr 2024 14:55:21 -0700 Subject: [PATCH 14/86] Fix imports --- internal/config/init.go | 3 ++- internal/super/scaffolds.go | 10 ++++++---- internal/super/setup.go | 8 +++++--- internal/super/setup_test.go | 10 ++++++---- 4 files changed, 19 insertions(+), 12 deletions(-) diff --git a/internal/config/init.go b/internal/config/init.go index 651803e87..c7ea5fe47 100644 --- a/internal/config/init.go +++ b/internal/config/init.go @@ -21,9 +21,10 @@ package config import ( "bytes" "fmt" + "os" + "github.com/onflow/flow-go-sdk/crypto" "github.com/spf13/cobra" - "os" "github.com/onflow/flowkit" "github.com/onflow/flowkit/config" diff --git a/internal/super/scaffolds.go b/internal/super/scaffolds.go index 08bd2944f..5c30b9995 100644 --- a/internal/super/scaffolds.go +++ b/internal/super/scaffolds.go @@ -21,15 +21,17 @@ package super import ( "encoding/json" "fmt" - "github.com/go-git/go-git/v5" - "github.com/go-git/go-git/v5/plumbing" - "github.com/onflow/flow-cli/internal/util" - "github.com/onflow/flowkit/output" "io" "net/http" "os" "path/filepath" "time" + + "github.com/go-git/go-git/v5" + "github.com/go-git/go-git/v5/plumbing" + "github.com/onflow/flowkit/output" + + "github.com/onflow/flow-cli/internal/util" ) const scaffoldListURL = "https://raw.githubusercontent.com/onflow/flow-cli/master/scaffolds.json" diff --git a/internal/super/setup.go b/internal/super/setup.go index d9388442c..f5016c26f 100644 --- a/internal/super/setup.go +++ b/internal/super/setup.go @@ -21,13 +21,15 @@ package super import ( "bytes" "fmt" - "github.com/onflow/flow-cli/internal/config" - "github.com/onflow/flow-cli/internal/util" - "github.com/spf13/cobra" "io" "os" "path/filepath" + "github.com/spf13/cobra" + + "github.com/onflow/flow-cli/internal/config" + "github.com/onflow/flow-cli/internal/util" + "github.com/onflow/flowkit" "github.com/onflow/flowkit/output" diff --git a/internal/super/setup_test.go b/internal/super/setup_test.go index 761130dcd..18da37df3 100644 --- a/internal/super/setup_test.go +++ b/internal/super/setup_test.go @@ -20,13 +20,15 @@ package super import ( "fmt" - "github.com/onflow/flow-cli/internal/command" - "github.com/onflow/flow-cli/internal/util" - "github.com/onflow/flowkit/output" - "github.com/stretchr/testify/assert" "os" "path/filepath" "testing" + + "github.com/onflow/flowkit/output" + "github.com/stretchr/testify/assert" + + "github.com/onflow/flow-cli/internal/command" + "github.com/onflow/flow-cli/internal/util" ) func TestCreate(t *testing.T) { From b219e1197acb701935f3b843f8a8a9af260fa2f8 Mon Sep 17 00:00:00 2001 From: Chase Fleming Date: Mon, 15 Apr 2024 16:56:53 -0700 Subject: [PATCH 15/86] Setup should prompt to add core contracts as dependencies and install (#1517) * Bump codecov/codecov-action from 1 to 4 Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 1 to 4. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/v1...v4) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] * Bump actions/add-to-project from 0.4.1 to 0.6.1 Bumps [actions/add-to-project](https://github.com/actions/add-to-project) from 0.4.1 to 0.6.1. - [Release notes](https://github.com/actions/add-to-project/releases) - [Commits](https://github.com/actions/add-to-project/compare/v0.4.1...v0.6.1) --- updated-dependencies: - dependency-name: actions/add-to-project dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Create option select prompt * Create AddMany method in dependency manager * Update flags naming * Add SaveState option to DependencyManager * Add target dir to dependencymanager for imports * Update Flow dependencies to latest version (#1509) * Update to latest Cadence Language Server (#1513) * Save to target dir * Add dependencies when selected * Fix tests * Change to addbysourcestring * Merge master * Fix imports * Remove test * Use constant for network --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jordan Ribbink Co-authored-by: Chase Fleming <1666730+chasefleming@users.noreply.github.com> --- .../workflows/add-issues-to-devx-project.yml | 2 +- .github/workflows/ci.yml | 2 +- go.mod | 39 +++--- go.sum | 95 ++++++++++----- internal/dependencymanager/add.go | 6 +- .../dependencymanager/dependencyinstaller.go | 67 ++++++++-- .../dependencyinstaller_test.go | 115 +++++++++++++++++- internal/dependencymanager/install.go | 4 +- internal/super/setup.go | 67 +++++++++- internal/super/setup_test.go | 52 -------- internal/util/prompt.go | 87 +++++++++++++ 11 files changed, 417 insertions(+), 119 deletions(-) delete mode 100644 internal/super/setup_test.go diff --git a/.github/workflows/add-issues-to-devx-project.yml b/.github/workflows/add-issues-to-devx-project.yml index 252fc9a83..44cd3e14c 100644 --- a/.github/workflows/add-issues-to-devx-project.yml +++ b/.github/workflows/add-issues-to-devx-project.yml @@ -10,7 +10,7 @@ jobs: name: Add issue to project runs-on: ubuntu-latest steps: - - uses: actions/add-to-project@v0.4.1 + - uses: actions/add-to-project@v0.6.1 with: project-url: https://github.com/orgs/onflow/projects/13 github-token: ${{ secrets.GH_ACTION_FOR_PROJECTS }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 14d62a674..792f1410d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -31,7 +31,7 @@ jobs: make check-tidy make check-headers - name: Upload coverage report - uses: codecov/codecov-action@v1 + uses: codecov/codecov-action@v4 with: file: ./coverage.txt flags: unittests diff --git a/go.mod b/go.mod index 365a11a8c..e5c826f96 100644 --- a/go.mod +++ b/go.mod @@ -3,23 +3,24 @@ module github.com/onflow/flow-cli go 1.20 require ( + github.com/charmbracelet/bubbletea v0.25.0 github.com/dukex/mixpanel v1.0.1 github.com/getsentry/sentry-go v0.27.0 github.com/go-git/go-git/v5 v5.11.0 github.com/gosuri/uilive v0.0.4 github.com/logrusorgru/aurora/v4 v4.0.0 github.com/manifoldco/promptui v0.9.0 - github.com/onflow/cadence v0.42.9 - github.com/onflow/cadence-tools/languageserver v0.33.3 - github.com/onflow/cadence-tools/lint v0.14.1 - github.com/onflow/cadence-tools/test v0.14.6 + github.com/onflow/cadence v0.42.10 + github.com/onflow/cadence-tools/languageserver v0.33.5 + github.com/onflow/cadence-tools/lint v0.14.2 + github.com/onflow/cadence-tools/test v0.14.7 github.com/onflow/fcl-dev-wallet v0.7.4 - github.com/onflow/flixkit-go v1.1.2 + github.com/onflow/flixkit-go v1.1.3 github.com/onflow/flow-core-contracts/lib/go/templates v1.2.4-0.20231016154253-a00dbf7c061f - github.com/onflow/flow-emulator v0.61.1 - github.com/onflow/flow-go v0.33.2-0.20240306234901-64ab8d27ea30 - github.com/onflow/flow-go-sdk v0.46.0 - github.com/onflow/flowkit v1.17.1 + github.com/onflow/flow-emulator v0.62.1 + github.com/onflow/flow-go v0.33.2-0.20240412174857-015156b297b5 + github.com/onflow/flow-go-sdk v0.46.2 + github.com/onflow/flowkit v1.17.3 github.com/onflowser/flowser/v3 v3.1.3 github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c github.com/pkg/errors v0.9.1 @@ -49,6 +50,7 @@ require ( github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 // indirect github.com/StackExchange/wmi v1.2.1 // indirect github.com/VictoriaMetrics/fastcache v1.12.1 // indirect + github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bits-and-blooms/bitset v1.10.0 // indirect github.com/btcsuite/btcd/btcec/v2 v2.2.1 // indirect @@ -66,6 +68,7 @@ require ( github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect github.com/consensys/bavard v0.1.13 // indirect github.com/consensys/gnark-crypto v0.12.1 // indirect + github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 // indirect github.com/coreos/go-semver v0.3.0 // indirect github.com/crate-crypto/go-kzg-4844 v0.7.0 // indirect github.com/cyphar/filepath-securejoin v0.2.4 // indirect @@ -83,7 +86,7 @@ require ( github.com/ef-ds/deque v1.0.4 // indirect github.com/emirpasic/gods v1.18.1 // indirect github.com/ethereum/c-kzg-4844 v0.4.0 // indirect - github.com/ethereum/go-ethereum v1.13.5 // indirect + github.com/ethereum/go-ethereum v1.13.10 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/fxamacker/cbor/v2 v2.4.1-0.20230228173756-c0c9f774e40c // indirect @@ -125,7 +128,7 @@ require ( github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/holiman/bloomfilter/v2 v2.0.3 // indirect - github.com/holiman/uint256 v1.2.3 // indirect + github.com/holiman/uint256 v1.2.4 // indirect github.com/iancoleman/orderedmap v0.0.0-20190318233801-ac98e3ecb4b0 // indirect github.com/improbable-eng/grpc-web v0.15.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect @@ -158,9 +161,11 @@ require ( github.com/libp2p/go-msgio v0.3.0 // indirect github.com/lmars/go-slip10 v0.0.0-20190606092855-400ba44fee12 // indirect github.com/logrusorgru/aurora v2.0.3+incompatible // indirect + github.com/lucasb-eyer/go-colorful v1.2.0 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect + github.com/mattn/go-localereader v0.0.1 // indirect github.com/mattn/go-runewidth v0.0.15 // indirect github.com/mattn/go-tty v0.0.4 // indirect github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect @@ -168,6 +173,10 @@ require ( github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mmcloughlin/addchain v0.4.0 // indirect github.com/mr-tron/base58 v1.2.0 // indirect + github.com/muesli/ansi v0.0.0-20211018074035-2e021307bc4b // indirect + github.com/muesli/cancelreader v0.2.2 // indirect + github.com/muesli/reflow v0.3.0 // indirect + github.com/muesli/termenv v0.15.2 // indirect github.com/multiformats/go-base32 v0.1.0 // indirect github.com/multiformats/go-base36 v0.2.0 // indirect github.com/multiformats/go-multiaddr v0.12.2 // indirect @@ -178,12 +187,12 @@ require ( github.com/multiformats/go-varint v0.0.7 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/onflow/atree v0.6.0 // indirect - github.com/onflow/crypto v0.25.0 // indirect - github.com/onflow/flow-cli/flowkit v1.11.0 // indirect + github.com/onflow/crypto v0.25.1 // indirect github.com/onflow/flow-core-contracts/lib/go/contracts v1.2.4-0.20231016154253-a00dbf7c061f // indirect github.com/onflow/flow-ft/lib/go/contracts v0.7.1-0.20230711213910-baad011d2b13 // indirect github.com/onflow/flow-nft/lib/go/contracts v1.1.0 // indirect - github.com/onflow/flow/protobuf/go/flow v0.3.7 // indirect + github.com/onflow/flow/protobuf/go/flow v0.4.0 // indirect + github.com/onflow/go-ethereum v1.13.4 // indirect github.com/onflow/nft-storefront/lib/go/contracts v0.0.0-20221222181731-14b90207cead // indirect github.com/onflow/sdks v0.5.0 // indirect github.com/onflow/wal v0.0.0-20240208022732-d756cd497d3b // indirect @@ -207,7 +216,6 @@ require ( github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect github.com/skeema/knownhosts v1.2.1 // indirect github.com/slok/go-http-metrics v0.10.0 // indirect - github.com/sony/gobreaker v0.5.0 // indirect github.com/sourcegraph/jsonrpc2 v0.1.0 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/spf13/cast v1.5.1 // indirect @@ -249,6 +257,7 @@ require ( golang.org/x/oauth2 v0.17.0 // indirect golang.org/x/sync v0.6.0 // indirect golang.org/x/sys v0.17.0 // indirect + golang.org/x/term v0.17.0 // indirect golang.org/x/text v0.14.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.17.0 // indirect diff --git a/go.sum b/go.sum index bc7fd3b42..ff0b4ddb1 100644 --- a/go.sum +++ b/go.sum @@ -136,6 +136,8 @@ github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.4 h1:rdovz3rEu github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.7.0 h1:HWsM0YQWX76V6MOp07YuTYacm8k7h69ObJuw7Nck+og= github.com/aws/aws-sdk-go-v2/service/s3 v1.15.0 h1:nPLfLPfglacc29Y949sDxpr3X/blaY40s3B85WT2yZU= github.com/aws/smithy-go v1.17.0 h1:wWJD7LX6PBV6etBUwO0zElG0nWN9rUhp0WdYeHSHAaI= +github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= +github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o= @@ -177,6 +179,8 @@ github.com/cespare/xxhash/v2 v2.0.1-0.20190104013014-3767db7a7e18/go.mod h1:HD5P github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/charmbracelet/bubbletea v0.25.0 h1:bAfwk7jRz7FKFl9RzlIULPkStffg5k6pNt5dywy4TcM= +github.com/charmbracelet/bubbletea v0.25.0/go.mod h1:EN3QDR1T5ZdWmdfDzYcqOCAps45+QIJbLOBxmVNWNNg= github.com/cheekybits/genny v1.0.0/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ= github.com/chzyer/logex v1.1.10 h1:Swpa1K6QvQznwJRcfTfQJmTE72DqScAa40E+fbHEXEE= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= @@ -216,6 +220,8 @@ github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH github.com/consensys/gnark-crypto v0.12.1 h1:lHH39WuuFgVHONRl3J0LRBtuYdQTumFSDtJF7HpyG8M= github.com/consensys/gnark-crypto v0.12.1/go.mod h1:v2Gy7L/4ZRosZ7Ivs+9SfUDr0f5UlG+EM5t7MPHiLuY= github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM= +github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 h1:q2hJAaP1k2wIvVRd/hEHD7lacgqrCPS+k8g1MndzfWY= +github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= @@ -301,8 +307,8 @@ github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHj github.com/ethereum/c-kzg-4844 v0.4.0 h1:3MS1s4JtA868KpJxroZoepdV0ZKBp3u/O5HcZ7R3nlY= github.com/ethereum/c-kzg-4844 v0.4.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= github.com/ethereum/go-ethereum v1.9.9/go.mod h1:a9TqabFudpDu1nucId+k9S8R9whYaHnGBLKFouA5EAo= -github.com/ethereum/go-ethereum v1.13.5 h1:U6TCRciCqZRe4FPXmy1sMGxTfuk8P7u2UoinF3VbaFk= -github.com/ethereum/go-ethereum v1.13.5/go.mod h1:yMTu38GSuyxaYzQMViqNmQ1s3cE84abZexQmTgenWk0= +github.com/ethereum/go-ethereum v1.13.10 h1:Ppdil79nN+Vc+mXfge0AuUgmKWuVv4eMqzoIVSdqZek= +github.com/ethereum/go-ethereum v1.13.10/go.mod h1:sc48XYQxCzH3fG9BcrXCOOgQk2JfZzNAmIKnceogzsA= github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= github.com/fatih/color v1.3.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= @@ -311,6 +317,7 @@ github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fjl/memsize v0.0.0-20180418122429-ca190fb6ffbc/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= +github.com/flynn/noise v1.0.1 h1:vPp/jdQLXC6ppsXSj/pM3W1BIJ5FEHE2TulSJBpb43Y= github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk= github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= @@ -597,11 +604,12 @@ github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUq github.com/hexops/valast v1.4.4 h1:rETyycw+/L2ZVJHHNxEBgh8KUn+87WugH9MxcEv9PGs= github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= -github.com/holiman/uint256 v1.2.3 h1:K8UWO1HUJpRMXBxbmaY1Y8IAMZC/RsKB+ArEnnK4l5o= -github.com/holiman/uint256 v1.2.3/go.mod h1:SC8Ryt4n+UBbPbIBKaG9zbbDlp4jOru9xFZmPzLUTxw= +github.com/holiman/uint256 v1.2.4 h1:jUc4Nk8fm9jZabQuqr2JzednajVmBpC+oiTiXZJEApU= +github.com/holiman/uint256 v1.2.4/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= github.com/huin/goupnp v0.0.0-20161224104101-679507af18f3/go.mod h1:MZ2ZmwcBpvOoJ22IJsc7va19ZwoheaBk43rKg12SKag= +github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= github.com/iancoleman/orderedmap v0.0.0-20190318233801-ac98e3ecb4b0 h1:i462o439ZjprVSFSZLZxcsoAe592sZB1rci2Z8j4wdk= github.com/iancoleman/orderedmap v0.0.0-20190318233801-ac98e3ecb4b0/go.mod h1:N0Wam8K1arqPXNWjMo21EXnBPOPp36vB07FNRdD2geA= @@ -646,12 +654,14 @@ github.com/ipfs/go-log/v2 v2.5.1 h1:1XdUzF7048prq4aBjDQQ4SL5RxftpRGdXhNRwKSAlcY= github.com/ipfs/go-log/v2 v2.5.1/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOLU9U5UI= github.com/ipfs/go-metrics-interface v0.0.1 h1:j+cpbjYvu4R8zbleSs36gvB7jR+wsL2fGD6n0jO4kdg= github.com/ipfs/go-metrics-interface v0.0.1/go.mod h1:6s6euYU4zowdslK0GKHmqaIZ3j/b/tL7HTWtJ4VPgWY= +github.com/ipld/go-ipld-prime v0.21.0 h1:n4JmcpOlPDIxBcY037SVfpd1G+Sj1nKZah0m6QH9C2E= github.com/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI= github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0= github.com/iris-contrib/jade v1.1.3/go.mod h1:H/geBymxJhShH5kecoiOCSssPX7QWYH7UaeZTSWddIk= github.com/iris-contrib/pongo2 v0.0.1/go.mod h1:Ssh+00+3GAZqSQb30AvBRNxBx7rf0GqwkjqxNd0u65g= github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw= github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= +github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= @@ -712,6 +722,7 @@ github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/4 github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/koron/go-ssdp v0.0.4 h1:1IDwrghSKYM7yLf7XCzbByg2sJ/JcNOZRXS2jczTwz0= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= @@ -731,6 +742,7 @@ github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7 github.com/leodido/go-urn v1.1.0/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdAPozLkw= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= +github.com/libp2p/go-addr-util v0.1.0 h1:acKsntI33w2bTU7tC9a0SaPimJGfSI0bFKC18ChxeVI= github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38yPW7c= @@ -738,12 +750,16 @@ github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFG github.com/libp2p/go-libp2p v0.32.2 h1:s8GYN4YJzgUoyeYNPdW7JZeZ5Ee31iNaIBfGYMAY4FQ= github.com/libp2p/go-libp2p v0.32.2/go.mod h1:E0LKe+diV/ZVJVnOJby8VC5xzHF0660osg71skcxJvk= github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94= +github.com/libp2p/go-libp2p-kad-dht v0.25.2 h1:FOIk9gHoe4YRWXTu8SY9Z1d0RILol0TrtApsMDPjAVQ= github.com/libp2p/go-libp2p-kbucket v0.6.3 h1:p507271wWzpy2f1XxPzCQG9NiN6R6lHL9GiSErbQQo0= github.com/libp2p/go-libp2p-pubsub v0.10.0 h1:wS0S5FlISavMaAbxyQn3dxMOe2eegMfswM471RuHJwA= github.com/libp2p/go-libp2p-pubsub v0.10.0/go.mod h1:1OxbaT/pFRO5h+Dpze8hdHQ63R0ke55XTs6b6NwLLkw= +github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= +github.com/libp2p/go-libp2p-routing-helpers v0.7.3 h1:u1LGzAMVRK9Nqq5aYDVOiq/HaB93U9WWczBzGyAC5ZY= github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA= github.com/libp2p/go-msgio v0.3.0 h1:mf3Z8B1xcFN314sWX+2vOTShIE0Mmn2TXn3YCUQGNj0= github.com/libp2p/go-msgio v0.3.0/go.mod h1:nyRM819GmVaF9LX3l03RMh10QdOroF++NBbxAb0mmDM= +github.com/libp2p/go-nat v0.2.0 h1:Tyz+bUFAYqGyJ/ppPPymMGbIgNRH+WqC5QrT5fKrrGk= github.com/libp2p/go-netroute v0.2.1 h1:V8kVrpD8GK0Riv15/7VN6RbUQ3URNZVosw7H2v9tksU= github.com/libp2p/go-reuseport v0.4.0 h1:nR5KU7hD0WxXCJbmw7r2rhRYruNRl2koHw8fQscQm2s= github.com/libp2p/go-yamux/v4 v4.0.1 h1:FfDR4S1wj6Bw2Pqbc8Uz7pCxeRBPbwsBbEdfwiCypkQ= @@ -756,6 +772,8 @@ github.com/logrusorgru/aurora v2.0.3+incompatible h1:tOpm7WcpBTn4fjmVfgpQq0EfczG github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= github.com/logrusorgru/aurora/v4 v4.0.0 h1:sRjfPpun/63iADiSvGGjgA1cAYegEWMPCJdUpJYn9JA= github.com/logrusorgru/aurora/v4 v4.0.0/go.mod h1:lP0iIa2nrnT/qoFXcOZSrZQpJ1o6n2CUf/hyHi2Q4ZQ= +github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= +github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= @@ -787,12 +805,15 @@ github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/ github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4= +github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.6/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= @@ -839,6 +860,14 @@ github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVq github.com/mr-tron/base58 v1.1.3/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= +github.com/muesli/ansi v0.0.0-20211018074035-2e021307bc4b h1:1XF24mVaiu7u+CFywTdcDo2ie1pzzhwjt6RHqzpMU34= +github.com/muesli/ansi v0.0.0-20211018074035-2e021307bc4b/go.mod h1:fQuZ0gauxyBcmsdE3ZT4NasjaRdxmbCS0jRHsrWu3Ho= +github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA= +github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo= +github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s= +github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8= +github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo= +github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8= github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= github.com/multiformats/go-base32 v0.1.0 h1:pVx9xoSPqEIQG8o+UbAe7DNi51oej1NtK+aGkbLYxPE= github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYgtWibDcT0rExnbI= @@ -889,43 +918,43 @@ github.com/onflow/atree v0.1.0-beta1.0.20211027184039-559ee654ece9/go.mod h1:+6x github.com/onflow/atree v0.6.0 h1:j7nQ2r8npznx4NX39zPpBYHmdy45f4xwoi+dm37Jk7c= github.com/onflow/atree v0.6.0/go.mod h1:gBHU0M05qCbv9NN0kijLWMgC47gHVNBIp4KmsVFi0tc= github.com/onflow/cadence v0.20.1/go.mod h1:7mzUvPZUIJztIbr9eTvs+fQjWWHTF8veC+yk4ihcNIA= -github.com/onflow/cadence v0.42.9 h1:EX+eak/Jjy9PyKcAEmOViGOHMyP/nCOwJO+deodZlJE= -github.com/onflow/cadence v0.42.9/go.mod h1:1wFd+LiNiN6qoZXof3MBdpM6d8BsxbVIxOA77LbIYmE= -github.com/onflow/cadence-tools/languageserver v0.33.3 h1:o6f2kPxsgSruH+HT8CakcZlm43QX5WtIuW6XVh/R5DM= -github.com/onflow/cadence-tools/languageserver v0.33.3/go.mod h1:rUy3zxWWZl+KYAyzhAcnrYNI8ZDKI242RFK8Q9w+90M= -github.com/onflow/cadence-tools/lint v0.14.1 h1:Qkw8+q+ALfB62W7KWHMFh+90gTfJ+NoFulYETMCTkcI= -github.com/onflow/cadence-tools/lint v0.14.1/go.mod h1:w1xfiiPpZ35v/F+2+MF/Rily7LcIgE0dm/FMW1vQkpc= -github.com/onflow/cadence-tools/test v0.14.6 h1:UQ9oUndf1uDlwGUhA4ks0AHM6fRLqs153JO36eVFnFY= -github.com/onflow/cadence-tools/test v0.14.6/go.mod h1:ix09Bb3GQ/fZMNpSR8E+vSFItGF54fzP9gFxU7AsOIw= -github.com/onflow/crypto v0.25.0 h1:BeWbLsh3ZD13Ej+Uky6kg1PL1ZIVBDVX+2MVBNwqddg= -github.com/onflow/crypto v0.25.0/go.mod h1:C8FbaX0x8y+FxWjbkHy0Q4EASCDR9bSPWZqlpCLYyVI= +github.com/onflow/cadence v0.42.10 h1:3oC5ceeXhdCrhHcf9H0yYXQKW3Tw/vkSXLe+PUZa4i0= +github.com/onflow/cadence v0.42.10/go.mod h1:1wFd+LiNiN6qoZXof3MBdpM6d8BsxbVIxOA77LbIYmE= +github.com/onflow/cadence-tools/languageserver v0.33.5 h1:Tg2YniU+ZJPI9RlTOuguqkLriUaFXue6FNXM+Ewijgo= +github.com/onflow/cadence-tools/languageserver v0.33.5/go.mod h1:euGucPAVixPrlTyYGnsZTHg65u7C6zdmfRJlVwRgMaI= +github.com/onflow/cadence-tools/lint v0.14.2 h1:WGh6ARN9MRVeYID3OnlalPtDTeYkliteHHR+ITCh/J4= +github.com/onflow/cadence-tools/lint v0.14.2/go.mod h1:PlYwSF4wwpCtQJKs1cQAb80AG90a4rhADTitCogQ4UE= +github.com/onflow/cadence-tools/test v0.14.7 h1:o4tHQLvxLGlG6mFyDl2vFYFtoTLCFJVxuJQ16ab+3u4= +github.com/onflow/cadence-tools/test v0.14.7/go.mod h1:CBq9lk7Dpqz8kPkUYLOD3AgrjzBjKCZhLgDjvJYokQs= +github.com/onflow/crypto v0.25.1 h1:0txy2PKPMM873JbpxQNbJmuOJtD56bfs48RQfm0ts5A= +github.com/onflow/crypto v0.25.1/go.mod h1:C8FbaX0x8y+FxWjbkHy0Q4EASCDR9bSPWZqlpCLYyVI= github.com/onflow/fcl-dev-wallet v0.7.4 h1:vI6t3U0AO88R/Iitn5KsnniSpbN9Lqsqwvi9EJT4C0k= github.com/onflow/fcl-dev-wallet v0.7.4/go.mod h1:kc42jkiuoPJmxMRFjfbRO9XvnR/3XLheaOerxVMDTiw= -github.com/onflow/flixkit-go v1.1.2 h1:pn8CtUr1qpHrZF+xbl6FXU+nVGtUgFKYm3XGaX0yKj8= -github.com/onflow/flixkit-go v1.1.2/go.mod h1:XkbRPv6drM8uQpvdKgZ5stShtOlOMiQ6Fy86D0EsW5U= -github.com/onflow/flow-cli/flowkit v1.11.0 h1:RSfKlla/l+ZJwqAmlvA5HPFbQ6ia2wzKSG0kJ8fqVa0= -github.com/onflow/flow-cli/flowkit v1.11.0/go.mod h1:aH4shan7Ggxd0GIXZD2S4kYMemNfzP1rLWvzKnb6K3g= +github.com/onflow/flixkit-go v1.1.3 h1:td94mkklIwXvDP075D0eofPE04oKse24PxvFTyOvMJI= +github.com/onflow/flixkit-go v1.1.3/go.mod h1:qOYI1l7r3gSPk6luTnk95ni020UeTY+E48GuB3Tl0xk= github.com/onflow/flow-core-contracts/lib/go/contracts v1.2.4-0.20231016154253-a00dbf7c061f h1:S8yIZw9LFXfYD1V5H9BiixihHw3GrXVPrmfplSzYaww= github.com/onflow/flow-core-contracts/lib/go/contracts v1.2.4-0.20231016154253-a00dbf7c061f/go.mod h1:jM6GMAL+m0hjusUgiYDNrixPQ6b9s8xjoJQoEu5bHQI= github.com/onflow/flow-core-contracts/lib/go/templates v1.2.4-0.20231016154253-a00dbf7c061f h1:Ep+Mpo2miWMe4pjPGIaEvEzshRep30dvNgxqk+//FrQ= github.com/onflow/flow-core-contracts/lib/go/templates v1.2.4-0.20231016154253-a00dbf7c061f/go.mod h1:ZeLxwaBkzuSInESGjL8/IPZWezF+YOYsYbMrZlhN+q4= -github.com/onflow/flow-emulator v0.61.1 h1:7uCzphiAMjZbehsCSTQ8mQWUpMeKqjxCd45yYRvMEQk= -github.com/onflow/flow-emulator v0.61.1/go.mod h1:YLR3/wi4Z9j7s9tJyIvTmxH3wAsO7zkFHSRrW0axyuE= +github.com/onflow/flow-emulator v0.62.1 h1:VivECYftZbaIo9oZBVsmeE/LUcxdx7hJJ1ET2rGY8p8= +github.com/onflow/flow-emulator v0.62.1/go.mod h1:JbvxBZ39Q8hOQ5fSwuV0ZJwfaiQeaYTiIY04ws8LcNE= github.com/onflow/flow-ft/lib/go/contracts v0.7.1-0.20230711213910-baad011d2b13 h1:B4ll7e3j+MqTJv2122Enq3RtDNzmIGRu9xjV7fo7un0= github.com/onflow/flow-ft/lib/go/contracts v0.7.1-0.20230711213910-baad011d2b13/go.mod h1:kTMFIySzEJJeupk+7EmXs0EJ6CBWY/MV9fv9iYQk+RU= -github.com/onflow/flow-go v0.33.2-0.20240306234901-64ab8d27ea30 h1:1JkIA71XEspysh2EsAGeOi1gNc2/TgZJ9kGyyPWJWDU= -github.com/onflow/flow-go v0.33.2-0.20240306234901-64ab8d27ea30/go.mod h1:I5sWWA5pHsJDlZV61iqqQ3k++IhB/k1qE/80s2sjP5s= +github.com/onflow/flow-go v0.33.2-0.20240412174857-015156b297b5 h1:2785d9unR8CpzJzRQcMz+yjKKRmqN+Kbvu0gKdy6iT4= +github.com/onflow/flow-go v0.33.2-0.20240412174857-015156b297b5/go.mod h1:FkonSWZ60bOtc5MdH+CRHScza34k+uNpa6GwXnRpUvg= github.com/onflow/flow-go-sdk v0.24.0/go.mod h1:IoptMLPyFXWvyd9yYA6/4EmSeeozl6nJoIv4FaEMg74= -github.com/onflow/flow-go-sdk v0.46.0 h1:mrIQziCDe6Oi5HH/aPFvYluh1XUwO6lYpoXLWrBZc2s= -github.com/onflow/flow-go-sdk v0.46.0/go.mod h1:azVWF0yHI8wT1erF0vuYGqQZybl6Frbc+0Zu3rIPeHc= +github.com/onflow/flow-go-sdk v0.46.2 h1:ypVGBeH9m5XpBOTU/CYVC0y/+z42e8mhUlq5aLiD24A= +github.com/onflow/flow-go-sdk v0.46.2/go.mod h1:tfLjB9FZmwqtT5gaacjvpIhz7KCd67YPm6v+iqYAjEA= github.com/onflow/flow-go/crypto v0.21.3/go.mod h1:vI6V4CY3R6c4JKBxdcRiR/AnjBfL8OSD97bJc60cLuQ= github.com/onflow/flow-nft/lib/go/contracts v1.1.0 h1:rhUDeD27jhLwOqQKI/23008CYfnqXErrJvc4EFRP2a0= github.com/onflow/flow-nft/lib/go/contracts v1.1.0/go.mod h1:YsvzYng4htDgRB9sa9jxdwoTuuhjK8WYWXTyLkIigZY= github.com/onflow/flow/protobuf/go/flow v0.2.2/go.mod h1:gQxYqCfkI8lpnKsmIjwtN2mV/N2PIwc1I+RUK4HPIc8= -github.com/onflow/flow/protobuf/go/flow v0.3.7 h1:+6sBdlE/u4ZMTVB9U1lA6Xn2Bd48lOOX96Bv9dNubsk= -github.com/onflow/flow/protobuf/go/flow v0.3.7/go.mod h1:NA2pX2nw8zuaxfKphhKsk00kWLwfd+tv8mS23YXO4Sk= -github.com/onflow/flowkit v1.17.1 h1:h8ok2cYsuKwu4BGAWOdMh6UancKyyYxsX6Kv0KCQIhQ= -github.com/onflow/flowkit v1.17.1/go.mod h1:zu2r0bM5eebHBD3e3Bmp0IbAPcOvGxL17Nm3X0YpM2Q= +github.com/onflow/flow/protobuf/go/flow v0.4.0 h1:5TGmPwRmnSt7aawgtPGF9ehoGHHir9Cy9LVoAiU9t/E= +github.com/onflow/flow/protobuf/go/flow v0.4.0/go.mod h1:NA2pX2nw8zuaxfKphhKsk00kWLwfd+tv8mS23YXO4Sk= +github.com/onflow/flowkit v1.17.3 h1:0Fi3tLnieWOYq95A3ySk3TZ0GUPtKaX8ofssgve9e58= +github.com/onflow/flowkit v1.17.3/go.mod h1:laapt1diM4Pbqt0dotKMH+LbUAOEqgugpH1p4+sPhcw= +github.com/onflow/go-ethereum v1.13.4 h1:iNO86fm8RbBbhZ87ZulblInqCdHnAQVY8okBrNsTevc= +github.com/onflow/go-ethereum v1.13.4/go.mod h1:cE/gEUkAffhwbVmMJYz+t1dAfVNHNwZCgc3BWtZxBGY= github.com/onflow/nft-storefront/lib/go/contracts v0.0.0-20221222181731-14b90207cead h1:2j1Unqs76Z1b95Gu4C3Y28hzNUHBix7wL490e61SMSw= github.com/onflow/nft-storefront/lib/go/contracts v0.0.0-20221222181731-14b90207cead/go.mod h1:E3ScfQb5XcWJCIAdtIeEnr5i5l2y60GT0BTXeIHseWg= github.com/onflow/sdks v0.5.0 h1:2HCRibwqDaQ1c9oUApnkZtEAhWiNY2GTpRD5+ftdkN8= @@ -991,6 +1020,7 @@ github.com/pkg/term v1.2.0-beta.2/go.mod h1:E25nymQcrSllhX42Ok8MRm1+hyBdHY0dCeiK github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/polydawn/refmt v0.89.0 h1:ADJTApkvkeBZsN0tBTx8QjpD9JkmxbKp0cxfr9qszm4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= @@ -1032,8 +1062,10 @@ github.com/psiemens/graceland v1.0.0 h1:L580AVV4Q2XLcPpmvxJRH9UpEAYr/eu2jBKmMglh github.com/psiemens/graceland v1.0.0/go.mod h1:1Tof+vt1LbmcZFE0lzgdwMN0QBymAChG3FRgDx8XisU= github.com/psiemens/sconfig v0.1.0 h1:xfWqW+TRpih7mXZIqKYTmpRhlZLQ1kbxV8EjllPv76s= github.com/psiemens/sconfig v0.1.0/go.mod h1:+MLKqdledP/8G3rOBpknbLh0IclCf4WneJUtS26JB2U= +github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qtls-go1-20 v0.4.1 h1:D33340mCNDAIKBqXuAvexTNMUByrYmFYVfKfDN5nfFs= github.com/quic-go/quic-go v0.40.1 h1:X3AGzUNFs0jVuO3esAGnTfvdgvL4fq655WaOi1snv1Q= +github.com/quic-go/webtransport-go v0.6.0 h1:CvNsKqc4W2HljHJnoT+rMmbRJybShZ0YPFDD3NxaZLY= github.com/radovskyb/watcher v1.0.7 h1:AYePLih6dpmS32vlHfhCeli8127LzkIgwJGcwwe8tUE= github.com/radovskyb/watcher v1.0.7/go.mod h1:78okwvY5wPdzcb1UYnip1pvrZNIVEIh/Cm+ZuvsUYIg= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= @@ -1041,6 +1073,7 @@ github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqn github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= +github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= @@ -1095,8 +1128,6 @@ github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1 github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= -github.com/sony/gobreaker v0.5.0 h1:dRCvqm0P490vZPmy7ppEk2qCnCieBooFJ+YoXGYB+yg= -github.com/sony/gobreaker v0.5.0/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= github.com/sourcegraph/jsonrpc2 v0.1.0 h1:ohJHjZ+PcaLxDUjqk2NC3tIGsVa5bXThe1ZheSXOjuk= github.com/sourcegraph/jsonrpc2 v0.1.0/go.mod h1:ZafdZgk/axhT1cvZAPOhw+95nz2I/Ra5qMlU4gTRwIo= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= @@ -1195,6 +1226,7 @@ github.com/vmihailenco/msgpack/v4 v4.3.11 h1:Q47CePddpNGNhk4GCnAx9DDtASi2rasatE0 github.com/vmihailenco/msgpack/v4 v4.3.11/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4= github.com/vmihailenco/tagparser v0.1.1 h1:quXMXlA39OCbd2wAdTsGDlK9RkOk6Wuw+x37wVyIuWY= github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= +github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 h1:EKhdznlJHPMoKr0XTrX+IlJs1LH3lyx2nfr1dOlZ79k= github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208/go.mod h1:IotVbo4F+mw0EzQ08zFqg7pK3FebNXpaMsRy2RT+Ees= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= @@ -1263,6 +1295,8 @@ go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= +go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= +go.uber.org/fx v1.20.1 h1:zVwVQGS8zYvhh9Xxcu4w1M6ESyeMzebzj2NbSayZ4Mk= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= @@ -1553,6 +1587,7 @@ golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/term v0.17.0 h1:mkTF7LCd6WGJNL3K1Ad7kwxNfYAW6a8a8QqtMblp/4U= +golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/internal/dependencymanager/add.go b/internal/dependencymanager/add.go index 40252f0d7..1542628f1 100644 --- a/internal/dependencymanager/add.go +++ b/internal/dependencymanager/add.go @@ -30,7 +30,7 @@ import ( ) type addFlagsCollection struct { - dependencyManagerFlagsCollection + DependencyManagerFlagsCollection name string `default:"" flag:"name" info:"Name of the dependency"` } @@ -58,13 +58,13 @@ func add( dep := args[0] - installer, err := NewDependencyInstaller(logger, state, addFlags.dependencyManagerFlagsCollection) + installer, err := NewDependencyInstaller(logger, state, true, "", addFlags.DependencyManagerFlagsCollection) if err != nil { logger.Error(fmt.Sprintf("Error: %v", err)) return nil, err } - if err := installer.Add(dep, addFlags.name); err != nil { + if err := installer.AddBySourceString(dep, addFlags.name); err != nil { logger.Error(fmt.Sprintf("Error: %v", err)) return nil, err } diff --git a/internal/dependencymanager/dependencyinstaller.go b/internal/dependencymanager/dependencyinstaller.go index 610709afd..14fdb9470 100644 --- a/internal/dependencymanager/dependencyinstaller.go +++ b/internal/dependencymanager/dependencyinstaller.go @@ -69,7 +69,7 @@ func (cl *categorizedLogs) LogAll(logger output.Logger) { } } -type dependencyManagerFlagsCollection struct { +type DependencyManagerFlagsCollection struct { skipDeployments bool `default:"false" flag:"skip-deployments" info:"Skip adding the dependency to deployments"` skipAlias bool `default:"false" flag:"skip-alias" info:"Skip prompting for an alias"` } @@ -78,13 +78,15 @@ type DependencyInstaller struct { Gateways map[string]gateway.Gateway Logger output.Logger State *flowkit.State + SaveState bool + TargetDir string SkipDeployments bool SkipAlias bool logs categorizedLogs } // NewDependencyInstaller creates a new instance of DependencyInstaller -func NewDependencyInstaller(logger output.Logger, state *flowkit.State, flags dependencyManagerFlagsCollection) (*DependencyInstaller, error) { +func NewDependencyInstaller(logger output.Logger, state *flowkit.State, saveState bool, targetDir string, flags DependencyManagerFlagsCollection) (*DependencyInstaller, error) { emulatorGateway, err := gateway.NewGrpcGateway(config.EmulatorNetwork) if err != nil { return nil, fmt.Errorf("error creating emulator gateway: %v", err) @@ -110,11 +112,24 @@ func NewDependencyInstaller(logger output.Logger, state *flowkit.State, flags de Gateways: gateways, Logger: logger, State: state, + SaveState: saveState, + TargetDir: targetDir, SkipDeployments: flags.skipDeployments, SkipAlias: flags.skipAlias, }, nil } +// saveState checks the SaveState flag and saves the state if set to true. +func (di *DependencyInstaller) saveState() error { + if di.SaveState { + statePath := filepath.Join(di.TargetDir, "flow.json") + if err := di.State.Save(statePath); err != nil { + return fmt.Errorf("error saving state: %w", err) + } + } + return nil +} + // Install processes all the dependencies in the state and installs them and any dependencies they have func (di *DependencyInstaller) Install() error { for _, dependency := range *di.State.Dependencies() { @@ -124,9 +139,8 @@ func (di *DependencyInstaller) Install() error { } } - err := di.State.SaveDefault() - if err != nil { - return fmt.Errorf("error saving state: %w", err) + if err := di.saveState(); err != nil { + return err } di.logs.LogAll(di.Logger) @@ -134,8 +148,8 @@ func (di *DependencyInstaller) Install() error { return nil } -// Add processes a single dependency and installs it and any dependencies it has, as well as adding it to the state -func (di *DependencyInstaller) Add(depSource, customName string) error { +// AddBySourceString processes a single dependency and installs it and any dependencies it has, as well as adding it to the state +func (di *DependencyInstaller) AddBySourceString(depSource, customName string) error { depNetwork, depAddress, depContractName, err := config.ParseSourceString(depSource) if err != nil { return fmt.Errorf("error parsing source: %w", err) @@ -160,9 +174,40 @@ func (di *DependencyInstaller) Add(depSource, customName string) error { return fmt.Errorf("error processing dependency: %w", err) } - err = di.State.SaveDefault() - if err != nil { - return fmt.Errorf("error saving state: %w", err) + if err := di.saveState(); err != nil { + return err + } + + di.logs.LogAll(di.Logger) + + return nil +} + +// Add processes a single dependency and installs it and any dependencies it has, as well as adding it to the state +func (di *DependencyInstaller) Add(dep config.Dependency) error { + if err := di.processDependency(dep); err != nil { + return fmt.Errorf("error processing dependency: %w", err) + } + + if err := di.saveState(); err != nil { + return err + } + + di.logs.LogAll(di.Logger) + + return nil +} + +// AddMany processes multiple dependencies and installs them as well as adding them to the state +func (di *DependencyInstaller) AddMany(dependencies []config.Dependency) error { + for _, dep := range dependencies { + if err := di.processDependency(dep); err != nil { + return fmt.Errorf("error processing dependency: %w", err) + } + } + + if err := di.saveState(); err != nil { + return err } di.logs.LogAll(di.Logger) @@ -241,7 +286,7 @@ func (di *DependencyInstaller) contractFileExists(address, contractName string) func (di *DependencyInstaller) createContractFile(address, contractName, data string) error { fileName := fmt.Sprintf("%s.cdc", contractName) - path := filepath.Join("imports", address, fileName) + path := filepath.Join(di.TargetDir, "imports", address, fileName) dir := filepath.Dir(path) if err := di.State.ReaderWriter().MkdirAll(dir, 0755); err != nil { diff --git a/internal/dependencymanager/dependencyinstaller_test.go b/internal/dependencymanager/dependencyinstaller_test.go index 92d64427e..dd1941bba 100644 --- a/internal/dependencymanager/dependencyinstaller_test.go +++ b/internal/dependencymanager/dependencyinstaller_test.go @@ -76,6 +76,8 @@ func TestDependencyInstallerInstall(t *testing.T) { }, Logger: logger, State: state, + SaveState: true, + TargetDir: "", SkipDeployments: true, SkipAlias: true, } @@ -120,12 +122,14 @@ func TestDependencyInstallerAdd(t *testing.T) { }, Logger: logger, State: state, + SaveState: true, + TargetDir: "", SkipDeployments: true, SkipAlias: true, } sourceStr := fmt.Sprintf("emulator://%s.%s", serviceAddress.String(), tests.ContractHelloString.Name) - err := di.Add(sourceStr, "") + err := di.AddBySourceString(sourceStr, "") assert.NoError(t, err, "Failed to install dependencies") filePath := fmt.Sprintf("imports/%s/%s.cdc", serviceAddress.String(), tests.ContractHelloString.Name) @@ -133,4 +137,113 @@ func TestDependencyInstallerAdd(t *testing.T) { assert.NoError(t, err, "Failed to read generated file") assert.NotNil(t, fileContent) }) + + t.Run("Success", func(t *testing.T) { + gw := mocks.DefaultMockGateway() + + gw.GetAccount.Run(func(args mock.Arguments) { + addr := args.Get(1).(flow.Address) + assert.Equal(t, addr.String(), serviceAcc.Address.String()) + acc := tests.NewAccountWithAddress(addr.String()) + acc.Contracts = map[string][]byte{ + tests.ContractHelloString.Name: tests.ContractHelloString.Source, + } + + gw.GetAccount.Return(acc, nil) + }) + + di := &DependencyInstaller{ + Gateways: map[string]gateway.Gateway{ + config.EmulatorNetwork.Name: gw.Mock, + config.TestnetNetwork.Name: gw.Mock, + config.MainnetNetwork.Name: gw.Mock, + }, + Logger: logger, + State: state, + SaveState: true, + TargetDir: "", + SkipDeployments: true, + SkipAlias: true, + } + + dep := config.Dependency{ + Name: tests.ContractHelloString.Name, + Source: config.Source{ + NetworkName: "emulator", + Address: flow.HexToAddress(serviceAddress.String()), + ContractName: tests.ContractHelloString.Name, + }, + } + err := di.Add(dep) + assert.NoError(t, err, "Failed to install dependencies") + + filePath := fmt.Sprintf("imports/%s/%s.cdc", serviceAddress.String(), tests.ContractHelloString.Name) + fileContent, err := state.ReaderWriter().ReadFile(filePath) + assert.NoError(t, err, "Failed to read generated file") + assert.NotNil(t, fileContent) + }) +} + +func TestDependencyInstallerAddMany(t *testing.T) { + logger := output.NewStdoutLogger(output.NoneLog) + _, state, _ := util.TestMocks(t) + + serviceAcc, _ := state.EmulatorServiceAccount() + serviceAddress := serviceAcc.Address.String() + + dependencies := []config.Dependency{ + { + Name: "ContractOne", + Source: config.Source{ + NetworkName: "emulator", + Address: flow.HexToAddress(serviceAddress), + ContractName: "ContractOne", + }, + }, + { + Name: "ContractTwo", + Source: config.Source{ + NetworkName: "emulator", + Address: flow.HexToAddress(serviceAddress), + ContractName: "ContractTwo", + }, + }, + } + + t.Run("AddMultipleDependencies", func(t *testing.T) { + gw := mocks.DefaultMockGateway() + gw.GetAccount.Run(func(args mock.Arguments) { + addr := args.Get(1).(flow.Address) + assert.Equal(t, addr.String(), serviceAddress) + acc := tests.NewAccountWithAddress(addr.String()) + acc.Contracts = map[string][]byte{ + "ContractOne": []byte("pub contract ContractOne {}"), + "ContractTwo": []byte("pub contract ContractTwo {}"), + } + gw.GetAccount.Return(acc, nil) + }) + + di := &DependencyInstaller{ + Gateways: map[string]gateway.Gateway{ + config.EmulatorNetwork.Name: gw.Mock, + config.TestnetNetwork.Name: gw.Mock, + config.MainnetNetwork.Name: gw.Mock, + }, + Logger: logger, + State: state, + SaveState: true, + TargetDir: "", + SkipDeployments: true, + SkipAlias: true, + } + + err := di.AddMany(dependencies) + assert.NoError(t, err, "Failed to add multiple dependencies") + + for _, dep := range dependencies { + filePath := fmt.Sprintf("imports/%s/%s.cdc", dep.Source.Address.String(), dep.Name) + _, err := state.ReaderWriter().ReadFile(filePath) + assert.NoError(t, err, fmt.Sprintf("Failed to read generated file for %s", dep.Name)) + } + }) } diff --git a/internal/dependencymanager/install.go b/internal/dependencymanager/install.go index 25bbb1ba1..4f1a72500 100644 --- a/internal/dependencymanager/install.go +++ b/internal/dependencymanager/install.go @@ -29,7 +29,7 @@ import ( "github.com/onflow/flow-cli/internal/command" ) -var installFlags = dependencyManagerFlagsCollection{} +var installFlags = DependencyManagerFlagsCollection{} var installCommand = &command.Command{ Cmd: &cobra.Command{ @@ -50,7 +50,7 @@ func install( ) (result command.Result, err error) { logger.Info("🔄 Installing dependencies from flow.json...") - installer, err := NewDependencyInstaller(logger, state, installFlags) + installer, err := NewDependencyInstaller(logger, state, true, "", installFlags) if err != nil { logger.Error(fmt.Sprintf("Error: %v", err)) return nil, err diff --git a/internal/super/setup.go b/internal/super/setup.go index f5016c26f..6887cc70e 100644 --- a/internal/super/setup.go +++ b/internal/super/setup.go @@ -25,14 +25,22 @@ import ( "os" "path/filepath" - "github.com/spf13/cobra" + tea "github.com/charmbracelet/bubbletea" + flowsdk "github.com/onflow/flow-go-sdk" + "github.com/onflow/flow-go/fvm/systemcontracts" + flowGo "github.com/onflow/flow-go/model/flow" + flowkitConfig "github.com/onflow/flowkit/config" - "github.com/onflow/flow-cli/internal/config" + "github.com/onflow/flow-cli/internal/dependencymanager" "github.com/onflow/flow-cli/internal/util" + "github.com/spf13/cobra" + "github.com/onflow/flowkit" "github.com/onflow/flowkit/output" + "github.com/onflow/flow-cli/internal/config" + "github.com/onflow/flow-cli/internal/command" ) @@ -108,7 +116,7 @@ func create( Global: false, TargetDirectory: targetDir, } - _, err := config.InitializeConfiguration(params, logger, state.ReaderWriter()) + state, err := config.InitializeConfiguration(params, logger, state.ReaderWriter()) if err != nil { return nil, fmt.Errorf("failed to initialize configuration: %w", err) } @@ -136,6 +144,59 @@ func create( return nil, err } + // Prompt to ask which core contracts should be installed + sc := systemcontracts.SystemContractsForChain(flowGo.Mainnet) + promptMessage := "Select the core contracts you'd like to install" + + contractNames := make([]string, 0) + + for _, contract := range sc.All() { + contractNames = append(contractNames, contract.Name) + } + + m := util.GenericOptionSelect(contractNames, promptMessage) + finalModel, err := tea.NewProgram(m).Run() + + if err != nil { + fmt.Printf("Error running program: %v\n", err) + os.Exit(1) + } + + final := finalModel.(util.OptionSelectModel) + + var dependencies []flowkitConfig.Dependency + + // Loop standard contracts and add them to the dependencies if selected + for i, contract := range sc.All() { + if _, ok := final.Selected[i]; ok { + dependencies = append(dependencies, flowkitConfig.Dependency{ + Name: contract.Name, + Source: flowkitConfig.Source{ + NetworkName: flowkitConfig.MainnetNetwork.Name, + Address: flowsdk.HexToAddress(contract.Address.String()), + ContractName: contract.Name, + }, + }) + } + } + + // Add the selected core contracts as dependencies + installer, err := dependencymanager.NewDependencyInstaller(logger, state, false, targetDir, dependencymanager.DependencyManagerFlagsCollection{}) + if err != nil { + logger.Error(fmt.Sprintf("Error: %v", err)) + return nil, err + } + + if err := installer.AddMany(dependencies); err != nil { + logger.Error(fmt.Sprintf("Error: %v", err)) + return nil, err + } + + err = state.Save(filepath.Join(targetDir, "flow.json")) + if err != nil { + return nil, err + } + } return &setupResult{targetDir: targetDir}, nil diff --git a/internal/super/setup_test.go b/internal/super/setup_test.go deleted file mode 100644 index 18da37df3..000000000 --- a/internal/super/setup_test.go +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Flow CLI - * - * Copyright 2019 Dapper Labs, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package super - -import ( - "fmt" - "os" - "path/filepath" - "testing" - - "github.com/onflow/flowkit/output" - "github.com/stretchr/testify/assert" - - "github.com/onflow/flow-cli/internal/command" - "github.com/onflow/flow-cli/internal/util" -) - -func TestCreate(t *testing.T) { - logger := output.NewStdoutLogger(output.NoneLog) - _, state, _ := util.TestMocks(t) - - projectName := "foobar" - - // Test project creation - _, err := create([]string{projectName}, command.GlobalFlags{}, logger, nil, state) - assert.NoError(t, err, "Failed to create project") - - // Check project was created in target directory which is in pwd - pwd, err := os.Getwd() - assert.NoError(t, err, "Failed to get working directory") - - target := filepath.Join(pwd, fmt.Sprintf("%s/flow.json", projectName)) - - _, err = state.ReaderWriter().ReadFile(target) - assert.NoError(t, err, "Failed to read generated file") -} diff --git a/internal/util/prompt.go b/internal/util/prompt.go index 7b5b912cf..96ea1f753 100644 --- a/internal/util/prompt.go +++ b/internal/util/prompt.go @@ -25,6 +25,8 @@ import ( "strconv" "strings" + tea "github.com/charmbracelet/bubbletea" + "github.com/onflow/flowkit/accounts" "github.com/gosuri/uilive" @@ -793,3 +795,88 @@ func GenericBoolPrompt(msg string) bool { return result == "Yes" } + +func GenericSelect(items []string, message string) string { + prompt := promptui.Select{ + Label: message, + Items: items, + } + _, result, _ := prompt.Run() + + return result +} + +// OptionSelectModel represents the prompt state +type OptionSelectModel struct { + message string // message to display + cursor int // position of the cursor + Choices []string // items on the list + Selected map[int]struct{} // which items are selected +} + +// GenericOptionSelect creates a prompt for selecting multiple options +func GenericOptionSelect(options []string, message string) OptionSelectModel { + return OptionSelectModel{ + message: message, + Choices: options, + Selected: make(map[int]struct{}), + } +} + +func (m OptionSelectModel) Init() tea.Cmd { + return nil // No initial command +} + +func (m OptionSelectModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { + switch msg := msg.(type) { + case tea.KeyMsg: + switch msg.Type { + case tea.KeyCtrlC, tea.KeyEsc: // Quit the program + return m, tea.Quit + + case tea.KeyUp: // Navigate up + if m.cursor > 0 { + m.cursor-- + } + + case tea.KeyDown: // Navigate down + if m.cursor < len(m.Choices)-1 { + m.cursor++ + } + + case tea.KeySpace: // Select an item + // Toggle selection + if _, ok := m.Selected[m.cursor]; ok { + delete(m.Selected, m.cursor) // Deselect + } else { + m.Selected[m.cursor] = struct{}{} // Select + } + + case tea.KeyEnter: // Confirm selection + return m, tea.Quit // Quit and process selections in main + } + } + + return m, nil +} + +func (m OptionSelectModel) View() string { + var b strings.Builder + b.WriteString(fmt.Sprintf("%s.\n", m.message)) + b.WriteString("Use arrow keys to navigate, space to select, enter to confirm, q to quit:\n\n") + for i, choice := range m.Choices { + if m.cursor == i { + b.WriteString("> ") + } else { + b.WriteString(" ") + } + // Mark selected items + if _, ok := m.Selected[i]; ok { + b.WriteString("[x] ") + } else { + b.WriteString("[ ] ") + } + b.WriteString(choice + "\n") + } + return b.String() +} From c7e776732fddc51ce557ed828bfcc188cadec3e3 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Tue, 16 Apr 2024 14:35:04 -0700 Subject: [PATCH 16/86] Move to prompt pkg --- internal/accounts/contract-add.go | 5 ++--- internal/accounts/contract-remove.go | 5 ++--- internal/accounts/create-interactive.go | 5 +++-- internal/command/command.go | 3 ++- internal/config/add-account.go | 8 ++++---- internal/config/add-contract.go | 8 ++++---- internal/config/add-deployment.go | 8 ++++---- internal/config/add-network.go | 3 ++- internal/config/remove-account.go | 4 ++-- internal/config/remove-contract.go | 4 ++-- internal/config/remove-deployment.go | 4 ++-- internal/config/remove-network.go | 4 ++-- .../dependencymanager/dependencyinstaller.go | 9 ++++----- internal/project/deploy.go | 6 +++--- internal/{util => prompt}/prompt.go | 16 ++++++++++++++-- internal/super/scaffolds.go | 9 ++++----- internal/super/setup.go | 9 ++++----- internal/tools/flowser.go | 12 ++++++------ internal/transactions/build.go | 4 ++-- internal/transactions/send-signed.go | 4 ++-- internal/transactions/sign.go | 4 ++-- internal/util/util.go | 11 ----------- 22 files changed, 72 insertions(+), 73 deletions(-) rename internal/{util => prompt}/prompt.go (98%) diff --git a/internal/accounts/contract-add.go b/internal/accounts/contract-add.go index 29061d525..bcf7f21b5 100644 --- a/internal/accounts/contract-add.go +++ b/internal/accounts/contract-add.go @@ -21,8 +21,7 @@ package accounts import ( "context" "fmt" - - "github.com/onflow/flow-cli/internal/util" + "github.com/onflow/flow-cli/internal/prompt" "github.com/onflow/cadence" flowsdk "github.com/onflow/flow-go-sdk" @@ -88,7 +87,7 @@ func deployContract(update bool, flags *deployContractFlags) command.RunWithStat deployFunc := flowkit.UpdateExistingContract(update) if updateContractFlags.ShowDiff { - deployFunc = util.ShowContractDiffPrompt(logger) + deployFunc = prompt.ShowContractDiffPrompt(logger) } txID, _, err := flow.AddContract( diff --git a/internal/accounts/contract-remove.go b/internal/accounts/contract-remove.go index d4ba049b4..0e7beb128 100644 --- a/internal/accounts/contract-remove.go +++ b/internal/accounts/contract-remove.go @@ -21,11 +21,10 @@ package accounts import ( "context" "fmt" + "github.com/onflow/flow-cli/internal/prompt" "github.com/spf13/cobra" - "github.com/onflow/flow-cli/internal/util" - "github.com/onflow/flowkit" "github.com/onflow/flowkit/output" @@ -70,7 +69,7 @@ func removeContract( return nil, err } - removeFromState := util.RemoveContractFromFlowJSONPrompt(contractName) + removeFromState := prompt.RemoveContractFromFlowJSONPrompt(contractName) if removeFromState { // If a network flag is provided, remove from that networks deployments diff --git a/internal/accounts/create-interactive.go b/internal/accounts/create-interactive.go index a173ebf7a..6dd52677f 100644 --- a/internal/accounts/create-interactive.go +++ b/internal/accounts/create-interactive.go @@ -24,6 +24,7 @@ import ( "crypto/tls" "encoding/json" "fmt" + "github.com/onflow/flow-cli/internal/prompt" "io" "net/http" "os" @@ -50,8 +51,8 @@ import ( // and it then uses account creation APIs to automatically create the account on the network as well as save it. func createInteractive(state *flowkit.State) (*accountResult, error) { log := output.NewStdoutLogger(output.InfoLog) - name := util.AccountNamePrompt(state.Accounts().Names()) - networkName, selectedNetwork := util.CreateAccountNetworkPrompt() + name := prompt.AccountNamePrompt(state.Accounts().Names()) + networkName, selectedNetwork := prompt.CreateAccountNetworkPrompt() privateFile := accounts.PrivateKeyFile(name) // create new gateway based on chosen network diff --git a/internal/command/command.go b/internal/command/command.go index cebdd608f..6a34a0855 100644 --- a/internal/command/command.go +++ b/internal/command/command.go @@ -23,6 +23,7 @@ import ( "encoding/base64" "errors" "fmt" + "github.com/onflow/flow-cli/internal/prompt" "io" "net/http" "os" @@ -311,7 +312,7 @@ func initCrashReporting() { // ask for crash report permission fmt.Printf("\n%s Crash detected! %s\n\n", output.ErrorEmoji(), event.Message) - if util.ReportCrash() { + if prompt.ReportCrash() { return event } else { fmt.Printf("\nPlease help us improve the Flow CLI by opening an issue on https://github.com/onflow/flow-cli/issues, \nand pasting the output as well as a description of the actions you took that resulted in this crash.\n\n") diff --git a/internal/config/add-account.go b/internal/config/add-account.go index 6ac9b657c..14972abb2 100644 --- a/internal/config/add-account.go +++ b/internal/config/add-account.go @@ -20,6 +20,7 @@ package config import ( "fmt" + "github.com/onflow/flow-cli/internal/prompt" "strconv" "github.com/onflow/flowkit/accounts" @@ -33,7 +34,6 @@ import ( "github.com/onflow/flowkit/output" "github.com/onflow/flow-cli/internal/command" - "github.com/onflow/flow-cli/internal/util" ) type flagsAddAccount struct { @@ -71,7 +71,7 @@ func addAccount( } if !flagsProvided { - raw = util.NewAccountPrompt() + raw = prompt.NewAccountPrompt() } key, err := parseKey(raw.Key, raw.SigAlgo) @@ -140,7 +140,7 @@ func parseKeyIndex(value string) (int, error) { return v, nil } -func flagsToAccountData(flags flagsAddAccount) (*util.AccountData, bool, error) { +func flagsToAccountData(flags flagsAddAccount) (*prompt.AccountData, bool, error) { if flags.Name == "" && flags.Address == "" && flags.Key == "" { return nil, false, nil } @@ -157,7 +157,7 @@ func flagsToAccountData(flags flagsAddAccount) (*util.AccountData, bool, error) return nil, true, fmt.Errorf("invalid address") } - return &util.AccountData{ + return &prompt.AccountData{ Name: flags.Name, Address: flags.Address, SigAlgo: flags.SigAlgo, diff --git a/internal/config/add-contract.go b/internal/config/add-contract.go index 176113345..8c17a539c 100644 --- a/internal/config/add-contract.go +++ b/internal/config/add-contract.go @@ -20,6 +20,7 @@ package config import ( "fmt" + "github.com/onflow/flow-cli/internal/prompt" "github.com/onflow/flow-go-sdk" "github.com/spf13/cobra" @@ -29,7 +30,6 @@ import ( "github.com/onflow/flowkit/output" "github.com/onflow/flow-cli/internal/command" - "github.com/onflow/flow-cli/internal/util" ) type flagsAddContract struct { @@ -66,7 +66,7 @@ func addContract( } if !flagsProvided { - raw = util.NewContractPrompt() + raw = prompt.NewContractPrompt() } contract := config.Contract{ @@ -107,7 +107,7 @@ func addContract( }, nil } -func flagsToContractData(flags flagsAddContract) (*util.ContractData, bool, error) { +func flagsToContractData(flags flagsAddContract) (*prompt.ContractData, bool, error) { if flags.Name == "" && flags.Filename == "" { return nil, false, nil } @@ -136,7 +136,7 @@ func flagsToContractData(flags flagsAddContract) (*util.ContractData, bool, erro return nil, true, fmt.Errorf("invalid mainnnet alias address") } - return &util.ContractData{ + return &prompt.ContractData{ Name: flags.Name, Source: flags.Filename, Emulator: flags.EmulatorAlias, diff --git a/internal/config/add-deployment.go b/internal/config/add-deployment.go index e1f0059c9..c19e5b7b8 100644 --- a/internal/config/add-deployment.go +++ b/internal/config/add-deployment.go @@ -20,6 +20,7 @@ package config import ( "fmt" + "github.com/onflow/flow-cli/internal/prompt" "github.com/spf13/cobra" @@ -28,7 +29,6 @@ import ( "github.com/onflow/flowkit/output" "github.com/onflow/flow-cli/internal/command" - "github.com/onflow/flow-cli/internal/util" ) type flagsAddDeployment struct { @@ -63,7 +63,7 @@ func addDeployment( } if !flagsProvided { - raw = util.NewDeploymentPrompt(*state.Networks(), state.Config().Accounts, *state.Contracts()) + raw = prompt.NewDeploymentPrompt(*state.Networks(), state.Config().Accounts, *state.Contracts()) } deployment := state.Deployments().ByAccountAndNetwork(raw.Account, raw.Network) @@ -90,7 +90,7 @@ func addDeployment( }, nil } -func flagsToDeploymentData(flags flagsAddDeployment) (*util.DeploymentData, bool, error) { +func flagsToDeploymentData(flags flagsAddDeployment) (*prompt.DeploymentData, bool, error) { if flags.Network == "" && flags.Account == "" && len(flags.Contracts) == 0 { return nil, false, nil } @@ -103,7 +103,7 @@ func flagsToDeploymentData(flags flagsAddDeployment) (*util.DeploymentData, bool return nil, true, fmt.Errorf("at least one contract name must be provided") } - return &util.DeploymentData{ + return &prompt.DeploymentData{ Network: flags.Network, Account: flags.Account, Contracts: flags.Contracts, diff --git a/internal/config/add-network.go b/internal/config/add-network.go index 8605020df..772046c04 100644 --- a/internal/config/add-network.go +++ b/internal/config/add-network.go @@ -20,6 +20,7 @@ package config import ( "fmt" + "github.com/onflow/flow-cli/internal/prompt" "net/url" "github.com/spf13/cobra" @@ -64,7 +65,7 @@ func addNetwork( } if !flagsProvided { - raw = util.NewNetworkPrompt() + raw = prompt.NewNetworkPrompt() } state.Networks().AddOrUpdate(config.Network{ diff --git a/internal/config/remove-account.go b/internal/config/remove-account.go index 29250051d..fb1668e78 100644 --- a/internal/config/remove-account.go +++ b/internal/config/remove-account.go @@ -19,13 +19,13 @@ package config import ( + "github.com/onflow/flow-cli/internal/prompt" "github.com/spf13/cobra" "github.com/onflow/flowkit" "github.com/onflow/flowkit/output" "github.com/onflow/flow-cli/internal/command" - "github.com/onflow/flow-cli/internal/util" ) type flagsRemoveAccount struct{} @@ -54,7 +54,7 @@ func removeAccount( if len(args) == 1 { name = args[0] } else { - name = util.RemoveAccountPrompt(state.Config().Accounts) + name = prompt.RemoveAccountPrompt(state.Config().Accounts) } err := state.Accounts().Remove(name) diff --git a/internal/config/remove-contract.go b/internal/config/remove-contract.go index c2a50e81a..3fc31addf 100644 --- a/internal/config/remove-contract.go +++ b/internal/config/remove-contract.go @@ -19,13 +19,13 @@ package config import ( + "github.com/onflow/flow-cli/internal/prompt" "github.com/spf13/cobra" "github.com/onflow/flowkit" "github.com/onflow/flowkit/output" "github.com/onflow/flow-cli/internal/command" - "github.com/onflow/flow-cli/internal/util" ) type flagsRemoveContract struct{} @@ -54,7 +54,7 @@ func removeContract( if len(args) == 1 { name = args[0] } else { - name = util.RemoveContractPrompt(*state.Contracts()) + name = prompt.RemoveContractPrompt(*state.Contracts()) } err := state.Contracts().Remove(name) diff --git a/internal/config/remove-deployment.go b/internal/config/remove-deployment.go index e2c85bc15..3bb0ca89c 100644 --- a/internal/config/remove-deployment.go +++ b/internal/config/remove-deployment.go @@ -19,13 +19,13 @@ package config import ( + "github.com/onflow/flow-cli/internal/prompt" "github.com/spf13/cobra" "github.com/onflow/flowkit" "github.com/onflow/flowkit/output" "github.com/onflow/flow-cli/internal/command" - "github.com/onflow/flow-cli/internal/util" ) type flagsRemoveDeployment struct{} @@ -56,7 +56,7 @@ func removeDeployment( account = args[0] network = args[1] } else { - account, network = util.RemoveDeploymentPrompt(*state.Deployments()) + account, network = prompt.RemoveDeploymentPrompt(*state.Deployments()) } err := state.Deployments().Remove(account, network) diff --git a/internal/config/remove-network.go b/internal/config/remove-network.go index 391f523bc..33912f5a9 100644 --- a/internal/config/remove-network.go +++ b/internal/config/remove-network.go @@ -19,13 +19,13 @@ package config import ( + "github.com/onflow/flow-cli/internal/prompt" "github.com/spf13/cobra" "github.com/onflow/flowkit" "github.com/onflow/flowkit/output" "github.com/onflow/flow-cli/internal/command" - "github.com/onflow/flow-cli/internal/util" ) type flagsRemoveNetwork struct{} @@ -54,7 +54,7 @@ func removeNetwork( if len(args) == 1 { name = args[0] } else { - name = util.RemoveNetworkPrompt(*state.Networks()) + name = prompt.RemoveNetworkPrompt(*state.Networks()) } err := state.Networks().Remove(name) diff --git a/internal/dependencymanager/dependencyinstaller.go b/internal/dependencymanager/dependencyinstaller.go index 14fdb9470..6a4c3ac3c 100644 --- a/internal/dependencymanager/dependencyinstaller.go +++ b/internal/dependencymanager/dependencyinstaller.go @@ -23,14 +23,13 @@ import ( "crypto/sha256" "encoding/hex" "fmt" + "github.com/onflow/flow-cli/internal/prompt" "os" "path/filepath" "github.com/onflow/flow-go/fvm/systemcontracts" flowGo "github.com/onflow/flow-go/model/flow" - "github.com/onflow/flow-cli/internal/util" - "github.com/onflow/flowkit/gateway" "github.com/onflow/flowkit/project" @@ -345,7 +344,7 @@ func (di *DependencyInstaller) handleFoundContract(networkName, contractAddr, as // If no hash, ignore if dependency != nil && dependency.Hash != "" && dependency.Hash != originalContractDataHash { msg := fmt.Sprintf("The latest version of %s is different from the one you have locally. Do you want to update it?", contractName) - if !util.GenericBoolPrompt(msg) { + if !prompt.GenericBoolPrompt(msg) { return nil } } @@ -389,7 +388,7 @@ func (di *DependencyInstaller) handleFoundContract(networkName, contractAddr, as func (di *DependencyInstaller) updateDependencyDeployment(contractName string) error { // Add to deployments // If a deployment already exists for that account, contract, and network, then ignore - raw := util.AddContractToDeploymentPrompt("emulator", *di.State.Accounts(), contractName) + raw := prompt.AddContractToDeploymentPrompt("emulator", *di.State.Accounts(), contractName) if raw != nil { deployment := di.State.Deployments().ByAccountAndNetwork(raw.Account, raw.Network) @@ -419,7 +418,7 @@ func (di *DependencyInstaller) updateDependencyAlias(contractName, aliasNetwork } label := fmt.Sprintf("Enter an alias address for %s on %s if you have one, otherwise leave blank", contractName, missingNetwork) - raw := util.AddressPromptOrEmpty(label, "Invalid alias address") + raw := prompt.AddressPromptOrEmpty(label, "Invalid alias address") if raw != "" { contract, err := di.State.Contracts().ByName(contractName) diff --git a/internal/project/deploy.go b/internal/project/deploy.go index a51e7d877..6eb648c10 100644 --- a/internal/project/deploy.go +++ b/internal/project/deploy.go @@ -22,6 +22,7 @@ import ( "context" "errors" "fmt" + "github.com/onflow/flow-cli/internal/prompt" "github.com/onflow/flow-go/fvm/systemcontracts" flowGo "github.com/onflow/flow-go/model/flow" @@ -36,7 +37,6 @@ import ( "github.com/onflow/flowkit/project" "github.com/onflow/flow-cli/internal/command" - "github.com/onflow/flow-cli/internal/util" ) type flagsDeploy struct { @@ -73,7 +73,7 @@ func deploy( deployFunc := flowkit.UpdateExistingContract(deployFlags.Update) if deployFlags.ShowDiff { - deployFunc = util.ShowContractDiffPrompt(logger) + deployFunc = prompt.ShowContractDiffPrompt(logger) } c, err := flow.DeployProject(context.Background(), deployFunc) @@ -149,7 +149,7 @@ func checkForStandardContractUsageOnMainnet(state *flowkit.State, logger output. logger.Info(fmt.Sprintf("It is a standard contract already deployed at address 0x%s \n", standardContract.address.String())) logger.Info(fmt.Sprintf("You can read more about it here: %s \n", standardContract.infoLink)) - if replace || util.WantToUseMainnetVersionPrompt() { + if replace || prompt.WantToUseMainnetVersionPrompt() { err := replaceContractWithAlias(state, standardContract) if err != nil { return err diff --git a/internal/util/prompt.go b/internal/prompt/prompt.go similarity index 98% rename from internal/util/prompt.go rename to internal/prompt/prompt.go index 96ea1f753..b414a3e21 100644 --- a/internal/util/prompt.go +++ b/internal/prompt/prompt.go @@ -16,10 +16,11 @@ * limitations under the License. */ -package util +package prompt import ( "fmt" + "github.com/onflow/flow-cli/internal/util" "os" "path/filepath" "strconv" @@ -195,7 +196,7 @@ func secureNetworkKeyPrompt() string { return nil } - return ValidateECDSAP256Pub(s) + return util.ValidateECDSAP256Pub(s) }, } networkKey, err := networkKeyPrompt.Run() @@ -490,6 +491,17 @@ func NewDeploymentPrompt( return deploymentData } +func removeFromStringArray(s []string, el string) []string { + for i, v := range s { + if v == el { + s = append(s[:i], s[i+1:]...) + break + } + } + + return s +} + // AddContractToDeploymentPrompt prompts a user to select an account to deploy a given contract on a given network func AddContractToDeploymentPrompt(networkName string, accounts accounts.Accounts, contractName string) *DeploymentData { deploymentData := &DeploymentData{ diff --git a/internal/super/scaffolds.go b/internal/super/scaffolds.go index 5c30b9995..ac17f90c4 100644 --- a/internal/super/scaffolds.go +++ b/internal/super/scaffolds.go @@ -21,6 +21,7 @@ package super import ( "encoding/json" "fmt" + "github.com/onflow/flow-cli/internal/prompt" "io" "net/http" "os" @@ -30,8 +31,6 @@ import ( "github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5/plumbing" "github.com/onflow/flowkit/output" - - "github.com/onflow/flow-cli/internal/util" ) const scaffoldListURL = "https://raw.githubusercontent.com/onflow/flow-cli/master/scaffolds.json" @@ -63,11 +62,11 @@ func selectScaffold(logger output.Logger) (*scaffold, error) { } if setupFlags.Scaffold { - scaffoldItems := make([]util.ScaffoldItem, 0) + scaffoldItems := make([]prompt.ScaffoldItem, 0) for i, s := range scaffolds { scaffoldItems = append( scaffoldItems, - util.ScaffoldItem{ + prompt.ScaffoldItem{ Index: i, Title: fmt.Sprintf("%s - %s", output.Bold(s.Name), s.Description), Category: s.Type, @@ -75,7 +74,7 @@ func selectScaffold(logger output.Logger) (*scaffold, error) { ) } - selected := util.ScaffoldPrompt(logger, scaffoldItems) + selected := prompt.ScaffoldPrompt(logger, scaffoldItems) pickedScaffold = scaffolds[selected] } diff --git a/internal/super/setup.go b/internal/super/setup.go index 6887cc70e..7e10c7339 100644 --- a/internal/super/setup.go +++ b/internal/super/setup.go @@ -21,6 +21,7 @@ package super import ( "bytes" "fmt" + "github.com/onflow/flow-cli/internal/prompt" "io" "os" "path/filepath" @@ -32,8 +33,6 @@ import ( flowkitConfig "github.com/onflow/flowkit/config" "github.com/onflow/flow-cli/internal/dependencymanager" - "github.com/onflow/flow-cli/internal/util" - "github.com/spf13/cobra" "github.com/onflow/flowkit" @@ -97,7 +96,7 @@ func create( } else { // Ask for project name if not given if len(args) < 1 { - name := util.NamePrompt() + name := prompt.NamePrompt() targetDir, err = getTargetDirectory(name) if err != nil { return nil, err @@ -154,7 +153,7 @@ func create( contractNames = append(contractNames, contract.Name) } - m := util.GenericOptionSelect(contractNames, promptMessage) + m := prompt.GenericOptionSelect(contractNames, promptMessage) finalModel, err := tea.NewProgram(m).Run() if err != nil { @@ -162,7 +161,7 @@ func create( os.Exit(1) } - final := finalModel.(util.OptionSelectModel) + final := finalModel.(prompt.OptionSelectModel) var dependencies []flowkitConfig.Dependency diff --git a/internal/tools/flowser.go b/internal/tools/flowser.go index 64ebea21c..53b3f507a 100644 --- a/internal/tools/flowser.go +++ b/internal/tools/flowser.go @@ -20,6 +20,7 @@ package tools import ( "fmt" + "github.com/onflow/flow-cli/internal/prompt" "os" "runtime" @@ -32,7 +33,6 @@ import ( "github.com/onflow/flow-cli/internal/command" "github.com/onflow/flow-cli/internal/settings" - "github.com/onflow/flow-cli/internal/util" ) type flagsFlowser struct{} @@ -94,21 +94,21 @@ func runFlowser( func installFlowser(flowser *flowser.App, installPath string) (string, error) { fmt.Println("It looks like Flowser is not yet installed on your system.") - installChoice := util.InstallPrompt() - if installChoice == util.CancelInstall { + installChoice := prompt.InstallPrompt() + if installChoice == prompt.CancelInstall { return "", fmt.Errorf("user denied install") } // if user says it already installed it we only ask for path and return it - if installChoice == util.AlreadyInstalled { - installPath = util.InstallPathPrompt(installPath) + if installChoice == prompt.AlreadyInstalled { + installPath = prompt.InstallPathPrompt(installPath) _ = settings.SetFlowserPath(installPath) return installPath, nil } // MacOS apps must always be installed inside Application folder if runtime.GOOS != settings.Darwin { - installPath = util.InstallPathPrompt(installPath) + installPath = prompt.InstallPathPrompt(installPath) _ = settings.SetFlowserPath(installPath) } diff --git a/internal/transactions/build.go b/internal/transactions/build.go index 70e4a73ec..12493d6a4 100644 --- a/internal/transactions/build.go +++ b/internal/transactions/build.go @@ -21,6 +21,7 @@ package transactions import ( "context" "fmt" + "github.com/onflow/flow-cli/internal/prompt" "github.com/onflow/cadence" flowsdk "github.com/onflow/flow-go-sdk" @@ -32,7 +33,6 @@ import ( "github.com/onflow/flowkit/transactions" "github.com/onflow/flow-cli/internal/command" - "github.com/onflow/flow-cli/internal/util" ) type flagsBuild struct { @@ -119,7 +119,7 @@ func build( return nil, err } - if !globalFlags.Yes && !util.ApproveTransactionForBuildingPrompt(tx.FlowTransaction()) { + if !globalFlags.Yes && !prompt.ApproveTransactionForBuildingPrompt(tx.FlowTransaction()) { return nil, fmt.Errorf("transaction was not approved") } diff --git a/internal/transactions/send-signed.go b/internal/transactions/send-signed.go index ccaae4953..65c1e878b 100644 --- a/internal/transactions/send-signed.go +++ b/internal/transactions/send-signed.go @@ -21,6 +21,7 @@ package transactions import ( "context" "fmt" + "github.com/onflow/flow-cli/internal/prompt" "github.com/onflow/flowkit/transactions" @@ -30,7 +31,6 @@ import ( "github.com/onflow/flowkit/output" "github.com/onflow/flow-cli/internal/command" - "github.com/onflow/flow-cli/internal/util" ) type flagsSendSigned struct { @@ -70,7 +70,7 @@ func sendSigned( return nil, err } - if !globalFlags.Yes && !util.ApproveTransactionForSendingPrompt(tx.FlowTransaction()) { + if !globalFlags.Yes && !prompt.ApproveTransactionForSendingPrompt(tx.FlowTransaction()) { return nil, fmt.Errorf("transaction was not approved for sending") } diff --git a/internal/transactions/sign.go b/internal/transactions/sign.go index 4c49cfd76..f792500d0 100644 --- a/internal/transactions/sign.go +++ b/internal/transactions/sign.go @@ -23,6 +23,7 @@ import ( "context" "encoding/hex" "fmt" + "github.com/onflow/flow-cli/internal/prompt" "io" "net/http" "sort" @@ -38,7 +39,6 @@ import ( "github.com/onflow/flowkit/output" "github.com/onflow/flow-cli/internal/command" - "github.com/onflow/flow-cli/internal/util" ) type flagsSign struct { @@ -115,7 +115,7 @@ func sign( }) for _, signer := range signers { - if !globalFlags.Yes && !util.ApproveTransactionForSigningPrompt(tx.FlowTransaction()) { + if !globalFlags.Yes && !prompt.ApproveTransactionForSigningPrompt(tx.FlowTransaction()) { return nil, fmt.Errorf("transaction was not approved for signing") } diff --git a/internal/util/util.go b/internal/util/util.go index beec1a411..b9d33c7f2 100644 --- a/internal/util/util.go +++ b/internal/util/util.go @@ -100,14 +100,3 @@ func ValidateECDSAP256Pub(key string) error { return nil } - -func removeFromStringArray(s []string, el string) []string { - for i, v := range s { - if v == el { - s = append(s[:i], s[i+1:]...) - break - } - } - - return s -} From 86dc574cc8cacdf0f9e5f134e677f23b7a607eaa Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Tue, 16 Apr 2024 14:36:05 -0700 Subject: [PATCH 17/86] Rename as SelectOptions --- internal/prompt/prompt.go | 4 ++-- internal/super/setup.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/prompt/prompt.go b/internal/prompt/prompt.go index b414a3e21..e152b2b6d 100644 --- a/internal/prompt/prompt.go +++ b/internal/prompt/prompt.go @@ -826,8 +826,8 @@ type OptionSelectModel struct { Selected map[int]struct{} // which items are selected } -// GenericOptionSelect creates a prompt for selecting multiple options -func GenericOptionSelect(options []string, message string) OptionSelectModel { +// SelectOptions creates a prompt for selecting multiple options +func SelectOptions(options []string, message string) OptionSelectModel { return OptionSelectModel{ message: message, Choices: options, diff --git a/internal/super/setup.go b/internal/super/setup.go index 7e10c7339..815b34e41 100644 --- a/internal/super/setup.go +++ b/internal/super/setup.go @@ -153,7 +153,7 @@ func create( contractNames = append(contractNames, contract.Name) } - m := prompt.GenericOptionSelect(contractNames, promptMessage) + m := prompt.SelectOptions(contractNames, promptMessage) finalModel, err := tea.NewProgram(m).Run() if err != nil { From 1c226634c1fb32c193898bcb7137f7c240cac897 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Tue, 16 Apr 2024 14:37:22 -0700 Subject: [PATCH 18/86] Move prompt to its own file --- internal/prompt/prompt.go | 77 ----------------------- internal/prompt/select-options.go | 100 ++++++++++++++++++++++++++++++ 2 files changed, 100 insertions(+), 77 deletions(-) create mode 100644 internal/prompt/select-options.go diff --git a/internal/prompt/prompt.go b/internal/prompt/prompt.go index e152b2b6d..5d6d17fea 100644 --- a/internal/prompt/prompt.go +++ b/internal/prompt/prompt.go @@ -26,8 +26,6 @@ import ( "strconv" "strings" - tea "github.com/charmbracelet/bubbletea" - "github.com/onflow/flowkit/accounts" "github.com/gosuri/uilive" @@ -817,78 +815,3 @@ func GenericSelect(items []string, message string) string { return result } - -// OptionSelectModel represents the prompt state -type OptionSelectModel struct { - message string // message to display - cursor int // position of the cursor - Choices []string // items on the list - Selected map[int]struct{} // which items are selected -} - -// SelectOptions creates a prompt for selecting multiple options -func SelectOptions(options []string, message string) OptionSelectModel { - return OptionSelectModel{ - message: message, - Choices: options, - Selected: make(map[int]struct{}), - } -} - -func (m OptionSelectModel) Init() tea.Cmd { - return nil // No initial command -} - -func (m OptionSelectModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { - switch msg := msg.(type) { - case tea.KeyMsg: - switch msg.Type { - case tea.KeyCtrlC, tea.KeyEsc: // Quit the program - return m, tea.Quit - - case tea.KeyUp: // Navigate up - if m.cursor > 0 { - m.cursor-- - } - - case tea.KeyDown: // Navigate down - if m.cursor < len(m.Choices)-1 { - m.cursor++ - } - - case tea.KeySpace: // Select an item - // Toggle selection - if _, ok := m.Selected[m.cursor]; ok { - delete(m.Selected, m.cursor) // Deselect - } else { - m.Selected[m.cursor] = struct{}{} // Select - } - - case tea.KeyEnter: // Confirm selection - return m, tea.Quit // Quit and process selections in main - } - } - - return m, nil -} - -func (m OptionSelectModel) View() string { - var b strings.Builder - b.WriteString(fmt.Sprintf("%s.\n", m.message)) - b.WriteString("Use arrow keys to navigate, space to select, enter to confirm, q to quit:\n\n") - for i, choice := range m.Choices { - if m.cursor == i { - b.WriteString("> ") - } else { - b.WriteString(" ") - } - // Mark selected items - if _, ok := m.Selected[i]; ok { - b.WriteString("[x] ") - } else { - b.WriteString("[ ] ") - } - b.WriteString(choice + "\n") - } - return b.String() -} diff --git a/internal/prompt/select-options.go b/internal/prompt/select-options.go new file mode 100644 index 000000000..6b36fe7f3 --- /dev/null +++ b/internal/prompt/select-options.go @@ -0,0 +1,100 @@ +/* + * Flow CLI + * + * Copyright 2019 Dapper Labs, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package prompt + +import ( + "fmt" + tea "github.com/charmbracelet/bubbletea" + "strings" +) + +// OptionSelectModel represents the prompt state +type OptionSelectModel struct { + message string // message to display + cursor int // position of the cursor + Choices []string // items on the list + Selected map[int]struct{} // which items are selected +} + +// SelectOptions creates a prompt for selecting multiple options +func SelectOptions(options []string, message string) OptionSelectModel { + return OptionSelectModel{ + message: message, + Choices: options, + Selected: make(map[int]struct{}), + } +} + +func (m OptionSelectModel) Init() tea.Cmd { + return nil // No initial command +} + +func (m OptionSelectModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { + switch msg := msg.(type) { + case tea.KeyMsg: + switch msg.Type { + case tea.KeyCtrlC, tea.KeyEsc: // Quit the program + return m, tea.Quit + + case tea.KeyUp: // Navigate up + if m.cursor > 0 { + m.cursor-- + } + + case tea.KeyDown: // Navigate down + if m.cursor < len(m.Choices)-1 { + m.cursor++ + } + + case tea.KeySpace: // Select an item + // Toggle selection + if _, ok := m.Selected[m.cursor]; ok { + delete(m.Selected, m.cursor) // Deselect + } else { + m.Selected[m.cursor] = struct{}{} // Select + } + + case tea.KeyEnter: // Confirm selection + return m, tea.Quit // Quit and process selections in main + } + } + + return m, nil +} + +func (m OptionSelectModel) View() string { + var b strings.Builder + b.WriteString(fmt.Sprintf("%s.\n", m.message)) + b.WriteString("Use arrow keys to navigate, space to select, enter to confirm, q to quit:\n\n") + for i, choice := range m.Choices { + if m.cursor == i { + b.WriteString("> ") + } else { + b.WriteString(" ") + } + // Mark selected items + if _, ok := m.Selected[i]; ok { + b.WriteString("[x] ") + } else { + b.WriteString("[ ] ") + } + b.WriteString(choice + "\n") + } + return b.String() +} From 7b0c2019166372bb4d4402bbca3d797f9af46234 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Tue, 16 Apr 2024 14:41:34 -0700 Subject: [PATCH 19/86] Run go imports fix --- internal/accounts/contract-add.go | 1 + internal/accounts/contract-remove.go | 1 + internal/accounts/create-interactive.go | 3 ++- internal/command/command.go | 3 ++- internal/config/add-account.go | 3 ++- internal/config/add-contract.go | 1 + internal/config/add-deployment.go | 1 + internal/config/add-network.go | 3 ++- internal/config/remove-account.go | 3 ++- internal/config/remove-contract.go | 3 ++- internal/config/remove-deployment.go | 3 ++- internal/config/remove-network.go | 3 ++- internal/dependencymanager/dependencyinstaller.go | 3 ++- internal/project/deploy.go | 1 + internal/prompt/prompt.go | 3 ++- internal/prompt/select-options.go | 3 ++- internal/super/scaffolds.go | 3 ++- internal/super/setup.go | 6 ++++-- internal/tools/flowser.go | 3 ++- internal/transactions/build.go | 1 + internal/transactions/send-signed.go | 1 + internal/transactions/sign.go | 3 ++- 22 files changed, 39 insertions(+), 16 deletions(-) diff --git a/internal/accounts/contract-add.go b/internal/accounts/contract-add.go index bcf7f21b5..6db34956b 100644 --- a/internal/accounts/contract-add.go +++ b/internal/accounts/contract-add.go @@ -21,6 +21,7 @@ package accounts import ( "context" "fmt" + "github.com/onflow/flow-cli/internal/prompt" "github.com/onflow/cadence" diff --git a/internal/accounts/contract-remove.go b/internal/accounts/contract-remove.go index 0e7beb128..22736e66b 100644 --- a/internal/accounts/contract-remove.go +++ b/internal/accounts/contract-remove.go @@ -21,6 +21,7 @@ package accounts import ( "context" "fmt" + "github.com/onflow/flow-cli/internal/prompt" "github.com/spf13/cobra" diff --git a/internal/accounts/create-interactive.go b/internal/accounts/create-interactive.go index 6dd52677f..3adc60083 100644 --- a/internal/accounts/create-interactive.go +++ b/internal/accounts/create-interactive.go @@ -24,13 +24,14 @@ import ( "crypto/tls" "encoding/json" "fmt" - "github.com/onflow/flow-cli/internal/prompt" "io" "net/http" "os" "strings" "time" + "github.com/onflow/flow-cli/internal/prompt" + flowsdk "github.com/onflow/flow-go-sdk" "github.com/onflow/flow-go-sdk/crypto" "google.golang.org/grpc/codes" diff --git a/internal/command/command.go b/internal/command/command.go index 6a34a0855..020e9357d 100644 --- a/internal/command/command.go +++ b/internal/command/command.go @@ -23,7 +23,6 @@ import ( "encoding/base64" "errors" "fmt" - "github.com/onflow/flow-cli/internal/prompt" "io" "net/http" "os" @@ -34,6 +33,8 @@ import ( "sync" "time" + "github.com/onflow/flow-cli/internal/prompt" + "github.com/dukex/mixpanel" "github.com/getsentry/sentry-go" "github.com/spf13/afero" diff --git a/internal/config/add-account.go b/internal/config/add-account.go index 14972abb2..3fc39c1f0 100644 --- a/internal/config/add-account.go +++ b/internal/config/add-account.go @@ -20,9 +20,10 @@ package config import ( "fmt" - "github.com/onflow/flow-cli/internal/prompt" "strconv" + "github.com/onflow/flow-cli/internal/prompt" + "github.com/onflow/flowkit/accounts" "github.com/onflow/flow-go-sdk" diff --git a/internal/config/add-contract.go b/internal/config/add-contract.go index 8c17a539c..5c2a8478e 100644 --- a/internal/config/add-contract.go +++ b/internal/config/add-contract.go @@ -20,6 +20,7 @@ package config import ( "fmt" + "github.com/onflow/flow-cli/internal/prompt" "github.com/onflow/flow-go-sdk" diff --git a/internal/config/add-deployment.go b/internal/config/add-deployment.go index c19e5b7b8..5bb920fd9 100644 --- a/internal/config/add-deployment.go +++ b/internal/config/add-deployment.go @@ -20,6 +20,7 @@ package config import ( "fmt" + "github.com/onflow/flow-cli/internal/prompt" "github.com/spf13/cobra" diff --git a/internal/config/add-network.go b/internal/config/add-network.go index 772046c04..28e7ad97f 100644 --- a/internal/config/add-network.go +++ b/internal/config/add-network.go @@ -20,9 +20,10 @@ package config import ( "fmt" - "github.com/onflow/flow-cli/internal/prompt" "net/url" + "github.com/onflow/flow-cli/internal/prompt" + "github.com/spf13/cobra" "github.com/onflow/flowkit" diff --git a/internal/config/remove-account.go b/internal/config/remove-account.go index fb1668e78..8edd47c80 100644 --- a/internal/config/remove-account.go +++ b/internal/config/remove-account.go @@ -19,9 +19,10 @@ package config import ( - "github.com/onflow/flow-cli/internal/prompt" "github.com/spf13/cobra" + "github.com/onflow/flow-cli/internal/prompt" + "github.com/onflow/flowkit" "github.com/onflow/flowkit/output" diff --git a/internal/config/remove-contract.go b/internal/config/remove-contract.go index 3fc31addf..9248b525b 100644 --- a/internal/config/remove-contract.go +++ b/internal/config/remove-contract.go @@ -19,9 +19,10 @@ package config import ( - "github.com/onflow/flow-cli/internal/prompt" "github.com/spf13/cobra" + "github.com/onflow/flow-cli/internal/prompt" + "github.com/onflow/flowkit" "github.com/onflow/flowkit/output" diff --git a/internal/config/remove-deployment.go b/internal/config/remove-deployment.go index 3bb0ca89c..9648ec523 100644 --- a/internal/config/remove-deployment.go +++ b/internal/config/remove-deployment.go @@ -19,9 +19,10 @@ package config import ( - "github.com/onflow/flow-cli/internal/prompt" "github.com/spf13/cobra" + "github.com/onflow/flow-cli/internal/prompt" + "github.com/onflow/flowkit" "github.com/onflow/flowkit/output" diff --git a/internal/config/remove-network.go b/internal/config/remove-network.go index 33912f5a9..e89588d97 100644 --- a/internal/config/remove-network.go +++ b/internal/config/remove-network.go @@ -19,9 +19,10 @@ package config import ( - "github.com/onflow/flow-cli/internal/prompt" "github.com/spf13/cobra" + "github.com/onflow/flow-cli/internal/prompt" + "github.com/onflow/flowkit" "github.com/onflow/flowkit/output" diff --git a/internal/dependencymanager/dependencyinstaller.go b/internal/dependencymanager/dependencyinstaller.go index 6a4c3ac3c..d2cee2731 100644 --- a/internal/dependencymanager/dependencyinstaller.go +++ b/internal/dependencymanager/dependencyinstaller.go @@ -23,10 +23,11 @@ import ( "crypto/sha256" "encoding/hex" "fmt" - "github.com/onflow/flow-cli/internal/prompt" "os" "path/filepath" + "github.com/onflow/flow-cli/internal/prompt" + "github.com/onflow/flow-go/fvm/systemcontracts" flowGo "github.com/onflow/flow-go/model/flow" diff --git a/internal/project/deploy.go b/internal/project/deploy.go index 6eb648c10..ed1cd7bc6 100644 --- a/internal/project/deploy.go +++ b/internal/project/deploy.go @@ -22,6 +22,7 @@ import ( "context" "errors" "fmt" + "github.com/onflow/flow-cli/internal/prompt" "github.com/onflow/flow-go/fvm/systemcontracts" diff --git a/internal/prompt/prompt.go b/internal/prompt/prompt.go index 5d6d17fea..b371d111c 100644 --- a/internal/prompt/prompt.go +++ b/internal/prompt/prompt.go @@ -20,12 +20,13 @@ package prompt import ( "fmt" - "github.com/onflow/flow-cli/internal/util" "os" "path/filepath" "strconv" "strings" + "github.com/onflow/flow-cli/internal/util" + "github.com/onflow/flowkit/accounts" "github.com/gosuri/uilive" diff --git a/internal/prompt/select-options.go b/internal/prompt/select-options.go index 6b36fe7f3..2d15a69ae 100644 --- a/internal/prompt/select-options.go +++ b/internal/prompt/select-options.go @@ -20,8 +20,9 @@ package prompt import ( "fmt" - tea "github.com/charmbracelet/bubbletea" "strings" + + tea "github.com/charmbracelet/bubbletea" ) // OptionSelectModel represents the prompt state diff --git a/internal/super/scaffolds.go b/internal/super/scaffolds.go index ac17f90c4..d882f437c 100644 --- a/internal/super/scaffolds.go +++ b/internal/super/scaffolds.go @@ -21,13 +21,14 @@ package super import ( "encoding/json" "fmt" - "github.com/onflow/flow-cli/internal/prompt" "io" "net/http" "os" "path/filepath" "time" + "github.com/onflow/flow-cli/internal/prompt" + "github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5/plumbing" "github.com/onflow/flowkit/output" diff --git a/internal/super/setup.go b/internal/super/setup.go index 815b34e41..c9f5d230f 100644 --- a/internal/super/setup.go +++ b/internal/super/setup.go @@ -21,20 +21,22 @@ package super import ( "bytes" "fmt" - "github.com/onflow/flow-cli/internal/prompt" "io" "os" "path/filepath" + "github.com/onflow/flow-cli/internal/prompt" + tea "github.com/charmbracelet/bubbletea" flowsdk "github.com/onflow/flow-go-sdk" "github.com/onflow/flow-go/fvm/systemcontracts" flowGo "github.com/onflow/flow-go/model/flow" flowkitConfig "github.com/onflow/flowkit/config" - "github.com/onflow/flow-cli/internal/dependencymanager" "github.com/spf13/cobra" + "github.com/onflow/flow-cli/internal/dependencymanager" + "github.com/onflow/flowkit" "github.com/onflow/flowkit/output" diff --git a/internal/tools/flowser.go b/internal/tools/flowser.go index 53b3f507a..043bd1c0e 100644 --- a/internal/tools/flowser.go +++ b/internal/tools/flowser.go @@ -20,10 +20,11 @@ package tools import ( "fmt" - "github.com/onflow/flow-cli/internal/prompt" "os" "runtime" + "github.com/onflow/flow-cli/internal/prompt" + "github.com/onflowser/flowser/v3/pkg/flowser" "github.com/spf13/cobra" diff --git a/internal/transactions/build.go b/internal/transactions/build.go index 12493d6a4..37fd0df81 100644 --- a/internal/transactions/build.go +++ b/internal/transactions/build.go @@ -21,6 +21,7 @@ package transactions import ( "context" "fmt" + "github.com/onflow/flow-cli/internal/prompt" "github.com/onflow/cadence" diff --git a/internal/transactions/send-signed.go b/internal/transactions/send-signed.go index 65c1e878b..f4260e816 100644 --- a/internal/transactions/send-signed.go +++ b/internal/transactions/send-signed.go @@ -21,6 +21,7 @@ package transactions import ( "context" "fmt" + "github.com/onflow/flow-cli/internal/prompt" "github.com/onflow/flowkit/transactions" diff --git a/internal/transactions/sign.go b/internal/transactions/sign.go index f792500d0..bbf4d9aec 100644 --- a/internal/transactions/sign.go +++ b/internal/transactions/sign.go @@ -23,11 +23,12 @@ import ( "context" "encoding/hex" "fmt" - "github.com/onflow/flow-cli/internal/prompt" "io" "net/http" "sort" + "github.com/onflow/flow-cli/internal/prompt" + "github.com/onflow/flowkit/transactions" "github.com/onflow/flowkit/accounts" From e7a2f49de427b783fc0951d4661b2555e36c2031 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Wed, 17 Apr 2024 15:10:24 -0700 Subject: [PATCH 20/86] Create text input --- go.mod | 3 ++ go.sum | 6 ++++ internal/prompt/text-input.go | 54 +++++++++++++++++++++++++++++++++++ 3 files changed, 63 insertions(+) create mode 100644 internal/prompt/text-input.go diff --git a/go.mod b/go.mod index e5c826f96..4be918fb7 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module github.com/onflow/flow-cli go 1.20 require ( + github.com/charmbracelet/bubbles v0.18.0 github.com/charmbracelet/bubbletea v0.25.0 github.com/dukex/mixpanel v1.0.1 github.com/getsentry/sentry-go v0.27.0 @@ -50,6 +51,7 @@ require ( github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 // indirect github.com/StackExchange/wmi v1.2.1 // indirect github.com/VictoriaMetrics/fastcache v1.12.1 // indirect + github.com/atotto/clipboard v0.1.4 // indirect github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bits-and-blooms/bitset v1.10.0 // indirect @@ -59,6 +61,7 @@ require ( github.com/cenkalti/backoff/v4 v4.2.1 // indirect github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/charmbracelet/lipgloss v0.9.1 // indirect github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e // indirect github.com/cloudflare/circl v1.3.3 // indirect github.com/cockroachdb/errors v1.9.1 // indirect diff --git a/go.sum b/go.sum index ff0b4ddb1..5941bb602 100644 --- a/go.sum +++ b/go.sum @@ -126,6 +126,8 @@ github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmV github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= +github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4= +github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI= github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= @@ -179,8 +181,12 @@ github.com/cespare/xxhash/v2 v2.0.1-0.20190104013014-3767db7a7e18/go.mod h1:HD5P github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/charmbracelet/bubbles v0.18.0 h1:PYv1A036luoBGroX6VWjQIE9Syf2Wby2oOl/39KLfy0= +github.com/charmbracelet/bubbles v0.18.0/go.mod h1:08qhZhtIwzgrtBjAcJnij1t1H0ZRjwHyGsy6AL11PSw= github.com/charmbracelet/bubbletea v0.25.0 h1:bAfwk7jRz7FKFl9RzlIULPkStffg5k6pNt5dywy4TcM= github.com/charmbracelet/bubbletea v0.25.0/go.mod h1:EN3QDR1T5ZdWmdfDzYcqOCAps45+QIJbLOBxmVNWNNg= +github.com/charmbracelet/lipgloss v0.9.1 h1:PNyd3jvaJbg4jRHKWXnCj1akQm4rh8dbEzN1p/u1KWg= +github.com/charmbracelet/lipgloss v0.9.1/go.mod h1:1mPmG4cxScwUQALAAnacHaigiiHB9Pmr+v1VEawJl6I= github.com/cheekybits/genny v1.0.0/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ= github.com/chzyer/logex v1.1.10 h1:Swpa1K6QvQznwJRcfTfQJmTE72DqScAa40E+fbHEXEE= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= diff --git a/internal/prompt/text-input.go b/internal/prompt/text-input.go new file mode 100644 index 000000000..fc3f23532 --- /dev/null +++ b/internal/prompt/text-input.go @@ -0,0 +1,54 @@ +package prompt + +import ( + "fmt" + "github.com/charmbracelet/bubbles/textinput" + tea "github.com/charmbracelet/bubbletea" +) + +type TextInputModel struct { + textInput textinput.Model + err error + customMsg string +} + +// NewTextInput initializes a new text input model with a custom message +func NewTextInput(customMsg, placeholder string) TextInputModel { + ti := textinput.New() + ti.Placeholder = placeholder + ti.Focus() + ti.CharLimit = 256 + ti.Width = 30 + + return TextInputModel{ + textInput: ti, + customMsg: customMsg, + } +} + +func (m TextInputModel) Init() tea.Cmd { + return textinput.Blink +} + +func (m TextInputModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { + switch msg := msg.(type) { + case tea.KeyMsg: + switch msg.Type { + case tea.KeyEnter, tea.KeyCtrlC, tea.KeyEsc: + return m, tea.Quit + } + var cmd tea.Cmd + m.textInput, cmd = m.textInput.Update(msg) + return m, cmd + } + + return m, nil +} + +func (m TextInputModel) View() string { + return fmt.Sprintf("%s\n\n%s\n\n%s", m.customMsg, m.textInput.View(), "(Enter to submit, Esc to quit)") +} + +func (m TextInputModel) GetValue() string { + return m.textInput.Value() +} From 10ba978598315676cb906d40ea441d9893113fe5 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Wed, 17 Apr 2024 15:11:53 -0700 Subject: [PATCH 21/86] Replace existing prompt --- internal/super/setup.go | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/internal/super/setup.go b/internal/super/setup.go index c9f5d230f..027a066c1 100644 --- a/internal/super/setup.go +++ b/internal/super/setup.go @@ -98,7 +98,16 @@ func create( } else { // Ask for project name if not given if len(args) < 1 { - name := prompt.NamePrompt() + m := prompt.NewTextInput("Enter the name of your project", "Hello World") + finalModel, err := tea.NewProgram(m).Run() + + if err != nil { + fmt.Printf("Error running program: %v\n", err) + os.Exit(1) + } + + name := finalModel.(prompt.TextInputModel).GetValue() + targetDir, err = getTargetDirectory(name) if err != nil { return nil, err From 95ff190a2166849aa382eb0f0d3e33723091cf7a Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Wed, 17 Apr 2024 15:26:17 -0700 Subject: [PATCH 22/86] Add Run methods to each prompt --- internal/prompt/select-options.go | 17 +++++++++++++++++ internal/prompt/text-input.go | 13 +++++++++++-- internal/super/setup.go | 28 ++++++++++------------------ 3 files changed, 38 insertions(+), 20 deletions(-) diff --git a/internal/prompt/select-options.go b/internal/prompt/select-options.go index 2d15a69ae..029249229 100644 --- a/internal/prompt/select-options.go +++ b/internal/prompt/select-options.go @@ -99,3 +99,20 @@ func (m OptionSelectModel) View() string { } return b.String() } + +// RunSelectOptions handles creating, running the select options prompt, and returning selected choices +func RunSelectOptions(options []string, message string) ([]string, error) { + model := SelectOptions(options, message) + p := tea.NewProgram(model) + finalModel, err := p.Run() + if err != nil { + return nil, err + } + + final := finalModel.(OptionSelectModel) + selectedChoices := make([]string, 0) + for i := range final.Selected { + selectedChoices = append(selectedChoices, final.Choices[i]) + } + return selectedChoices, nil +} diff --git a/internal/prompt/text-input.go b/internal/prompt/text-input.go index fc3f23532..7889ea5f5 100644 --- a/internal/prompt/text-input.go +++ b/internal/prompt/text-input.go @@ -49,6 +49,15 @@ func (m TextInputModel) View() string { return fmt.Sprintf("%s\n\n%s\n\n%s", m.customMsg, m.textInput.View(), "(Enter to submit, Esc to quit)") } -func (m TextInputModel) GetValue() string { - return m.textInput.Value() +// RunTextInput handles running the text input and retrieving the result +func RunTextInput(customMsg, placeholder string) (string, error) { + model := NewTextInput(customMsg, placeholder) + p := tea.NewProgram(model) + + if finalModel, err := p.Run(); err != nil { + return "", err // return the error to handle it outside if necessary + } else { + final := finalModel.(TextInputModel) + return final.textInput.Value(), nil // directly return the input value + } } diff --git a/internal/super/setup.go b/internal/super/setup.go index 027a066c1..cedb04fa8 100644 --- a/internal/super/setup.go +++ b/internal/super/setup.go @@ -21,14 +21,14 @@ package super import ( "bytes" "fmt" + flowsdk "github.com/onflow/flow-go-sdk" + "golang.org/x/exp/slices" "io" "os" "path/filepath" "github.com/onflow/flow-cli/internal/prompt" - tea "github.com/charmbracelet/bubbletea" - flowsdk "github.com/onflow/flow-go-sdk" "github.com/onflow/flow-go/fvm/systemcontracts" flowGo "github.com/onflow/flow-go/model/flow" flowkitConfig "github.com/onflow/flowkit/config" @@ -98,17 +98,13 @@ func create( } else { // Ask for project name if not given if len(args) < 1 { - m := prompt.NewTextInput("Enter the name of your project", "Hello World") - finalModel, err := tea.NewProgram(m).Run() - + userInput, err := prompt.RunTextInput("Enter the name of your project", "Type your project name here...") if err != nil { - fmt.Printf("Error running program: %v\n", err) + fmt.Printf("Error running project name: %v\n", err) os.Exit(1) } - name := finalModel.(prompt.TextInputModel).GetValue() - - targetDir, err = getTargetDirectory(name) + targetDir, err = getTargetDirectory(userInput) if err != nil { return nil, err } @@ -156,7 +152,7 @@ func create( // Prompt to ask which core contracts should be installed sc := systemcontracts.SystemContractsForChain(flowGo.Mainnet) - promptMessage := "Select the core contracts you'd like to install" + promptMessage := "Select the core contracts you'd like to install:" contractNames := make([]string, 0) @@ -164,21 +160,17 @@ func create( contractNames = append(contractNames, contract.Name) } - m := prompt.SelectOptions(contractNames, promptMessage) - finalModel, err := tea.NewProgram(m).Run() - + selectedContractNames, err := prompt.RunSelectOptions(contractNames, promptMessage) if err != nil { - fmt.Printf("Error running program: %v\n", err) + fmt.Printf("Error running dependency selection: %v\n", err) os.Exit(1) } - final := finalModel.(prompt.OptionSelectModel) - var dependencies []flowkitConfig.Dependency // Loop standard contracts and add them to the dependencies if selected - for i, contract := range sc.All() { - if _, ok := final.Selected[i]; ok { + for _, contract := range sc.All() { + if slices.Contains(selectedContractNames, contract.Name) { dependencies = append(dependencies, flowkitConfig.Dependency{ Name: contract.Name, Source: flowkitConfig.Source{ From 4d4773c8bdca05c4c3978baa45bf4a41705962b6 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Wed, 17 Apr 2024 15:33:23 -0700 Subject: [PATCH 23/86] Make models private --- internal/prompt/select-options.go | 46 +++++++++++++++---------------- internal/prompt/text-input.go | 25 +++++++++-------- 2 files changed, 36 insertions(+), 35 deletions(-) diff --git a/internal/prompt/select-options.go b/internal/prompt/select-options.go index 029249229..63c4c06e1 100644 --- a/internal/prompt/select-options.go +++ b/internal/prompt/select-options.go @@ -25,28 +25,28 @@ import ( tea "github.com/charmbracelet/bubbletea" ) -// OptionSelectModel represents the prompt state -type OptionSelectModel struct { +// optionSelectModel represents the prompt state but is now private +type optionSelectModel struct { message string // message to display cursor int // position of the cursor - Choices []string // items on the list - Selected map[int]struct{} // which items are selected + choices []string // items on the list + selected map[int]struct{} // which items are selected } -// SelectOptions creates a prompt for selecting multiple options -func SelectOptions(options []string, message string) OptionSelectModel { - return OptionSelectModel{ +// selectOptions creates a prompt for selecting multiple options but is now private +func selectOptions(options []string, message string) optionSelectModel { + return optionSelectModel{ message: message, - Choices: options, - Selected: make(map[int]struct{}), + choices: options, + selected: make(map[int]struct{}), } } -func (m OptionSelectModel) Init() tea.Cmd { +func (m optionSelectModel) Init() tea.Cmd { return nil // No initial command } -func (m OptionSelectModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { +func (m optionSelectModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { switch msg := msg.(type) { case tea.KeyMsg: switch msg.Type { @@ -59,16 +59,16 @@ func (m OptionSelectModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { } case tea.KeyDown: // Navigate down - if m.cursor < len(m.Choices)-1 { + if m.cursor < len(m.choices)-1 { m.cursor++ } case tea.KeySpace: // Select an item // Toggle selection - if _, ok := m.Selected[m.cursor]; ok { - delete(m.Selected, m.cursor) // Deselect + if _, ok := m.selected[m.cursor]; ok { + delete(m.selected, m.cursor) // Deselect } else { - m.Selected[m.cursor] = struct{}{} // Select + m.selected[m.cursor] = struct{}{} // Select } case tea.KeyEnter: // Confirm selection @@ -79,18 +79,18 @@ func (m OptionSelectModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { return m, nil } -func (m OptionSelectModel) View() string { +func (m optionSelectModel) View() string { var b strings.Builder b.WriteString(fmt.Sprintf("%s.\n", m.message)) b.WriteString("Use arrow keys to navigate, space to select, enter to confirm, q to quit:\n\n") - for i, choice := range m.Choices { + for i, choice := range m.choices { if m.cursor == i { b.WriteString("> ") } else { b.WriteString(" ") } // Mark selected items - if _, ok := m.Selected[i]; ok { + if _, ok := m.selected[i]; ok { b.WriteString("[x] ") } else { b.WriteString("[ ] ") @@ -100,19 +100,19 @@ func (m OptionSelectModel) View() string { return b.String() } -// RunSelectOptions handles creating, running the select options prompt, and returning selected choices +// RunSelectOptions remains public and is the interface for external usage. func RunSelectOptions(options []string, message string) ([]string, error) { - model := SelectOptions(options, message) + model := selectOptions(options, message) p := tea.NewProgram(model) finalModel, err := p.Run() if err != nil { return nil, err } - final := finalModel.(OptionSelectModel) + final := finalModel.(optionSelectModel) selectedChoices := make([]string, 0) - for i := range final.Selected { - selectedChoices = append(selectedChoices, final.Choices[i]) + for i := range final.selected { + selectedChoices = append(selectedChoices, final.choices[i]) } return selectedChoices, nil } diff --git a/internal/prompt/text-input.go b/internal/prompt/text-input.go index 7889ea5f5..147e78b19 100644 --- a/internal/prompt/text-input.go +++ b/internal/prompt/text-input.go @@ -6,31 +6,32 @@ import ( tea "github.com/charmbracelet/bubbletea" ) -type TextInputModel struct { +// textInputModel is now private, only accessible within the 'prompt' package. +type textInputModel struct { textInput textinput.Model err error customMsg string } -// NewTextInput initializes a new text input model with a custom message -func NewTextInput(customMsg, placeholder string) TextInputModel { +// newTextInput is a private function that initializes a new text input model. +func newTextInput(customMsg, placeholder string) textInputModel { ti := textinput.New() ti.Placeholder = placeholder ti.Focus() ti.CharLimit = 256 ti.Width = 30 - return TextInputModel{ + return textInputModel{ textInput: ti, customMsg: customMsg, } } -func (m TextInputModel) Init() tea.Cmd { +func (m textInputModel) Init() tea.Cmd { return textinput.Blink } -func (m TextInputModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { +func (m textInputModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { switch msg := msg.(type) { case tea.KeyMsg: switch msg.Type { @@ -45,19 +46,19 @@ func (m TextInputModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { return m, nil } -func (m TextInputModel) View() string { +func (m textInputModel) View() string { return fmt.Sprintf("%s\n\n%s\n\n%s", m.customMsg, m.textInput.View(), "(Enter to submit, Esc to quit)") } -// RunTextInput handles running the text input and retrieving the result +// RunTextInput remains public. It's the entry point for external usage. func RunTextInput(customMsg, placeholder string) (string, error) { - model := NewTextInput(customMsg, placeholder) + model := newTextInput(customMsg, placeholder) p := tea.NewProgram(model) if finalModel, err := p.Run(); err != nil { - return "", err // return the error to handle it outside if necessary + return "", err } else { - final := finalModel.(TextInputModel) - return final.textInput.Value(), nil // directly return the input value + final := finalModel.(textInputModel) + return final.textInput.Value(), nil } } From 274a69884c5eb516b6fe5ae7de3afe724eb3a8f4 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Wed, 17 Apr 2024 15:41:54 -0700 Subject: [PATCH 24/86] Fix imports --- internal/prompt/text-input.go | 1 + internal/super/setup.go | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/internal/prompt/text-input.go b/internal/prompt/text-input.go index 147e78b19..ccb88cce3 100644 --- a/internal/prompt/text-input.go +++ b/internal/prompt/text-input.go @@ -2,6 +2,7 @@ package prompt import ( "fmt" + "github.com/charmbracelet/bubbles/textinput" tea "github.com/charmbracelet/bubbletea" ) diff --git a/internal/super/setup.go b/internal/super/setup.go index cedb04fa8..e1ce6c2b5 100644 --- a/internal/super/setup.go +++ b/internal/super/setup.go @@ -21,12 +21,13 @@ package super import ( "bytes" "fmt" - flowsdk "github.com/onflow/flow-go-sdk" - "golang.org/x/exp/slices" "io" "os" "path/filepath" + flowsdk "github.com/onflow/flow-go-sdk" + "golang.org/x/exp/slices" + "github.com/onflow/flow-cli/internal/prompt" "github.com/onflow/flow-go/fvm/systemcontracts" From 6fe02787d88a01db6ef2670f180135ace770635e Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Wed, 17 Apr 2024 15:46:10 -0700 Subject: [PATCH 25/86] Add header --- internal/prompt/text-input.go | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/internal/prompt/text-input.go b/internal/prompt/text-input.go index ccb88cce3..16e89b22c 100644 --- a/internal/prompt/text-input.go +++ b/internal/prompt/text-input.go @@ -1,3 +1,21 @@ +/* + * Flow CLI + * + * Copyright 2019 Dapper Labs, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package prompt import ( From f0a09d42bf8aa342d3b25cb3cc04bc114f53c57f Mon Sep 17 00:00:00 2001 From: Chase Fleming Date: Mon, 22 Apr 2024 14:01:50 -0700 Subject: [PATCH 26/86] Merge master into feature branch (#1534) * Bump codecov/codecov-action from 1 to 4 Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 1 to 4. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/v1...v4) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] * Bump actions/add-to-project from 0.4.1 to 0.6.1 Bumps [actions/add-to-project](https://github.com/actions/add-to-project) from 0.4.1 to 0.6.1. - [Release notes](https://github.com/actions/add-to-project/releases) - [Commits](https://github.com/actions/add-to-project/compare/v0.4.1...v0.6.1) --- updated-dependencies: - dependency-name: actions/add-to-project dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Update Flow dependencies to latest version (#1509) * Update to latest Cadence Language Server (#1513) * Bump google.golang.org/grpc from 1.63.0 to 1.63.2 (#1515) Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.63.0 to 1.63.2. - [Release notes](https://github.com/grpc/grpc-go/releases) - [Commits](https://github.com/grpc/grpc-go/compare/v1.63.0...v1.63.2) --- updated-dependencies: - dependency-name: google.golang.org/grpc dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump actions/add-to-project from 0.6.1 to 1.0.1 (#1514) Bumps [actions/add-to-project](https://github.com/actions/add-to-project) from 0.6.1 to 1.0.1. - [Release notes](https://github.com/actions/add-to-project/releases) - [Commits](https://github.com/actions/add-to-project/compare/v0.6.1...v1.0.1) --- updated-dependencies: - dependency-name: actions/add-to-project dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jordan Ribbink * Bump version to v1.17.1 * Fix embedded flags issue when running Dependency Manager flags manually (#1530) * Fix embedded flags issue * Run lint fix * Use sconfig * Run goimport fix --------- Co-authored-by: Chase Fleming <1666730+chasefleming@users.noreply.github.com> * Change flags anme --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jordan Ribbink Co-authored-by: Chase Fleming <1666730+chasefleming@users.noreply.github.com> --- .../workflows/add-issues-to-devx-project.yml | 2 +- go.mod | 2 +- go.sum | 4 ++-- internal/dependencymanager/add.go | 20 +++++++++++++------ .../dependencymanager/dependencyinstaller.go | 20 +++++++++++++++++-- internal/dependencymanager/install.go | 2 +- internal/super/setup.go | 2 +- version.txt | 2 +- 8 files changed, 39 insertions(+), 15 deletions(-) diff --git a/.github/workflows/add-issues-to-devx-project.yml b/.github/workflows/add-issues-to-devx-project.yml index 44cd3e14c..d00e3014c 100644 --- a/.github/workflows/add-issues-to-devx-project.yml +++ b/.github/workflows/add-issues-to-devx-project.yml @@ -10,7 +10,7 @@ jobs: name: Add issue to project runs-on: ubuntu-latest steps: - - uses: actions/add-to-project@v0.6.1 + - uses: actions/add-to-project@v1.0.1 with: project-url: https://github.com/orgs/onflow/projects/13 github-token: ${{ secrets.GH_ACTION_FOR_PROJECTS }} diff --git a/go.mod b/go.mod index 4be918fb7..1b8b56eee 100644 --- a/go.mod +++ b/go.mod @@ -34,7 +34,7 @@ require ( github.com/spf13/viper v1.16.0 github.com/stretchr/testify v1.8.4 golang.org/x/exp v0.0.0-20240119083558-1b970713d09a - google.golang.org/grpc v1.63.0 + google.golang.org/grpc v1.63.2 ) require ( diff --git a/go.sum b/go.sum index 5941bb602..b016a3f01 100644 --- a/go.sum +++ b/go.sum @@ -1846,8 +1846,8 @@ google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQ google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= -google.golang.org/grpc v1.63.0 h1:WjKe+dnvABXyPJMD7KDNLxtoGk5tgk+YFWN6cBWjZE8= -google.golang.org/grpc v1.63.0/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA= +google.golang.org/grpc v1.63.2 h1:MUeiw1B2maTVZthpU5xvASfTh3LDbxHd6IJ6QQVU+xM= +google.golang.org/grpc v1.63.2/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= diff --git a/internal/dependencymanager/add.go b/internal/dependencymanager/add.go index 1542628f1..861895489 100644 --- a/internal/dependencymanager/add.go +++ b/internal/dependencymanager/add.go @@ -30,11 +30,13 @@ import ( ) type addFlagsCollection struct { - DependencyManagerFlagsCollection - name string `default:"" flag:"name" info:"Name of the dependency"` + *Flags + name string } -var addFlags = addFlagsCollection{} +var addFlags = addFlagsCollection{ + Flags: &Flags{}, +} var addCommand = &command.Command{ Cmd: &cobra.Command{ @@ -43,8 +45,14 @@ var addCommand = &command.Command{ Example: "flow dependencies add testnet://0afe396ebc8eee65.FlowToken", Args: cobra.ExactArgs(1), }, - Flags: &addFlags, - RunS: add, + RunS: add, +} + +func init() { + // Add common flags. + addFlags.Flags.AddToCommand(addCommand.Cmd) + // Add command-specific flags. + addCommand.Cmd.Flags().StringVar(&addFlags.name, "name", "", "Name of the dependency") } func add( @@ -58,7 +66,7 @@ func add( dep := args[0] - installer, err := NewDependencyInstaller(logger, state, true, "", addFlags.DependencyManagerFlagsCollection) + installer, err := NewDependencyInstaller(logger, state, true, "", *addFlags.Flags) if err != nil { logger.Error(fmt.Sprintf("Error: %v", err)) return nil, err diff --git a/internal/dependencymanager/dependencyinstaller.go b/internal/dependencymanager/dependencyinstaller.go index d2cee2731..b6482e7ab 100644 --- a/internal/dependencymanager/dependencyinstaller.go +++ b/internal/dependencymanager/dependencyinstaller.go @@ -26,7 +26,12 @@ import ( "os" "path/filepath" + "github.com/psiemens/sconfig" + "github.com/onflow/flow-cli/internal/prompt" + "github.com/onflow/flow-cli/internal/util" + + "github.com/spf13/cobra" "github.com/onflow/flow-go/fvm/systemcontracts" flowGo "github.com/onflow/flow-go/model/flow" @@ -69,11 +74,22 @@ func (cl *categorizedLogs) LogAll(logger output.Logger) { } } -type DependencyManagerFlagsCollection struct { +type Flags struct { skipDeployments bool `default:"false" flag:"skip-deployments" info:"Skip adding the dependency to deployments"` skipAlias bool `default:"false" flag:"skip-alias" info:"Skip prompting for an alias"` } +func (f *Flags) AddToCommand(cmd *cobra.Command) { + err := sconfig.New(f). + FromEnvironment(util.EnvPrefix). + BindFlags(cmd.Flags()). + Parse() + + if err != nil { + panic(err) + } +} + type DependencyInstaller struct { Gateways map[string]gateway.Gateway Logger output.Logger @@ -86,7 +102,7 @@ type DependencyInstaller struct { } // NewDependencyInstaller creates a new instance of DependencyInstaller -func NewDependencyInstaller(logger output.Logger, state *flowkit.State, saveState bool, targetDir string, flags DependencyManagerFlagsCollection) (*DependencyInstaller, error) { +func NewDependencyInstaller(logger output.Logger, state *flowkit.State, saveState bool, targetDir string, flags Flags) (*DependencyInstaller, error) { emulatorGateway, err := gateway.NewGrpcGateway(config.EmulatorNetwork) if err != nil { return nil, fmt.Errorf("error creating emulator gateway: %v", err) diff --git a/internal/dependencymanager/install.go b/internal/dependencymanager/install.go index 4f1a72500..53fbbb177 100644 --- a/internal/dependencymanager/install.go +++ b/internal/dependencymanager/install.go @@ -29,7 +29,7 @@ import ( "github.com/onflow/flow-cli/internal/command" ) -var installFlags = DependencyManagerFlagsCollection{} +var installFlags = Flags{} var installCommand = &command.Command{ Cmd: &cobra.Command{ diff --git a/internal/super/setup.go b/internal/super/setup.go index e1ce6c2b5..1b24442c4 100644 --- a/internal/super/setup.go +++ b/internal/super/setup.go @@ -184,7 +184,7 @@ func create( } // Add the selected core contracts as dependencies - installer, err := dependencymanager.NewDependencyInstaller(logger, state, false, targetDir, dependencymanager.DependencyManagerFlagsCollection{}) + installer, err := dependencymanager.NewDependencyInstaller(logger, state, false, targetDir, dependencymanager.Flags{}) if err != nil { logger.Error(fmt.Sprintf("Error: %v", err)) return nil, err diff --git a/version.txt b/version.txt index 07c3efad8..7893098b6 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -v1.17.0 +v1.17.1 From 8f00ed879500cb0122b0af750e4c8064cf4b3940 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Wed, 1 May 2024 12:14:06 -0700 Subject: [PATCH 27/86] Create project in temp directory then move to target directory if successful --- internal/super/setup.go | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/internal/super/setup.go b/internal/super/setup.go index 1b24442c4..6c0c6010a 100644 --- a/internal/super/setup.go +++ b/internal/super/setup.go @@ -116,12 +116,26 @@ func create( } } + // Create a temp directory which will later be moved to the target directory if successful + tempDir, err := os.MkdirTemp("", "flow-cli-*") + if err != nil { + return nil, fmt.Errorf("failed to create temp directory: %w", err) + } + + defer func() { + if err := os.RemoveAll(tempDir); err != nil { + logger.Error(fmt.Sprintf("Failed to remove %s: %v", tempDir, err)) + } + }() + + fmt.Printf("Creating project in %s\n", tempDir) + params := config.InitConfigParameters{ ServiceKeySigAlgo: "ECDSA_P256", ServiceKeyHashAlgo: "SHA3_256", Reset: false, Global: false, - TargetDirectory: targetDir, + TargetDirectory: tempDir, } state, err := config.InitializeConfiguration(params, logger, state.ReaderWriter()) if err != nil { @@ -134,7 +148,7 @@ func create( // cadence/transactions/DefaultTransaction.cdc // cadence/tests/DefaultContract_test.cdc - directoryPath := filepath.Join(targetDir, "cadence") + directoryPath := filepath.Join(tempDir, "cadence") _, err = generateNew([]string{"DefaultContract"}, "contract", directoryPath, logger, state) if err != nil { @@ -184,7 +198,7 @@ func create( } // Add the selected core contracts as dependencies - installer, err := dependencymanager.NewDependencyInstaller(logger, state, false, targetDir, dependencymanager.Flags{}) + installer, err := dependencymanager.NewDependencyInstaller(logger, state, false, tempDir, dependencymanager.Flags{}) if err != nil { logger.Error(fmt.Sprintf("Error: %v", err)) return nil, err @@ -195,16 +209,26 @@ func create( return nil, err } - err = state.Save(filepath.Join(targetDir, "flow.json")) + err = state.Save(filepath.Join(tempDir, "flow.json")) if err != nil { return nil, err } + // Move the temp directory to the target directory + err = os.Rename(tempDir, targetDir) + if err != nil { + return nil, fmt.Errorf("failed to move temp directory to target directory: %w", err) + } + } return &setupResult{targetDir: targetDir}, nil } +// getTargetDirectory checks if the specified directory path is suitable for use. +// It verifies that the path points to an existing, empty directory. +// If the directory does not exist, the function returns the path without error, +// indicating that the path is available for use (assuming creation is handled elsewhere). func getTargetDirectory(directory string) (string, error) { pwd, err := os.Getwd() if err != nil { From 3d435c11f448dec5b027c1378cfe7e95e93b6ce9 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Wed, 1 May 2024 12:18:56 -0700 Subject: [PATCH 28/86] Move scaffold logic to its own function --- internal/super/scaffolds.go | 27 +++++++++++++++++++++++++++ internal/super/setup.go | 20 +++++--------------- 2 files changed, 32 insertions(+), 15 deletions(-) diff --git a/internal/super/scaffolds.go b/internal/super/scaffolds.go index d882f437c..26e68ffed 100644 --- a/internal/super/scaffolds.go +++ b/internal/super/scaffolds.go @@ -46,6 +46,33 @@ type scaffold struct { Type string `json:"type"` } +func handleScaffold( + projectName string, + logger output.Logger, +) (string, error) { + targetDir, err := getTargetDirectory(projectName) + if err != nil { + return "", err + } + + selectedScaffold, err := selectScaffold(logger) + if err != nil { + return "", fmt.Errorf("error selecting scaffold %w", err) + } + + logger.StartProgress(fmt.Sprintf("Creating your project %s", targetDir)) + defer logger.StopProgress() + + if selectedScaffold != nil { + err = cloneScaffold(targetDir, *selectedScaffold) + if err != nil { + return "", fmt.Errorf("failed creating scaffold %w", err) + } + } + + return targetDir, nil +} + func selectScaffold(logger output.Logger) (*scaffold, error) { scaffolds, err := getScaffolds() if err != nil { diff --git a/internal/super/setup.go b/internal/super/setup.go index 6c0c6010a..ffcd572e9 100644 --- a/internal/super/setup.go +++ b/internal/super/setup.go @@ -77,24 +77,14 @@ func create( var err error if setupFlags.Scaffold || setupFlags.ScaffoldID != 0 { - targetDir, err = getTargetDirectory(args[0]) - if err != nil { - return nil, err + // Error if no project name is given + if len(args) < 1 || args[0] == "" { + return nil, fmt.Errorf("no project name provided") } - selectedScaffold, err := selectScaffold(logger) + targetDir, err = handleScaffold(args[0], logger) if err != nil { - return nil, fmt.Errorf("error selecting scaffold %w", err) - } - - logger.StartProgress(fmt.Sprintf("Creating your project %s", targetDir)) - defer logger.StopProgress() - - if selectedScaffold != nil { - err = cloneScaffold(targetDir, *selectedScaffold) - if err != nil { - return nil, fmt.Errorf("failed creating scaffold %w", err) - } + return nil, err } } else { // Ask for project name if not given From f007474d729baf5a1be7a40362e60236bd30ba5c Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Wed, 1 May 2024 12:25:38 -0700 Subject: [PATCH 29/86] Move interactive setup to its own function --- internal/super/setup.go | 213 +++++++++++++++++++++------------------- 1 file changed, 114 insertions(+), 99 deletions(-) diff --git a/internal/super/setup.go b/internal/super/setup.go index ffcd572e9..f314464f2 100644 --- a/internal/super/setup.go +++ b/internal/super/setup.go @@ -87,132 +87,147 @@ func create( return nil, err } } else { - // Ask for project name if not given - if len(args) < 1 { - userInput, err := prompt.RunTextInput("Enter the name of your project", "Type your project name here...") - if err != nil { - fmt.Printf("Error running project name: %v\n", err) - os.Exit(1) - } - - targetDir, err = getTargetDirectory(userInput) - if err != nil { - return nil, err - } - } else { - targetDir, err = getTargetDirectory(args[0]) - if err != nil { - return nil, err - } - } - - // Create a temp directory which will later be moved to the target directory if successful - tempDir, err := os.MkdirTemp("", "flow-cli-*") + targetDir, err = startInteractiveSetup(args, logger, state) if err != nil { - return nil, fmt.Errorf("failed to create temp directory: %w", err) + return nil, err } + } - defer func() { - if err := os.RemoveAll(tempDir); err != nil { - logger.Error(fmt.Sprintf("Failed to remove %s: %v", tempDir, err)) - } - }() + return &setupResult{targetDir: targetDir}, nil +} - fmt.Printf("Creating project in %s\n", tempDir) +func startInteractiveSetup( + args []string, + logger output.Logger, + state *flowkit.State, +) (string, error) { + var targetDir string + var err error - params := config.InitConfigParameters{ - ServiceKeySigAlgo: "ECDSA_P256", - ServiceKeyHashAlgo: "SHA3_256", - Reset: false, - Global: false, - TargetDirectory: tempDir, - } - state, err := config.InitializeConfiguration(params, logger, state.ReaderWriter()) + // Ask for project name if not given + if len(args) < 1 { + userInput, err := prompt.RunTextInput("Enter the name of your project", "Type your project name here...") if err != nil { - return nil, fmt.Errorf("failed to initialize configuration: %w", err) + fmt.Printf("Error running project name: %v\n", err) + os.Exit(1) } - // Generate standard cadence files - // cadence/contracts/DefaultContract.cdc - // cadence/scripts/DefaultScript.cdc - // cadence/transactions/DefaultTransaction.cdc - // cadence/tests/DefaultContract_test.cdc - - directoryPath := filepath.Join(tempDir, "cadence") - - _, err = generateNew([]string{"DefaultContract"}, "contract", directoryPath, logger, state) + targetDir, err = getTargetDirectory(userInput) if err != nil { - return nil, err + return "", err } - - _, err = generateNew([]string{"DefaultScript"}, "script", directoryPath, logger, state) + } else { + targetDir, err = getTargetDirectory(args[0]) if err != nil { - return nil, err + return "", err } + } - _, err = generateNew([]string{"DefaultTransaction"}, "transaction", directoryPath, logger, state) - if err != nil { - return nil, err + // Create a temp directory which will later be moved to the target directory if successful + tempDir, err := os.MkdirTemp("", "flow-cli-*") + if err != nil { + return "", fmt.Errorf("failed to create temp directory: %w", err) + } + + defer func() { + if err := os.RemoveAll(tempDir); err != nil { + logger.Error(fmt.Sprintf("Failed to remove %s: %v", tempDir, err)) } + }() - // Prompt to ask which core contracts should be installed - sc := systemcontracts.SystemContractsForChain(flowGo.Mainnet) - promptMessage := "Select the core contracts you'd like to install:" + fmt.Printf("Creating project in %s\n", tempDir) - contractNames := make([]string, 0) + params := config.InitConfigParameters{ + ServiceKeySigAlgo: "ECDSA_P256", + ServiceKeyHashAlgo: "SHA3_256", + Reset: false, + Global: false, + TargetDirectory: tempDir, + } + state, err = config.InitializeConfiguration(params, logger, state.ReaderWriter()) + if err != nil { + return "", fmt.Errorf("failed to initialize configuration: %w", err) + } - for _, contract := range sc.All() { - contractNames = append(contractNames, contract.Name) - } + // Generate standard cadence files + // cadence/contracts/DefaultContract.cdc + // cadence/scripts/DefaultScript.cdc + // cadence/transactions/DefaultTransaction.cdc + // cadence/tests/DefaultContract_test.cdc - selectedContractNames, err := prompt.RunSelectOptions(contractNames, promptMessage) - if err != nil { - fmt.Printf("Error running dependency selection: %v\n", err) - os.Exit(1) - } + directoryPath := filepath.Join(tempDir, "cadence") - var dependencies []flowkitConfig.Dependency - - // Loop standard contracts and add them to the dependencies if selected - for _, contract := range sc.All() { - if slices.Contains(selectedContractNames, contract.Name) { - dependencies = append(dependencies, flowkitConfig.Dependency{ - Name: contract.Name, - Source: flowkitConfig.Source{ - NetworkName: flowkitConfig.MainnetNetwork.Name, - Address: flowsdk.HexToAddress(contract.Address.String()), - ContractName: contract.Name, - }, - }) - } - } + _, err = generateNew([]string{"DefaultContract"}, "contract", directoryPath, logger, state) + if err != nil { + return "", err + } - // Add the selected core contracts as dependencies - installer, err := dependencymanager.NewDependencyInstaller(logger, state, false, tempDir, dependencymanager.Flags{}) - if err != nil { - logger.Error(fmt.Sprintf("Error: %v", err)) - return nil, err - } + _, err = generateNew([]string{"DefaultScript"}, "script", directoryPath, logger, state) + if err != nil { + return "", err + } - if err := installer.AddMany(dependencies); err != nil { - logger.Error(fmt.Sprintf("Error: %v", err)) - return nil, err - } + _, err = generateNew([]string{"DefaultTransaction"}, "transaction", directoryPath, logger, state) + if err != nil { + return "", err + } - err = state.Save(filepath.Join(tempDir, "flow.json")) - if err != nil { - return nil, err - } + // Prompt to ask which core contracts should be installed + sc := systemcontracts.SystemContractsForChain(flowGo.Mainnet) + promptMessage := "Select the core contracts you'd like to install:" - // Move the temp directory to the target directory - err = os.Rename(tempDir, targetDir) - if err != nil { - return nil, fmt.Errorf("failed to move temp directory to target directory: %w", err) + contractNames := make([]string, 0) + + for _, contract := range sc.All() { + contractNames = append(contractNames, contract.Name) + } + + selectedContractNames, err := prompt.RunSelectOptions(contractNames, promptMessage) + if err != nil { + fmt.Printf("Error running dependency selection: %v\n", err) + os.Exit(1) + } + + var dependencies []flowkitConfig.Dependency + + // Loop standard contracts and add them to the dependencies if selected + for _, contract := range sc.All() { + if slices.Contains(selectedContractNames, contract.Name) { + dependencies = append(dependencies, flowkitConfig.Dependency{ + Name: contract.Name, + Source: flowkitConfig.Source{ + NetworkName: flowkitConfig.MainnetNetwork.Name, + Address: flowsdk.HexToAddress(contract.Address.String()), + ContractName: contract.Name, + }, + }) } + } + // Add the selected core contracts as dependencies + installer, err := dependencymanager.NewDependencyInstaller(logger, state, false, tempDir, dependencymanager.Flags{}) + if err != nil { + logger.Error(fmt.Sprintf("Error: %v", err)) + return "", err } - return &setupResult{targetDir: targetDir}, nil + if err := installer.AddMany(dependencies); err != nil { + logger.Error(fmt.Sprintf("Error: %v", err)) + return "", err + } + + err = state.Save(filepath.Join(tempDir, "flow.json")) + if err != nil { + return "", err + } + + // Move the temp directory to the target directory + err = os.Rename(tempDir, targetDir) + if err != nil { + return "", fmt.Errorf("failed to move temp directory to target directory: %w", err) + } + + return targetDir, nil } // getTargetDirectory checks if the specified directory path is suitable for use. From 45022d1731044cae64a280112ed291364bddff36 Mon Sep 17 00:00:00 2001 From: Chase Fleming Date: Wed, 1 May 2024 13:03:11 -0700 Subject: [PATCH 30/86] Update internal/super/setup.go Co-authored-by: Jordan Ribbink --- internal/super/setup.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/super/setup.go b/internal/super/setup.go index f314464f2..82e69faba 100644 --- a/internal/super/setup.go +++ b/internal/super/setup.go @@ -135,7 +135,7 @@ func startInteractiveSetup( } }() - fmt.Printf("Creating project in %s\n", tempDir) + fmt.Printf("Creating project in %s\n", targetDir) params := config.InitConfigParameters{ ServiceKeySigAlgo: "ECDSA_P256", From 854a60c67a24cab1c7a05abfd407861d4796e760 Mon Sep 17 00:00:00 2001 From: Chase Fleming Date: Wed, 1 May 2024 13:03:42 -0700 Subject: [PATCH 31/86] Update internal/super/setup.go Co-authored-by: Jordan Ribbink --- internal/super/setup.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/internal/super/setup.go b/internal/super/setup.go index 82e69faba..714240959 100644 --- a/internal/super/setup.go +++ b/internal/super/setup.go @@ -184,8 +184,7 @@ func startInteractiveSetup( selectedContractNames, err := prompt.RunSelectOptions(contractNames, promptMessage) if err != nil { - fmt.Printf("Error running dependency selection: %v\n", err) - os.Exit(1) + return "", fmt.Errorf("error running dependency selection: %v\n", err) } var dependencies []flowkitConfig.Dependency From 0ce2016652ebc608d31447f84db936d45c0fe5af Mon Sep 17 00:00:00 2001 From: Chase Fleming Date: Wed, 1 May 2024 13:04:27 -0700 Subject: [PATCH 32/86] Update internal/super/setup.go Co-authored-by: Jordan Ribbink --- internal/super/setup.go | 1 - 1 file changed, 1 deletion(-) diff --git a/internal/super/setup.go b/internal/super/setup.go index 714240959..6aff10b84 100644 --- a/internal/super/setup.go +++ b/internal/super/setup.go @@ -211,7 +211,6 @@ func startInteractiveSetup( } if err := installer.AddMany(dependencies); err != nil { - logger.Error(fmt.Sprintf("Error: %v", err)) return "", err } From 7cddd11b2beac31bb1ff03bbcebfb9fa99c9a908 Mon Sep 17 00:00:00 2001 From: Chase Fleming Date: Wed, 1 May 2024 13:04:34 -0700 Subject: [PATCH 33/86] Update internal/super/setup.go Co-authored-by: Jordan Ribbink --- internal/super/setup.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/internal/super/setup.go b/internal/super/setup.go index 6aff10b84..53ff7d721 100644 --- a/internal/super/setup.go +++ b/internal/super/setup.go @@ -108,8 +108,7 @@ func startInteractiveSetup( if len(args) < 1 { userInput, err := prompt.RunTextInput("Enter the name of your project", "Type your project name here...") if err != nil { - fmt.Printf("Error running project name: %v\n", err) - os.Exit(1) + return nil, fmt.Errorf("error running project name: %v", err) } targetDir, err = getTargetDirectory(userInput) From be7805afd1763511dc809b89b906ac91acf18870 Mon Sep 17 00:00:00 2001 From: Chase Fleming Date: Wed, 1 May 2024 13:04:41 -0700 Subject: [PATCH 34/86] Update internal/super/setup.go Co-authored-by: Jordan Ribbink --- internal/super/setup.go | 1 - 1 file changed, 1 deletion(-) diff --git a/internal/super/setup.go b/internal/super/setup.go index 53ff7d721..c30df8b9e 100644 --- a/internal/super/setup.go +++ b/internal/super/setup.go @@ -205,7 +205,6 @@ func startInteractiveSetup( // Add the selected core contracts as dependencies installer, err := dependencymanager.NewDependencyInstaller(logger, state, false, tempDir, dependencymanager.Flags{}) if err != nil { - logger.Error(fmt.Sprintf("Error: %v", err)) return "", err } From 3d1b54ea0d196b8501bd9b0933cf765438066780 Mon Sep 17 00:00:00 2001 From: Jordan Ribbink Date: Wed, 1 May 2024 13:06:18 -0700 Subject: [PATCH 35/86] nil fix --- internal/super/setup.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/super/setup.go b/internal/super/setup.go index c30df8b9e..adc3dd5be 100644 --- a/internal/super/setup.go +++ b/internal/super/setup.go @@ -108,7 +108,7 @@ func startInteractiveSetup( if len(args) < 1 { userInput, err := prompt.RunTextInput("Enter the name of your project", "Type your project name here...") if err != nil { - return nil, fmt.Errorf("error running project name: %v", err) + return "", fmt.Errorf("error running project name: %v", err) } targetDir, err = getTargetDirectory(userInput) From efd1eea2aec1f8ca44bd04ad267d0dbacafdc65c Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Wed, 1 May 2024 13:07:20 -0700 Subject: [PATCH 36/86] Remove print --- internal/super/setup.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/internal/super/setup.go b/internal/super/setup.go index c30df8b9e..0a5a515e5 100644 --- a/internal/super/setup.go +++ b/internal/super/setup.go @@ -134,8 +134,6 @@ func startInteractiveSetup( } }() - fmt.Printf("Creating project in %s\n", targetDir) - params := config.InitConfigParameters{ ServiceKeySigAlgo: "ECDSA_P256", ServiceKeyHashAlgo: "SHA3_256", From 2b2d1a0fea358b58a670cdf0efb6a0dfbb9dab74 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Thu, 2 May 2024 16:30:12 -0700 Subject: [PATCH 37/86] Disable logs and refactor to Generator --- internal/super/generate.go | 149 ++++++++++++++++++++------------ internal/super/generate_test.go | 31 ++++--- internal/super/setup.go | 15 ++-- 3 files changed, 121 insertions(+), 74 deletions(-) diff --git a/internal/super/generate.go b/internal/super/generate.go index 2dee91770..739393b30 100644 --- a/internal/super/generate.go +++ b/internal/super/generate.go @@ -102,7 +102,13 @@ func generateContract( _ flowkit.Services, state *flowkit.State, ) (result command.Result, err error) { - return generateNew(args, "contract", generateFlags.Directory, logger, state) + if len(args) < 1 { + return nil, fmt.Errorf("invalid number of arguments") + } + + generator := NewGenerator(map[string]string{"contract": args[0]}, "cadence", state, logger) + err = generator.Create() + return nil, err } func generateTransaction( @@ -112,7 +118,13 @@ func generateTransaction( _ flowkit.Services, state *flowkit.State, ) (result command.Result, err error) { - return generateNew(args, "transaction", generateFlags.Directory, logger, state) + if len(args) < 1 { + return nil, fmt.Errorf("invalid number of arguments") + } + + generator := NewGenerator(map[string]string{"transaction": args[0]}, "cadence", state, logger) + err = generator.Create() + return nil, err } func generateScript( @@ -122,7 +134,13 @@ func generateScript( _ flowkit.Services, state *flowkit.State, ) (result command.Result, err error) { - return generateNew(args, "script", generateFlags.Directory, logger, state) + if len(args) < 1 { + return nil, fmt.Errorf("invalid number of arguments") + } + + generator := NewGenerator(map[string]string{"script": args[0]}, "cadence", state, logger) + err = generator.Create() + return nil, err } func addCDCExtension(name string) string { @@ -136,40 +154,36 @@ func stripCDCExtension(name string) string { return strings.TrimSuffix(name, filepath.Ext(name)) } -// processTemplate reads a template file from the embedded filesystem and processes it with the provided data -// If you don't need to provide data, pass nil -func processTemplate(templatePath string, data map[string]interface{}) (string, error) { - templateData, err := templatesFS.ReadFile(templatePath) - if err != nil { - return "", fmt.Errorf("failed to read template file: %w", err) - } +type Generator struct { + TypeNames map[string]string // Map of template types to their specific names + Directory string + State *flowkit.State + Logger output.Logger + DisableLogs bool +} - tmpl, err := template.New("template").Parse(string(templateData)) - if err != nil { - return "", fmt.Errorf("failed to parse template: %w", err) +func NewGenerator(typeNames map[string]string, directory string, state *flowkit.State, logger output.Logger) *Generator { + return &Generator{ + TypeNames: typeNames, + Directory: directory, + State: state, + Logger: logger, } +} - var executedTemplate bytes.Buffer - // Execute the template with the provided data or nil if no data is needed - if err = tmpl.Execute(&executedTemplate, data); err != nil { - return "", fmt.Errorf("failed to execute template: %w", err) +func (g *Generator) Create() error { + for templateType, name := range g.TypeNames { + err := g.generate(templateType, name) + if err != nil { + return err + } } - - return executedTemplate.String(), nil + return nil } -func generateNew( - args []string, - templateType string, - directory string, - logger output.Logger, - state *flowkit.State, -) (result command.Result, err error) { - if len(args) < 1 { - return nil, fmt.Errorf("invalid number of arguments") - } +func (g *Generator) generate(templateType, name string) error { - name := stripCDCExtension(args[0]) + name = stripCDCExtension(name) filename := addCDCExtension(name) var fileToWrite string @@ -177,9 +191,10 @@ func generateNew( var rootDir = "cadence" var basePath string var testsBasePath = "tests" + var err error - if directory != "" { - rootDir = directory + if g.Directory != "" { + rootDir = g.Directory } switch templateType { @@ -188,68 +203,70 @@ func generateNew( nameData := map[string]interface{}{"Name": name} fileToWrite, err = processTemplate("templates/contract_init.cdc.tmpl", nameData) if err != nil { - return nil, fmt.Errorf("error generating contract template: %w", err) + return fmt.Errorf("error generating contract template: %w", err) } testFileToWrite, err = processTemplate("templates/contract_init_test.cdc.tmpl", nameData) if err != nil { - return nil, fmt.Errorf("error generating contract test template: %w", err) + return fmt.Errorf("error generating contract test template: %w", err) } case "script": basePath = "scripts" fileToWrite, err = processTemplate("templates/script_init.cdc.tmpl", nil) if err != nil { - return nil, fmt.Errorf("error generating script template: %w", err) + return fmt.Errorf("error generating script template: %w", err) } case "transaction": basePath = "transactions" fileToWrite, err = processTemplate("templates/transaction_init.cdc.tmpl", nil) if err != nil { - return nil, fmt.Errorf("error generating transaction template: %w", err) + return fmt.Errorf("error generating transaction template: %w", err) } default: - return nil, fmt.Errorf("invalid template type: %s", templateType) + return fmt.Errorf("invalid template type: %s", templateType) } directoryWithBasePath := filepath.Join(rootDir, basePath) filenameWithBasePath := filepath.Join(rootDir, basePath, filename) // Check file existence - if _, err := state.ReaderWriter().ReadFile(filenameWithBasePath); err == nil { - return nil, fmt.Errorf("file already exists: %s", filenameWithBasePath) + if _, err := g.State.ReaderWriter().ReadFile(filenameWithBasePath); err == nil { + return fmt.Errorf("file already exists: %s", filenameWithBasePath) } // Ensure the directory exists - if err := state.ReaderWriter().MkdirAll(directoryWithBasePath, 0755); err != nil { - return nil, fmt.Errorf("error creating directories: %w", err) + if err := g.State.ReaderWriter().MkdirAll(directoryWithBasePath, 0755); err != nil { + return fmt.Errorf("error creating directories: %w", err) } // Write files - err = state.ReaderWriter().WriteFile(filenameWithBasePath, []byte(fileToWrite), 0644) + err = g.State.ReaderWriter().WriteFile(filenameWithBasePath, []byte(fileToWrite), 0644) if err != nil { - return nil, fmt.Errorf("error writing file: %w", err) + return fmt.Errorf("error writing file: %w", err) } - logger.Info(fmt.Sprintf("Generated new %s: %s at %s", templateType, name, filenameWithBasePath)) + if !g.DisableLogs { + g.Logger.Info(fmt.Sprintf("Generated new %s: %s at %s", templateType, name, filenameWithBasePath)) + } if generateFlags.SkipTests != true && templateType == "contract" { testDirectoryWithBasePath := filepath.Join(rootDir, testsBasePath) testFilenameWithBasePath := filepath.Join(rootDir, testsBasePath, addCDCExtension(fmt.Sprintf("%s_test", name))) - if _, err := state.ReaderWriter().ReadFile(testFilenameWithBasePath); err == nil { - return nil, fmt.Errorf("file already exists: %s", testFilenameWithBasePath) + if _, err := g.State.ReaderWriter().ReadFile(testFilenameWithBasePath); err == nil { + return fmt.Errorf("file already exists: %s", testFilenameWithBasePath) } - if err := state.ReaderWriter().MkdirAll(testDirectoryWithBasePath, 0755); err != nil { - return nil, fmt.Errorf("error creating test directory: %w", err) + if err := g.State.ReaderWriter().MkdirAll(testDirectoryWithBasePath, 0755); err != nil { + return fmt.Errorf("error creating test directory: %w", err) } - err = state.ReaderWriter().WriteFile(testFilenameWithBasePath, []byte(testFileToWrite), 0644) + err := g.State.ReaderWriter().WriteFile(testFilenameWithBasePath, []byte(testFileToWrite), 0644) if err != nil { - return nil, fmt.Errorf("error writing test file: %w", err) + return fmt.Errorf("error writing test file: %w", err) } - logger.Info(fmt.Sprintf("Generated new test file: %s at %s", name, testFilenameWithBasePath)) + g.Logger.Info(fmt.Sprintf("Generated new test file: %s at %s", name, testFilenameWithBasePath)) } if templateType == "contract" { @@ -267,12 +284,34 @@ func generateNew( Location: filenameWithBasePath, Aliases: aliases, } - state.Contracts().AddOrUpdate(contract) - err = state.SaveDefault() + g.State.Contracts().AddOrUpdate(contract) + err := g.State.SaveDefault() if err != nil { - return nil, fmt.Errorf("error saving to flow.json: %w", err) + return fmt.Errorf("error saving to flow.json: %w", err) } } - return nil, err + return nil +} + +// processTemplate reads a template file from the embedded filesystem and processes it with the provided data +// If you don't need to provide data, pass nil +func processTemplate(templatePath string, data map[string]interface{}) (string, error) { + templateData, err := templatesFS.ReadFile(templatePath) + if err != nil { + return "", fmt.Errorf("failed to read template file: %w", err) + } + + tmpl, err := template.New("template").Parse(string(templateData)) + if err != nil { + return "", fmt.Errorf("failed to parse template: %w", err) + } + + var executedTemplate bytes.Buffer + // Execute the template with the provided data or nil if no data is needed + if err = tmpl.Execute(&executedTemplate, data); err != nil { + return "", fmt.Errorf("failed to execute template: %w", err) + } + + return executedTemplate.String(), nil } diff --git a/internal/super/generate_test.go b/internal/super/generate_test.go index 951d6ed9d..5679717d0 100644 --- a/internal/super/generate_test.go +++ b/internal/super/generate_test.go @@ -34,8 +34,10 @@ func TestGenerateNewContract(t *testing.T) { logger := output.NewStdoutLogger(output.NoneLog) _, state, _ := util.TestMocks(t) + generator := NewGenerator(map[string]string{"contract": "TestContract"}, "cadence", state, logger) + // Test contract generation - _, err := generateNew([]string{"TestContract"}, "contract", "", logger, state) + err := generator.Create() assert.NoError(t, err, "Failed to generate contract") fileContent, err := state.ReaderWriter().ReadFile("cadence/contracts/TestContract.cdc") @@ -70,7 +72,8 @@ access(all) fun testContract() { assert.Equal(t, expectedTestContent, util.NormalizeLineEndings(string(testContent))) // Test file already exists scenario - _, err = generateNew([]string{"TestContract"}, "contract", "", logger, state) + generator = NewGenerator(map[string]string{"contract": "TestContract"}, "cadence", state, logger) + err = generator.Create() assert.Error(t, err) expectedError := fmt.Sprintf("file already exists: %s", filepath.FromSlash("cadence/contracts/TestContract.cdc")) assert.Equal(t, expectedError, err.Error()) @@ -82,12 +85,13 @@ func TestGenerateNewContractSkipTests(t *testing.T) { generateFlags.SkipTests = true + generator := NewGenerator(map[string]string{"contract": "TestContract"}, "cadence", state, logger) t.Cleanup(func() { generateFlags.SkipTests = false }) // Test contract generation - _, err := generateNew([]string{"TestContract"}, "contract", "", logger, state) + err := generator.Create() assert.NoError(t, err, "Failed to generate contract") fileContent, err := state.ReaderWriter().ReadFile("cadence/contracts/TestContract.cdc") @@ -104,7 +108,8 @@ func TestGenerateNewContractWithCDCExtension(t *testing.T) { _, state, _ := util.TestMocks(t) // Test contract generation - _, err := generateNew([]string{"Tester.cdc"}, "contract", "", logger, state) + generator := NewGenerator(map[string]string{"contract": "Tester.cdc"}, "cadence", state, logger) + err := generator.Create() assert.NoError(t, err, "Failed to generate contract") fileContent, err := state.ReaderWriter().ReadFile("cadence/contracts/Tester.cdc") @@ -121,7 +126,8 @@ func TestGenerateNewContractFileAlreadyExists(t *testing.T) { _, state, _ := util.TestMocks(t) // Test contract generation - _, err := generateNew([]string{"TestContract"}, "contract", "", logger, state) + generator := NewGenerator(map[string]string{"contract": "TestContract"}, "cadence", state, logger) + err := generator.Create() assert.NoError(t, err, "Failed to generate contract") //// Check if the file exists in the correct directory @@ -130,7 +136,8 @@ func TestGenerateNewContractFileAlreadyExists(t *testing.T) { assert.NotNil(t, content) // Test file already exists scenario - _, err = generateNew([]string{"TestContract"}, "contract", "", logger, state) + generator = NewGenerator(map[string]string{"contract": "TestContract"}, "cadence", state, logger) + err = generator.Create() assert.Error(t, err) expectedError := fmt.Sprintf("file already exists: %s", filepath.FromSlash("cadence/contracts/TestContract.cdc")) assert.Equal(t, expectedError, err.Error()) @@ -140,7 +147,8 @@ func TestGenerateNewContractWithFileExtension(t *testing.T) { logger := output.NewStdoutLogger(output.NoneLog) _, state, _ := util.TestMocks(t) - _, err := generateNew([]string{"TestContract.cdc"}, "contract", "", logger, state) + generator := NewGenerator(map[string]string{"contract": "TestContract.cdc"}, "cadence", state, logger) + err := generator.Create() assert.NoError(t, err, "Failed to generate contract") // Check file exists @@ -153,7 +161,8 @@ func TestGenerateNewScript(t *testing.T) { logger := output.NewStdoutLogger(output.NoneLog) _, state, _ := util.TestMocks(t) - _, err := generateNew([]string{"TestScript"}, "script", "", logger, state) + generator := NewGenerator(map[string]string{"script": "TestScript"}, "cadence", state, logger) + err := generator.Create() assert.NoError(t, err, "Failed to generate contract") content, err := state.ReaderWriter().ReadFile("cadence/scripts/TestScript.cdc") @@ -171,7 +180,8 @@ func TestGenerateNewTransaction(t *testing.T) { logger := output.NewStdoutLogger(output.NoneLog) _, state, _ := util.TestMocks(t) - _, err := generateNew([]string{"TestTransaction"}, "transaction", "", logger, state) + generator := NewGenerator(map[string]string{"transaction": "TestTransaction"}, "cadence", state, logger) + err := generator.Create() assert.NoError(t, err, "Failed to generate contract") content, err := state.ReaderWriter().ReadFile("cadence/transactions/TestTransaction.cdc") @@ -190,7 +200,8 @@ func TestGenerateNewWithDirFlag(t *testing.T) { logger := output.NewStdoutLogger(output.NoneLog) _, state, _ := util.TestMocks(t) - _, err := generateNew([]string{"TestContract"}, "contract", "customDir", logger, state) + generator := NewGenerator(map[string]string{"contract": "TestContract"}, "customDir", state, logger) + err := generator.Create() assert.NoError(t, err, "Failed to generate contract") content, err := state.ReaderWriter().ReadFile("customDir/contracts/TestContract.cdc") diff --git a/internal/super/setup.go b/internal/super/setup.go index 2c9f2cb17..55998145b 100644 --- a/internal/super/setup.go +++ b/internal/super/setup.go @@ -154,17 +154,14 @@ func startInteractiveSetup( directoryPath := filepath.Join(tempDir, "cadence") - _, err = generateNew([]string{"DefaultContract"}, "contract", directoryPath, logger, state) - if err != nil { - return "", err - } - - _, err = generateNew([]string{"DefaultScript"}, "script", directoryPath, logger, state) - if err != nil { - return "", err + templates := map[string]string{ + "contract": "DefaultContract", + "script": "DefaultScripts", + "transaction": "DefaultTransaction", } - _, err = generateNew([]string{"DefaultTransaction"}, "transaction", directoryPath, logger, state) + generator := NewGenerator(templates, directoryPath, state, logger) + err = generator.Create() if err != nil { return "", err } From 4b1adb06e678b653f73332d6c07c26ca4dc0bb44 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Fri, 3 May 2024 10:03:10 -0700 Subject: [PATCH 38/86] Move templates to create as arg --- internal/super/generate.go | 23 ++++++++++--------- internal/super/generate_test.go | 40 ++++++++++++++++----------------- internal/super/setup.go | 6 ++--- 3 files changed, 35 insertions(+), 34 deletions(-) diff --git a/internal/super/generate.go b/internal/super/generate.go index 739393b30..b4760f32b 100644 --- a/internal/super/generate.go +++ b/internal/super/generate.go @@ -106,8 +106,8 @@ func generateContract( return nil, fmt.Errorf("invalid number of arguments") } - generator := NewGenerator(map[string]string{"contract": args[0]}, "cadence", state, logger) - err = generator.Create() + generator := NewGenerator("cadence", state, logger) + err = generator.Create(TemplateMap{"contract": args[0]}) return nil, err } @@ -122,8 +122,8 @@ func generateTransaction( return nil, fmt.Errorf("invalid number of arguments") } - generator := NewGenerator(map[string]string{"transaction": args[0]}, "cadence", state, logger) - err = generator.Create() + generator := NewGenerator("cadence", state, logger) + err = generator.Create(TemplateMap{"transaction": args[0]}) return nil, err } @@ -138,8 +138,8 @@ func generateScript( return nil, fmt.Errorf("invalid number of arguments") } - generator := NewGenerator(map[string]string{"script": args[0]}, "cadence", state, logger) - err = generator.Create() + generator := NewGenerator("cadence", state, logger) + err = generator.Create(TemplateMap{"script": args[0]}) return nil, err } @@ -154,25 +154,26 @@ func stripCDCExtension(name string) string { return strings.TrimSuffix(name, filepath.Ext(name)) } +// TemplateMap defines a map of template types to their specific names +type TemplateMap map[string]string + type Generator struct { - TypeNames map[string]string // Map of template types to their specific names Directory string State *flowkit.State Logger output.Logger DisableLogs bool } -func NewGenerator(typeNames map[string]string, directory string, state *flowkit.State, logger output.Logger) *Generator { +func NewGenerator(directory string, state *flowkit.State, logger output.Logger) *Generator { return &Generator{ - TypeNames: typeNames, Directory: directory, State: state, Logger: logger, } } -func (g *Generator) Create() error { - for templateType, name := range g.TypeNames { +func (g *Generator) Create(typeNames TemplateMap) error { + for templateType, name := range typeNames { err := g.generate(templateType, name) if err != nil { return err diff --git a/internal/super/generate_test.go b/internal/super/generate_test.go index 5679717d0..9ede25953 100644 --- a/internal/super/generate_test.go +++ b/internal/super/generate_test.go @@ -34,10 +34,10 @@ func TestGenerateNewContract(t *testing.T) { logger := output.NewStdoutLogger(output.NoneLog) _, state, _ := util.TestMocks(t) - generator := NewGenerator(map[string]string{"contract": "TestContract"}, "cadence", state, logger) + generator := NewGenerator("cadence", state, logger) // Test contract generation - err := generator.Create() + err := generator.Create(TemplateMap{"contract": "TestContract"}) assert.NoError(t, err, "Failed to generate contract") fileContent, err := state.ReaderWriter().ReadFile("cadence/contracts/TestContract.cdc") @@ -72,8 +72,8 @@ access(all) fun testContract() { assert.Equal(t, expectedTestContent, util.NormalizeLineEndings(string(testContent))) // Test file already exists scenario - generator = NewGenerator(map[string]string{"contract": "TestContract"}, "cadence", state, logger) - err = generator.Create() + generator = NewGenerator("cadence", state, logger) + err = generator.Create(TemplateMap{"contract": "TestContract"}) assert.Error(t, err) expectedError := fmt.Sprintf("file already exists: %s", filepath.FromSlash("cadence/contracts/TestContract.cdc")) assert.Equal(t, expectedError, err.Error()) @@ -85,13 +85,13 @@ func TestGenerateNewContractSkipTests(t *testing.T) { generateFlags.SkipTests = true - generator := NewGenerator(map[string]string{"contract": "TestContract"}, "cadence", state, logger) + generator := NewGenerator("cadence", state, logger) t.Cleanup(func() { generateFlags.SkipTests = false }) // Test contract generation - err := generator.Create() + err := generator.Create(TemplateMap{"contract": "TestContract"}) assert.NoError(t, err, "Failed to generate contract") fileContent, err := state.ReaderWriter().ReadFile("cadence/contracts/TestContract.cdc") @@ -108,8 +108,8 @@ func TestGenerateNewContractWithCDCExtension(t *testing.T) { _, state, _ := util.TestMocks(t) // Test contract generation - generator := NewGenerator(map[string]string{"contract": "Tester.cdc"}, "cadence", state, logger) - err := generator.Create() + generator := NewGenerator("cadence", state, logger) + err := generator.Create(TemplateMap{"contract": "Tester.cdc"}) assert.NoError(t, err, "Failed to generate contract") fileContent, err := state.ReaderWriter().ReadFile("cadence/contracts/Tester.cdc") @@ -126,8 +126,8 @@ func TestGenerateNewContractFileAlreadyExists(t *testing.T) { _, state, _ := util.TestMocks(t) // Test contract generation - generator := NewGenerator(map[string]string{"contract": "TestContract"}, "cadence", state, logger) - err := generator.Create() + generator := NewGenerator("cadence", state, logger) + err := generator.Create(TemplateMap{"contract": "TestContract"}) assert.NoError(t, err, "Failed to generate contract") //// Check if the file exists in the correct directory @@ -136,8 +136,8 @@ func TestGenerateNewContractFileAlreadyExists(t *testing.T) { assert.NotNil(t, content) // Test file already exists scenario - generator = NewGenerator(map[string]string{"contract": "TestContract"}, "cadence", state, logger) - err = generator.Create() + generator = NewGenerator("cadence", state, logger) + err = generator.Create(TemplateMap{"contract": "TestContract"}) assert.Error(t, err) expectedError := fmt.Sprintf("file already exists: %s", filepath.FromSlash("cadence/contracts/TestContract.cdc")) assert.Equal(t, expectedError, err.Error()) @@ -147,8 +147,8 @@ func TestGenerateNewContractWithFileExtension(t *testing.T) { logger := output.NewStdoutLogger(output.NoneLog) _, state, _ := util.TestMocks(t) - generator := NewGenerator(map[string]string{"contract": "TestContract.cdc"}, "cadence", state, logger) - err := generator.Create() + generator := NewGenerator("cadence", state, logger) + err := generator.Create(TemplateMap{"contract": "TestContract.cdc"}) assert.NoError(t, err, "Failed to generate contract") // Check file exists @@ -161,8 +161,8 @@ func TestGenerateNewScript(t *testing.T) { logger := output.NewStdoutLogger(output.NoneLog) _, state, _ := util.TestMocks(t) - generator := NewGenerator(map[string]string{"script": "TestScript"}, "cadence", state, logger) - err := generator.Create() + generator := NewGenerator("cadence", state, logger) + err := generator.Create(TemplateMap{"script": "TestScript"}) assert.NoError(t, err, "Failed to generate contract") content, err := state.ReaderWriter().ReadFile("cadence/scripts/TestScript.cdc") @@ -180,8 +180,8 @@ func TestGenerateNewTransaction(t *testing.T) { logger := output.NewStdoutLogger(output.NoneLog) _, state, _ := util.TestMocks(t) - generator := NewGenerator(map[string]string{"transaction": "TestTransaction"}, "cadence", state, logger) - err := generator.Create() + generator := NewGenerator("cadence", state, logger) + err := generator.Create(TemplateMap{"transaction": "TestTransaction"}) assert.NoError(t, err, "Failed to generate contract") content, err := state.ReaderWriter().ReadFile("cadence/transactions/TestTransaction.cdc") @@ -200,8 +200,8 @@ func TestGenerateNewWithDirFlag(t *testing.T) { logger := output.NewStdoutLogger(output.NoneLog) _, state, _ := util.TestMocks(t) - generator := NewGenerator(map[string]string{"contract": "TestContract"}, "customDir", state, logger) - err := generator.Create() + generator := NewGenerator("customDir", state, logger) + err := generator.Create(TemplateMap{"contract": "TestContract"}) assert.NoError(t, err, "Failed to generate contract") content, err := state.ReaderWriter().ReadFile("customDir/contracts/TestContract.cdc") diff --git a/internal/super/setup.go b/internal/super/setup.go index 55998145b..0efca0f74 100644 --- a/internal/super/setup.go +++ b/internal/super/setup.go @@ -154,14 +154,14 @@ func startInteractiveSetup( directoryPath := filepath.Join(tempDir, "cadence") - templates := map[string]string{ + templates := TemplateMap{ "contract": "DefaultContract", "script": "DefaultScripts", "transaction": "DefaultTransaction", } - generator := NewGenerator(templates, directoryPath, state, logger) - err = generator.Create() + generator := NewGenerator(directoryPath, state, logger) + err = generator.Create(templates) if err != nil { return "", err } From 7aa20ef7964652ddb2bc92ba6f72bc259a997e75 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Fri, 3 May 2024 10:14:21 -0700 Subject: [PATCH 39/86] Change generator to options --- internal/super/generate.go | 59 ++++++++++++++++---------- internal/super/generate_test.go | 74 +++++++++++++++++++++++++++------ internal/super/setup.go | 7 +++- 3 files changed, 106 insertions(+), 34 deletions(-) diff --git a/internal/super/generate.go b/internal/super/generate.go index b4760f32b..48b1faf9f 100644 --- a/internal/super/generate.go +++ b/internal/super/generate.go @@ -106,7 +106,12 @@ func generateContract( return nil, fmt.Errorf("invalid number of arguments") } - generator := NewGenerator("cadence", state, logger) + options := GeneratorOptions{ + Directory: "cadence", + State: state, + Logger: logger, + } + generator := NewGenerator(options) err = generator.Create(TemplateMap{"contract": args[0]}) return nil, err } @@ -122,7 +127,12 @@ func generateTransaction( return nil, fmt.Errorf("invalid number of arguments") } - generator := NewGenerator("cadence", state, logger) + options := GeneratorOptions{ + Directory: "cadence", + State: state, + Logger: logger, + } + generator := NewGenerator(options) err = generator.Create(TemplateMap{"transaction": args[0]}) return nil, err } @@ -138,7 +148,12 @@ func generateScript( return nil, fmt.Errorf("invalid number of arguments") } - generator := NewGenerator("cadence", state, logger) + options := GeneratorOptions{ + Directory: "cadence", + State: state, + Logger: logger, + } + generator := NewGenerator(options) err = generator.Create(TemplateMap{"script": args[0]}) return nil, err } @@ -157,18 +172,20 @@ func stripCDCExtension(name string) string { // TemplateMap defines a map of template types to their specific names type TemplateMap map[string]string -type Generator struct { +type GeneratorOptions struct { Directory string State *flowkit.State Logger output.Logger DisableLogs bool } -func NewGenerator(directory string, state *flowkit.State, logger output.Logger) *Generator { +type Generator struct { + Options GeneratorOptions +} + +func NewGenerator(options GeneratorOptions) *Generator { return &Generator{ - Directory: directory, - State: state, - Logger: logger, + Options: options, } } @@ -194,8 +211,8 @@ func (g *Generator) generate(templateType, name string) error { var testsBasePath = "tests" var err error - if g.Directory != "" { - rootDir = g.Directory + if g.Options.Directory != "" { + rootDir = g.Options.Directory } switch templateType { @@ -231,43 +248,43 @@ func (g *Generator) generate(templateType, name string) error { filenameWithBasePath := filepath.Join(rootDir, basePath, filename) // Check file existence - if _, err := g.State.ReaderWriter().ReadFile(filenameWithBasePath); err == nil { + if _, err := g.Options.State.ReaderWriter().ReadFile(filenameWithBasePath); err == nil { return fmt.Errorf("file already exists: %s", filenameWithBasePath) } // Ensure the directory exists - if err := g.State.ReaderWriter().MkdirAll(directoryWithBasePath, 0755); err != nil { + if err := g.Options.State.ReaderWriter().MkdirAll(directoryWithBasePath, 0755); err != nil { return fmt.Errorf("error creating directories: %w", err) } // Write files - err = g.State.ReaderWriter().WriteFile(filenameWithBasePath, []byte(fileToWrite), 0644) + err = g.Options.State.ReaderWriter().WriteFile(filenameWithBasePath, []byte(fileToWrite), 0644) if err != nil { return fmt.Errorf("error writing file: %w", err) } - if !g.DisableLogs { - g.Logger.Info(fmt.Sprintf("Generated new %s: %s at %s", templateType, name, filenameWithBasePath)) + if !g.Options.DisableLogs { + g.Options.Logger.Info(fmt.Sprintf("Generated new %s: %s at %s", templateType, name, filenameWithBasePath)) } if generateFlags.SkipTests != true && templateType == "contract" { testDirectoryWithBasePath := filepath.Join(rootDir, testsBasePath) testFilenameWithBasePath := filepath.Join(rootDir, testsBasePath, addCDCExtension(fmt.Sprintf("%s_test", name))) - if _, err := g.State.ReaderWriter().ReadFile(testFilenameWithBasePath); err == nil { + if _, err := g.Options.State.ReaderWriter().ReadFile(testFilenameWithBasePath); err == nil { return fmt.Errorf("file already exists: %s", testFilenameWithBasePath) } - if err := g.State.ReaderWriter().MkdirAll(testDirectoryWithBasePath, 0755); err != nil { + if err := g.Options.State.ReaderWriter().MkdirAll(testDirectoryWithBasePath, 0755); err != nil { return fmt.Errorf("error creating test directory: %w", err) } - err := g.State.ReaderWriter().WriteFile(testFilenameWithBasePath, []byte(testFileToWrite), 0644) + err := g.Options.State.ReaderWriter().WriteFile(testFilenameWithBasePath, []byte(testFileToWrite), 0644) if err != nil { return fmt.Errorf("error writing test file: %w", err) } - g.Logger.Info(fmt.Sprintf("Generated new test file: %s at %s", name, testFilenameWithBasePath)) + g.Options.Logger.Info(fmt.Sprintf("Generated new test file: %s at %s", name, testFilenameWithBasePath)) } if templateType == "contract" { @@ -285,8 +302,8 @@ func (g *Generator) generate(templateType, name string) error { Location: filenameWithBasePath, Aliases: aliases, } - g.State.Contracts().AddOrUpdate(contract) - err := g.State.SaveDefault() + g.Options.State.Contracts().AddOrUpdate(contract) + err := g.Options.State.SaveDefault() if err != nil { return fmt.Errorf("error saving to flow.json: %w", err) } diff --git a/internal/super/generate_test.go b/internal/super/generate_test.go index 9ede25953..af64393a3 100644 --- a/internal/super/generate_test.go +++ b/internal/super/generate_test.go @@ -34,7 +34,12 @@ func TestGenerateNewContract(t *testing.T) { logger := output.NewStdoutLogger(output.NoneLog) _, state, _ := util.TestMocks(t) - generator := NewGenerator("cadence", state, logger) + options := GeneratorOptions{ + Directory: "cadence", + State: state, + Logger: logger, + } + generator := NewGenerator(options) // Test contract generation err := generator.Create(TemplateMap{"contract": "TestContract"}) @@ -72,8 +77,13 @@ access(all) fun testContract() { assert.Equal(t, expectedTestContent, util.NormalizeLineEndings(string(testContent))) // Test file already exists scenario - generator = NewGenerator("cadence", state, logger) - err = generator.Create(TemplateMap{"contract": "TestContract"}) + optionsTwo := GeneratorOptions{ + Directory: "cadence", + State: state, + Logger: logger, + } + generatorTwo := NewGenerator(optionsTwo) + err = generatorTwo.Create(TemplateMap{"contract": "TestContract"}) assert.Error(t, err) expectedError := fmt.Sprintf("file already exists: %s", filepath.FromSlash("cadence/contracts/TestContract.cdc")) assert.Equal(t, expectedError, err.Error()) @@ -85,7 +95,12 @@ func TestGenerateNewContractSkipTests(t *testing.T) { generateFlags.SkipTests = true - generator := NewGenerator("cadence", state, logger) + options := GeneratorOptions{ + Directory: "cadence", + State: state, + Logger: logger, + } + generator := NewGenerator(options) t.Cleanup(func() { generateFlags.SkipTests = false }) @@ -108,7 +123,12 @@ func TestGenerateNewContractWithCDCExtension(t *testing.T) { _, state, _ := util.TestMocks(t) // Test contract generation - generator := NewGenerator("cadence", state, logger) + options := GeneratorOptions{ + Directory: "cadence", + State: state, + Logger: logger, + } + generator := NewGenerator(options) err := generator.Create(TemplateMap{"contract": "Tester.cdc"}) assert.NoError(t, err, "Failed to generate contract") @@ -126,7 +146,12 @@ func TestGenerateNewContractFileAlreadyExists(t *testing.T) { _, state, _ := util.TestMocks(t) // Test contract generation - generator := NewGenerator("cadence", state, logger) + options := GeneratorOptions{ + Directory: "cadence", + State: state, + Logger: logger, + } + generator := NewGenerator(options) err := generator.Create(TemplateMap{"contract": "TestContract"}) assert.NoError(t, err, "Failed to generate contract") @@ -136,8 +161,13 @@ func TestGenerateNewContractFileAlreadyExists(t *testing.T) { assert.NotNil(t, content) // Test file already exists scenario - generator = NewGenerator("cadence", state, logger) - err = generator.Create(TemplateMap{"contract": "TestContract"}) + optionsTwo := GeneratorOptions{ + Directory: "cadence", + State: state, + Logger: logger, + } + generatorTwo := NewGenerator(optionsTwo) + err = generatorTwo.Create(TemplateMap{"contract": "TestContract"}) assert.Error(t, err) expectedError := fmt.Sprintf("file already exists: %s", filepath.FromSlash("cadence/contracts/TestContract.cdc")) assert.Equal(t, expectedError, err.Error()) @@ -147,7 +177,12 @@ func TestGenerateNewContractWithFileExtension(t *testing.T) { logger := output.NewStdoutLogger(output.NoneLog) _, state, _ := util.TestMocks(t) - generator := NewGenerator("cadence", state, logger) + options := GeneratorOptions{ + Directory: "cadence", + State: state, + Logger: logger, + } + generator := NewGenerator(options) err := generator.Create(TemplateMap{"contract": "TestContract.cdc"}) assert.NoError(t, err, "Failed to generate contract") @@ -161,7 +196,12 @@ func TestGenerateNewScript(t *testing.T) { logger := output.NewStdoutLogger(output.NoneLog) _, state, _ := util.TestMocks(t) - generator := NewGenerator("cadence", state, logger) + options := GeneratorOptions{ + Directory: "cadence", + State: state, + Logger: logger, + } + generator := NewGenerator(options) err := generator.Create(TemplateMap{"script": "TestScript"}) assert.NoError(t, err, "Failed to generate contract") @@ -180,7 +220,12 @@ func TestGenerateNewTransaction(t *testing.T) { logger := output.NewStdoutLogger(output.NoneLog) _, state, _ := util.TestMocks(t) - generator := NewGenerator("cadence", state, logger) + options := GeneratorOptions{ + Directory: "cadence", + State: state, + Logger: logger, + } + generator := NewGenerator(options) err := generator.Create(TemplateMap{"transaction": "TestTransaction"}) assert.NoError(t, err, "Failed to generate contract") @@ -200,7 +245,12 @@ func TestGenerateNewWithDirFlag(t *testing.T) { logger := output.NewStdoutLogger(output.NoneLog) _, state, _ := util.TestMocks(t) - generator := NewGenerator("customDir", state, logger) + options := GeneratorOptions{ + Directory: "customDir", + State: state, + Logger: logger, + } + generator := NewGenerator(options) err := generator.Create(TemplateMap{"contract": "TestContract"}) assert.NoError(t, err, "Failed to generate contract") diff --git a/internal/super/setup.go b/internal/super/setup.go index 0efca0f74..b82899fad 100644 --- a/internal/super/setup.go +++ b/internal/super/setup.go @@ -160,7 +160,12 @@ func startInteractiveSetup( "transaction": "DefaultTransaction", } - generator := NewGenerator(directoryPath, state, logger) + options := GeneratorOptions{ + Directory: directoryPath, + State: state, + Logger: logger, + } + generator := NewGenerator(options) err = generator.Create(templates) if err != nil { return "", err From 4784f5f6caa76c2bd3e8fbfe0d4303b16c45b384 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Fri, 3 May 2024 10:16:17 -0700 Subject: [PATCH 40/86] Disable logs --- internal/super/generate.go | 4 +++- internal/super/setup.go | 7 ++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/internal/super/generate.go b/internal/super/generate.go index 48b1faf9f..a4a7c2bf3 100644 --- a/internal/super/generate.go +++ b/internal/super/generate.go @@ -284,7 +284,9 @@ func (g *Generator) generate(templateType, name string) error { return fmt.Errorf("error writing test file: %w", err) } - g.Options.Logger.Info(fmt.Sprintf("Generated new test file: %s at %s", name, testFilenameWithBasePath)) + if !g.Options.DisableLogs { + g.Options.Logger.Info(fmt.Sprintf("Generated new test file: %s at %s", name, testFilenameWithBasePath)) + } } if templateType == "contract" { diff --git a/internal/super/setup.go b/internal/super/setup.go index b82899fad..9168204ad 100644 --- a/internal/super/setup.go +++ b/internal/super/setup.go @@ -161,9 +161,10 @@ func startInteractiveSetup( } options := GeneratorOptions{ - Directory: directoryPath, - State: state, - Logger: logger, + Directory: directoryPath, + State: state, + Logger: logger, + DisableLogs: true, } generator := NewGenerator(options) err = generator.Create(templates) From 25e987a7a46ec7deb4901e1d81e846da3028a481 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Fri, 3 May 2024 10:22:28 -0700 Subject: [PATCH 41/86] Move to util --- internal/super/generate.go | 19 ++++--------------- internal/util/files.go | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 15 deletions(-) create mode 100644 internal/util/files.go diff --git a/internal/super/generate.go b/internal/super/generate.go index a4a7c2bf3..d32afe43c 100644 --- a/internal/super/generate.go +++ b/internal/super/generate.go @@ -22,8 +22,8 @@ import ( "bytes" "embed" "fmt" + "github.com/onflow/flow-cli/internal/util" "path/filepath" - "strings" "text/template" flowsdk "github.com/onflow/flow-go-sdk" @@ -158,17 +158,6 @@ func generateScript( return nil, err } -func addCDCExtension(name string) string { - if strings.HasSuffix(name, ".cdc") { - return name - } - return fmt.Sprintf("%s.cdc", name) -} - -func stripCDCExtension(name string) string { - return strings.TrimSuffix(name, filepath.Ext(name)) -} - // TemplateMap defines a map of template types to their specific names type TemplateMap map[string]string @@ -201,8 +190,8 @@ func (g *Generator) Create(typeNames TemplateMap) error { func (g *Generator) generate(templateType, name string) error { - name = stripCDCExtension(name) - filename := addCDCExtension(name) + name = util.StripCDCExtension(name) + filename := util.AddCDCExtension(name) var fileToWrite string var testFileToWrite string @@ -269,7 +258,7 @@ func (g *Generator) generate(templateType, name string) error { if generateFlags.SkipTests != true && templateType == "contract" { testDirectoryWithBasePath := filepath.Join(rootDir, testsBasePath) - testFilenameWithBasePath := filepath.Join(rootDir, testsBasePath, addCDCExtension(fmt.Sprintf("%s_test", name))) + testFilenameWithBasePath := filepath.Join(rootDir, testsBasePath, util.AddCDCExtension(fmt.Sprintf("%s_test", name))) if _, err := g.Options.State.ReaderWriter().ReadFile(testFilenameWithBasePath); err == nil { return fmt.Errorf("file already exists: %s", testFilenameWithBasePath) diff --git a/internal/util/files.go b/internal/util/files.go new file mode 100644 index 000000000..ce011bc1c --- /dev/null +++ b/internal/util/files.go @@ -0,0 +1,36 @@ +/* + * Flow CLI + * + * Copyright 2019 Dapper Labs, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package util + +import ( + "fmt" + "path/filepath" + "strings" +) + +func AddCDCExtension(name string) string { + if strings.HasSuffix(name, ".cdc") { + return name + } + return fmt.Sprintf("%s.cdc", name) +} + +func StripCDCExtension(name string) string { + return strings.TrimSuffix(name, filepath.Ext(name)) +} From 82b89172882973fe11c40e36fa2ec842b606b6ff Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Fri, 3 May 2024 10:37:43 -0700 Subject: [PATCH 42/86] Remove check --- internal/super/generate.go | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/internal/super/generate.go b/internal/super/generate.go index d32afe43c..f3b76ebd7 100644 --- a/internal/super/generate.go +++ b/internal/super/generate.go @@ -102,10 +102,6 @@ func generateContract( _ flowkit.Services, state *flowkit.State, ) (result command.Result, err error) { - if len(args) < 1 { - return nil, fmt.Errorf("invalid number of arguments") - } - options := GeneratorOptions{ Directory: "cadence", State: state, @@ -123,10 +119,6 @@ func generateTransaction( _ flowkit.Services, state *flowkit.State, ) (result command.Result, err error) { - if len(args) < 1 { - return nil, fmt.Errorf("invalid number of arguments") - } - options := GeneratorOptions{ Directory: "cadence", State: state, @@ -144,10 +136,6 @@ func generateScript( _ flowkit.Services, state *flowkit.State, ) (result command.Result, err error) { - if len(args) < 1 { - return nil, fmt.Errorf("invalid number of arguments") - } - options := GeneratorOptions{ Directory: "cadence", State: state, From 76d43f353b32cc1bb0cb4dc6e458fe2de7e640eb Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Fri, 3 May 2024 10:38:32 -0700 Subject: [PATCH 43/86] Run goimport fix --- internal/dependencymanager/install.go | 1 + internal/super/generate.go | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/internal/dependencymanager/install.go b/internal/dependencymanager/install.go index 7efad4f9f..261a5535c 100644 --- a/internal/dependencymanager/install.go +++ b/internal/dependencymanager/install.go @@ -20,6 +20,7 @@ package dependencymanager import ( "fmt" + "github.com/onflow/flow-cli/internal/util" "github.com/spf13/cobra" diff --git a/internal/super/generate.go b/internal/super/generate.go index f3b76ebd7..dd7039b0f 100644 --- a/internal/super/generate.go +++ b/internal/super/generate.go @@ -22,10 +22,11 @@ import ( "bytes" "embed" "fmt" - "github.com/onflow/flow-cli/internal/util" "path/filepath" "text/template" + "github.com/onflow/flow-cli/internal/util" + flowsdk "github.com/onflow/flow-go-sdk" "github.com/onflow/flowkit/config" From 792f973f8c674338663e9362f51f19515eb07d08 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Fri, 3 May 2024 10:40:28 -0700 Subject: [PATCH 44/86] Add cadence dir constant --- internal/super/generate.go | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/internal/super/generate.go b/internal/super/generate.go index dd7039b0f..5a996336c 100644 --- a/internal/super/generate.go +++ b/internal/super/generate.go @@ -96,6 +96,8 @@ func init() { GenerateScriptCommand.AddToParent(GenerateCommand) } +const DefaultCadenceDirectory = "cadence" + func generateContract( args []string, _ command.GlobalFlags, @@ -104,7 +106,7 @@ func generateContract( state *flowkit.State, ) (result command.Result, err error) { options := GeneratorOptions{ - Directory: "cadence", + Directory: DefaultCadenceDirectory, State: state, Logger: logger, } @@ -121,7 +123,7 @@ func generateTransaction( state *flowkit.State, ) (result command.Result, err error) { options := GeneratorOptions{ - Directory: "cadence", + Directory: DefaultCadenceDirectory, State: state, Logger: logger, } @@ -138,7 +140,7 @@ func generateScript( state *flowkit.State, ) (result command.Result, err error) { options := GeneratorOptions{ - Directory: "cadence", + Directory: DefaultCadenceDirectory, State: state, Logger: logger, } @@ -184,7 +186,7 @@ func (g *Generator) generate(templateType, name string) error { var fileToWrite string var testFileToWrite string - var rootDir = "cadence" + var rootDir = DefaultCadenceDirectory var basePath string var testsBasePath = "tests" var err error From 65428446b4479570b8e5fc731c3e86aa5cd0d020 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Fri, 3 May 2024 10:42:08 -0700 Subject: [PATCH 45/86] Use constants for types --- internal/super/generate.go | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/internal/super/generate.go b/internal/super/generate.go index 5a996336c..d0e6ac8e9 100644 --- a/internal/super/generate.go +++ b/internal/super/generate.go @@ -96,7 +96,12 @@ func init() { GenerateScriptCommand.AddToParent(GenerateCommand) } -const DefaultCadenceDirectory = "cadence" +const ( + DefaultCadenceDirectory = "cadence" + ContractType = "contract" + TransactionType = "transaction" + ScriptType = "script" +) func generateContract( args []string, @@ -111,7 +116,7 @@ func generateContract( Logger: logger, } generator := NewGenerator(options) - err = generator.Create(TemplateMap{"contract": args[0]}) + err = generator.Create(TemplateMap{ContractType: args[0]}) return nil, err } @@ -128,7 +133,7 @@ func generateTransaction( Logger: logger, } generator := NewGenerator(options) - err = generator.Create(TemplateMap{"transaction": args[0]}) + err = generator.Create(TemplateMap{TransactionType: args[0]}) return nil, err } @@ -145,7 +150,7 @@ func generateScript( Logger: logger, } generator := NewGenerator(options) - err = generator.Create(TemplateMap{"script": args[0]}) + err = generator.Create(TemplateMap{ScriptType: args[0]}) return nil, err } @@ -196,7 +201,7 @@ func (g *Generator) generate(templateType, name string) error { } switch templateType { - case "contract": + case ContractType: basePath = "contracts" nameData := map[string]interface{}{"Name": name} fileToWrite, err = processTemplate("templates/contract_init.cdc.tmpl", nameData) @@ -208,13 +213,13 @@ func (g *Generator) generate(templateType, name string) error { if err != nil { return fmt.Errorf("error generating contract test template: %w", err) } - case "script": + case ScriptType: basePath = "scripts" fileToWrite, err = processTemplate("templates/script_init.cdc.tmpl", nil) if err != nil { return fmt.Errorf("error generating script template: %w", err) } - case "transaction": + case TransactionType: basePath = "transactions" fileToWrite, err = processTemplate("templates/transaction_init.cdc.tmpl", nil) if err != nil { @@ -247,7 +252,7 @@ func (g *Generator) generate(templateType, name string) error { g.Options.Logger.Info(fmt.Sprintf("Generated new %s: %s at %s", templateType, name, filenameWithBasePath)) } - if generateFlags.SkipTests != true && templateType == "contract" { + if generateFlags.SkipTests != true && templateType == ContractType { testDirectoryWithBasePath := filepath.Join(rootDir, testsBasePath) testFilenameWithBasePath := filepath.Join(rootDir, testsBasePath, util.AddCDCExtension(fmt.Sprintf("%s_test", name))) @@ -269,7 +274,7 @@ func (g *Generator) generate(templateType, name string) error { } } - if templateType == "contract" { + if templateType == ContractType { var aliases config.Aliases if generateFlags.SkipTests != true { From b4b68bd9c81c63bae81c0012820a1a8fb34e0a2a Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Fri, 3 May 2024 10:54:09 -0700 Subject: [PATCH 46/86] Move contract update to seperate method --- internal/super/generate.go | 50 ++++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 21 deletions(-) diff --git a/internal/super/generate.go b/internal/super/generate.go index d0e6ac8e9..ce4f1347a 100644 --- a/internal/super/generate.go +++ b/internal/super/generate.go @@ -22,15 +22,13 @@ import ( "bytes" "embed" "fmt" + flowsdk "github.com/onflow/flow-go-sdk" + "github.com/onflow/flowkit/config" "path/filepath" "text/template" "github.com/onflow/flow-cli/internal/util" - flowsdk "github.com/onflow/flow-go-sdk" - - "github.com/onflow/flowkit/config" - "github.com/onflow/flowkit" "github.com/onflow/flowkit/output" @@ -275,30 +273,40 @@ func (g *Generator) generate(templateType, name string) error { } if templateType == ContractType { - var aliases config.Aliases - - if generateFlags.SkipTests != true { - aliases = config.Aliases{{ - Network: config.TestingNetwork.Name, - Address: flowsdk.HexToAddress("0x0000000000000007"), - }} - } - - contract := config.Contract{ - Name: name, - Location: filenameWithBasePath, - Aliases: aliases, - } - g.Options.State.Contracts().AddOrUpdate(contract) - err := g.Options.State.SaveDefault() + err := g.updateContractsState(name, filenameWithBasePath) if err != nil { - return fmt.Errorf("error saving to flow.json: %w", err) + return err } } return nil } +func (g *Generator) updateContractsState(name, location string) error { + var aliases config.Aliases + + if generateFlags.SkipTests != true { + aliases = config.Aliases{{ + Network: config.TestingNetwork.Name, + Address: flowsdk.HexToAddress("0x0000000000000007"), + }} + } + + contract := config.Contract{ + Name: name, + Location: location, + Aliases: aliases, + } + + g.Options.State.Contracts().AddOrUpdate(contract) + err := g.Options.State.SaveDefault() + if err != nil { + return fmt.Errorf("error saving to flow.json: %w", err) + } + + return nil +} + // processTemplate reads a template file from the embedded filesystem and processes it with the provided data // If you don't need to provide data, pass nil func processTemplate(templatePath string, data map[string]interface{}) (string, error) { From 599b2bd9794738fe9a70cc7d2b3b511084e8a106 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Fri, 3 May 2024 10:58:22 -0700 Subject: [PATCH 47/86] Run imports fix --- internal/super/generate.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/internal/super/generate.go b/internal/super/generate.go index ce4f1347a..7594f5328 100644 --- a/internal/super/generate.go +++ b/internal/super/generate.go @@ -22,11 +22,12 @@ import ( "bytes" "embed" "fmt" - flowsdk "github.com/onflow/flow-go-sdk" - "github.com/onflow/flowkit/config" "path/filepath" "text/template" + flowsdk "github.com/onflow/flow-go-sdk" + "github.com/onflow/flowkit/config" + "github.com/onflow/flow-cli/internal/util" "github.com/onflow/flowkit" From cb630fda42a223288cf0be31b5fb8da1b03c0b40 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Fri, 3 May 2024 11:28:04 -0700 Subject: [PATCH 48/86] Change constructor --- internal/super/generate.go | 62 +++++++++++------------------ internal/super/generate_test.go | 70 +++++---------------------------- internal/super/setup.go | 8 +--- 3 files changed, 34 insertions(+), 106 deletions(-) diff --git a/internal/super/generate.go b/internal/super/generate.go index 7594f5328..23523c877 100644 --- a/internal/super/generate.go +++ b/internal/super/generate.go @@ -109,12 +109,7 @@ func generateContract( _ flowkit.Services, state *flowkit.State, ) (result command.Result, err error) { - options := GeneratorOptions{ - Directory: DefaultCadenceDirectory, - State: state, - Logger: logger, - } - generator := NewGenerator(options) + generator := NewGenerator(DefaultCadenceDirectory, state, logger, false) err = generator.Create(TemplateMap{ContractType: args[0]}) return nil, err } @@ -126,12 +121,7 @@ func generateTransaction( _ flowkit.Services, state *flowkit.State, ) (result command.Result, err error) { - options := GeneratorOptions{ - Directory: DefaultCadenceDirectory, - State: state, - Logger: logger, - } - generator := NewGenerator(options) + generator := NewGenerator(DefaultCadenceDirectory, state, logger, false) err = generator.Create(TemplateMap{TransactionType: args[0]}) return nil, err } @@ -143,12 +133,7 @@ func generateScript( _ flowkit.Services, state *flowkit.State, ) (result command.Result, err error) { - options := GeneratorOptions{ - Directory: DefaultCadenceDirectory, - State: state, - Logger: logger, - } - generator := NewGenerator(options) + generator := NewGenerator(DefaultCadenceDirectory, state, logger, false) err = generator.Create(TemplateMap{ScriptType: args[0]}) return nil, err } @@ -156,20 +141,19 @@ func generateScript( // TemplateMap defines a map of template types to their specific names type TemplateMap map[string]string -type GeneratorOptions struct { +type Generator struct { Directory string State *flowkit.State Logger output.Logger DisableLogs bool } -type Generator struct { - Options GeneratorOptions -} - -func NewGenerator(options GeneratorOptions) *Generator { +func NewGenerator(directory string, state *flowkit.State, logger output.Logger, disableLogs bool) *Generator { return &Generator{ - Options: options, + Directory: directory, + State: state, + Logger: logger, + DisableLogs: disableLogs, } } @@ -195,8 +179,8 @@ func (g *Generator) generate(templateType, name string) error { var testsBasePath = "tests" var err error - if g.Options.Directory != "" { - rootDir = g.Options.Directory + if g.Directory != "" { + rootDir = g.Directory } switch templateType { @@ -232,44 +216,44 @@ func (g *Generator) generate(templateType, name string) error { filenameWithBasePath := filepath.Join(rootDir, basePath, filename) // Check file existence - if _, err := g.Options.State.ReaderWriter().ReadFile(filenameWithBasePath); err == nil { + if _, err := g.State.ReaderWriter().ReadFile(filenameWithBasePath); err == nil { return fmt.Errorf("file already exists: %s", filenameWithBasePath) } // Ensure the directory exists - if err := g.Options.State.ReaderWriter().MkdirAll(directoryWithBasePath, 0755); err != nil { + if err := g.State.ReaderWriter().MkdirAll(directoryWithBasePath, 0755); err != nil { return fmt.Errorf("error creating directories: %w", err) } // Write files - err = g.Options.State.ReaderWriter().WriteFile(filenameWithBasePath, []byte(fileToWrite), 0644) + err = g.State.ReaderWriter().WriteFile(filenameWithBasePath, []byte(fileToWrite), 0644) if err != nil { return fmt.Errorf("error writing file: %w", err) } - if !g.Options.DisableLogs { - g.Options.Logger.Info(fmt.Sprintf("Generated new %s: %s at %s", templateType, name, filenameWithBasePath)) + if !g.DisableLogs { + g.Logger.Info(fmt.Sprintf("Generated new %s: %s at %s", templateType, name, filenameWithBasePath)) } if generateFlags.SkipTests != true && templateType == ContractType { testDirectoryWithBasePath := filepath.Join(rootDir, testsBasePath) testFilenameWithBasePath := filepath.Join(rootDir, testsBasePath, util.AddCDCExtension(fmt.Sprintf("%s_test", name))) - if _, err := g.Options.State.ReaderWriter().ReadFile(testFilenameWithBasePath); err == nil { + if _, err := g.State.ReaderWriter().ReadFile(testFilenameWithBasePath); err == nil { return fmt.Errorf("file already exists: %s", testFilenameWithBasePath) } - if err := g.Options.State.ReaderWriter().MkdirAll(testDirectoryWithBasePath, 0755); err != nil { + if err := g.State.ReaderWriter().MkdirAll(testDirectoryWithBasePath, 0755); err != nil { return fmt.Errorf("error creating test directory: %w", err) } - err := g.Options.State.ReaderWriter().WriteFile(testFilenameWithBasePath, []byte(testFileToWrite), 0644) + err := g.State.ReaderWriter().WriteFile(testFilenameWithBasePath, []byte(testFileToWrite), 0644) if err != nil { return fmt.Errorf("error writing test file: %w", err) } - if !g.Options.DisableLogs { - g.Options.Logger.Info(fmt.Sprintf("Generated new test file: %s at %s", name, testFilenameWithBasePath)) + if !g.DisableLogs { + g.Logger.Info(fmt.Sprintf("Generated new test file: %s at %s", name, testFilenameWithBasePath)) } } @@ -299,8 +283,8 @@ func (g *Generator) updateContractsState(name, location string) error { Aliases: aliases, } - g.Options.State.Contracts().AddOrUpdate(contract) - err := g.Options.State.SaveDefault() + g.State.Contracts().AddOrUpdate(contract) + err := g.State.SaveDefault() if err != nil { return fmt.Errorf("error saving to flow.json: %w", err) } diff --git a/internal/super/generate_test.go b/internal/super/generate_test.go index af64393a3..755bd4488 100644 --- a/internal/super/generate_test.go +++ b/internal/super/generate_test.go @@ -34,12 +34,7 @@ func TestGenerateNewContract(t *testing.T) { logger := output.NewStdoutLogger(output.NoneLog) _, state, _ := util.TestMocks(t) - options := GeneratorOptions{ - Directory: "cadence", - State: state, - Logger: logger, - } - generator := NewGenerator(options) + generator := NewGenerator("cadence", state, logger, false) // Test contract generation err := generator.Create(TemplateMap{"contract": "TestContract"}) @@ -77,12 +72,7 @@ access(all) fun testContract() { assert.Equal(t, expectedTestContent, util.NormalizeLineEndings(string(testContent))) // Test file already exists scenario - optionsTwo := GeneratorOptions{ - Directory: "cadence", - State: state, - Logger: logger, - } - generatorTwo := NewGenerator(optionsTwo) + generatorTwo := NewGenerator("cadence", state, logger, false) err = generatorTwo.Create(TemplateMap{"contract": "TestContract"}) assert.Error(t, err) expectedError := fmt.Sprintf("file already exists: %s", filepath.FromSlash("cadence/contracts/TestContract.cdc")) @@ -95,12 +85,7 @@ func TestGenerateNewContractSkipTests(t *testing.T) { generateFlags.SkipTests = true - options := GeneratorOptions{ - Directory: "cadence", - State: state, - Logger: logger, - } - generator := NewGenerator(options) + generator := NewGenerator("cadence", state, logger, false) t.Cleanup(func() { generateFlags.SkipTests = false }) @@ -123,12 +108,7 @@ func TestGenerateNewContractWithCDCExtension(t *testing.T) { _, state, _ := util.TestMocks(t) // Test contract generation - options := GeneratorOptions{ - Directory: "cadence", - State: state, - Logger: logger, - } - generator := NewGenerator(options) + generator := NewGenerator("cadence", state, logger, false) err := generator.Create(TemplateMap{"contract": "Tester.cdc"}) assert.NoError(t, err, "Failed to generate contract") @@ -146,12 +126,7 @@ func TestGenerateNewContractFileAlreadyExists(t *testing.T) { _, state, _ := util.TestMocks(t) // Test contract generation - options := GeneratorOptions{ - Directory: "cadence", - State: state, - Logger: logger, - } - generator := NewGenerator(options) + generator := NewGenerator("cadence", state, logger, false) err := generator.Create(TemplateMap{"contract": "TestContract"}) assert.NoError(t, err, "Failed to generate contract") @@ -161,12 +136,7 @@ func TestGenerateNewContractFileAlreadyExists(t *testing.T) { assert.NotNil(t, content) // Test file already exists scenario - optionsTwo := GeneratorOptions{ - Directory: "cadence", - State: state, - Logger: logger, - } - generatorTwo := NewGenerator(optionsTwo) + generatorTwo := NewGenerator("cadence", state, logger, false) err = generatorTwo.Create(TemplateMap{"contract": "TestContract"}) assert.Error(t, err) expectedError := fmt.Sprintf("file already exists: %s", filepath.FromSlash("cadence/contracts/TestContract.cdc")) @@ -177,12 +147,7 @@ func TestGenerateNewContractWithFileExtension(t *testing.T) { logger := output.NewStdoutLogger(output.NoneLog) _, state, _ := util.TestMocks(t) - options := GeneratorOptions{ - Directory: "cadence", - State: state, - Logger: logger, - } - generator := NewGenerator(options) + generator := NewGenerator("cadence", state, logger, false) err := generator.Create(TemplateMap{"contract": "TestContract.cdc"}) assert.NoError(t, err, "Failed to generate contract") @@ -196,12 +161,7 @@ func TestGenerateNewScript(t *testing.T) { logger := output.NewStdoutLogger(output.NoneLog) _, state, _ := util.TestMocks(t) - options := GeneratorOptions{ - Directory: "cadence", - State: state, - Logger: logger, - } - generator := NewGenerator(options) + generator := NewGenerator("cadence", state, logger, false) err := generator.Create(TemplateMap{"script": "TestScript"}) assert.NoError(t, err, "Failed to generate contract") @@ -220,12 +180,7 @@ func TestGenerateNewTransaction(t *testing.T) { logger := output.NewStdoutLogger(output.NoneLog) _, state, _ := util.TestMocks(t) - options := GeneratorOptions{ - Directory: "cadence", - State: state, - Logger: logger, - } - generator := NewGenerator(options) + generator := NewGenerator("cadence", state, logger, false) err := generator.Create(TemplateMap{"transaction": "TestTransaction"}) assert.NoError(t, err, "Failed to generate contract") @@ -245,12 +200,7 @@ func TestGenerateNewWithDirFlag(t *testing.T) { logger := output.NewStdoutLogger(output.NoneLog) _, state, _ := util.TestMocks(t) - options := GeneratorOptions{ - Directory: "customDir", - State: state, - Logger: logger, - } - generator := NewGenerator(options) + generator := NewGenerator("customDir", state, logger, false) err := generator.Create(TemplateMap{"contract": "TestContract"}) assert.NoError(t, err, "Failed to generate contract") diff --git a/internal/super/setup.go b/internal/super/setup.go index 9168204ad..28f1082c2 100644 --- a/internal/super/setup.go +++ b/internal/super/setup.go @@ -160,13 +160,7 @@ func startInteractiveSetup( "transaction": "DefaultTransaction", } - options := GeneratorOptions{ - Directory: directoryPath, - State: state, - Logger: logger, - DisableLogs: true, - } - generator := NewGenerator(options) + generator := NewGenerator(directoryPath, state, logger, true) err = generator.Create(templates) if err != nil { return "", err From 11d22ae46de79c008e7772bd8325757ef323af42 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Fri, 3 May 2024 11:33:41 -0700 Subject: [PATCH 49/86] Change template types to be categorized --- internal/super/generate.go | 18 ++++++++++-------- internal/super/generate_test.go | 20 ++++++++++---------- internal/super/setup.go | 6 +++--- 3 files changed, 23 insertions(+), 21 deletions(-) diff --git a/internal/super/generate.go b/internal/super/generate.go index 23523c877..578f7ed69 100644 --- a/internal/super/generate.go +++ b/internal/super/generate.go @@ -110,7 +110,7 @@ func generateContract( state *flowkit.State, ) (result command.Result, err error) { generator := NewGenerator(DefaultCadenceDirectory, state, logger, false) - err = generator.Create(TemplateMap{ContractType: args[0]}) + err = generator.Create(TemplateMap{ContractType: []string{args[0]}}) return nil, err } @@ -122,7 +122,7 @@ func generateTransaction( state *flowkit.State, ) (result command.Result, err error) { generator := NewGenerator(DefaultCadenceDirectory, state, logger, false) - err = generator.Create(TemplateMap{TransactionType: args[0]}) + err = generator.Create(TemplateMap{TransactionType: []string{args[0]}}) return nil, err } @@ -134,12 +134,12 @@ func generateScript( state *flowkit.State, ) (result command.Result, err error) { generator := NewGenerator(DefaultCadenceDirectory, state, logger, false) - err = generator.Create(TemplateMap{ScriptType: args[0]}) + err = generator.Create(TemplateMap{ScriptType: []string{args[0]}}) return nil, err } // TemplateMap defines a map of template types to their specific names -type TemplateMap map[string]string +type TemplateMap map[string][]string type Generator struct { Directory string @@ -158,10 +158,12 @@ func NewGenerator(directory string, state *flowkit.State, logger output.Logger, } func (g *Generator) Create(typeNames TemplateMap) error { - for templateType, name := range typeNames { - err := g.generate(templateType, name) - if err != nil { - return err + for templateType, names := range typeNames { + for _, name := range names { + err := g.generate(templateType, name) + if err != nil { + return err + } } } return nil diff --git a/internal/super/generate_test.go b/internal/super/generate_test.go index 755bd4488..5a9400cc0 100644 --- a/internal/super/generate_test.go +++ b/internal/super/generate_test.go @@ -37,7 +37,7 @@ func TestGenerateNewContract(t *testing.T) { generator := NewGenerator("cadence", state, logger, false) // Test contract generation - err := generator.Create(TemplateMap{"contract": "TestContract"}) + err := generator.Create(TemplateMap{"contract": []string{"TestContract"}}) assert.NoError(t, err, "Failed to generate contract") fileContent, err := state.ReaderWriter().ReadFile("cadence/contracts/TestContract.cdc") @@ -73,7 +73,7 @@ access(all) fun testContract() { // Test file already exists scenario generatorTwo := NewGenerator("cadence", state, logger, false) - err = generatorTwo.Create(TemplateMap{"contract": "TestContract"}) + err = generatorTwo.Create(TemplateMap{"contract": []string{"TestContract"}}) assert.Error(t, err) expectedError := fmt.Sprintf("file already exists: %s", filepath.FromSlash("cadence/contracts/TestContract.cdc")) assert.Equal(t, expectedError, err.Error()) @@ -91,7 +91,7 @@ func TestGenerateNewContractSkipTests(t *testing.T) { }) // Test contract generation - err := generator.Create(TemplateMap{"contract": "TestContract"}) + err := generator.Create(TemplateMap{"contract": []string{"TestContract"}}) assert.NoError(t, err, "Failed to generate contract") fileContent, err := state.ReaderWriter().ReadFile("cadence/contracts/TestContract.cdc") @@ -109,7 +109,7 @@ func TestGenerateNewContractWithCDCExtension(t *testing.T) { // Test contract generation generator := NewGenerator("cadence", state, logger, false) - err := generator.Create(TemplateMap{"contract": "Tester.cdc"}) + err := generator.Create(TemplateMap{"contract": []string{"Tester.cdc"}}) assert.NoError(t, err, "Failed to generate contract") fileContent, err := state.ReaderWriter().ReadFile("cadence/contracts/Tester.cdc") @@ -127,7 +127,7 @@ func TestGenerateNewContractFileAlreadyExists(t *testing.T) { // Test contract generation generator := NewGenerator("cadence", state, logger, false) - err := generator.Create(TemplateMap{"contract": "TestContract"}) + err := generator.Create(TemplateMap{"contract": []string{"TestContract"}}) assert.NoError(t, err, "Failed to generate contract") //// Check if the file exists in the correct directory @@ -137,7 +137,7 @@ func TestGenerateNewContractFileAlreadyExists(t *testing.T) { // Test file already exists scenario generatorTwo := NewGenerator("cadence", state, logger, false) - err = generatorTwo.Create(TemplateMap{"contract": "TestContract"}) + err = generatorTwo.Create(TemplateMap{"contract": []string{"TestContract"}}) assert.Error(t, err) expectedError := fmt.Sprintf("file already exists: %s", filepath.FromSlash("cadence/contracts/TestContract.cdc")) assert.Equal(t, expectedError, err.Error()) @@ -148,7 +148,7 @@ func TestGenerateNewContractWithFileExtension(t *testing.T) { _, state, _ := util.TestMocks(t) generator := NewGenerator("cadence", state, logger, false) - err := generator.Create(TemplateMap{"contract": "TestContract.cdc"}) + err := generator.Create(TemplateMap{"contract": []string{"TestContract.cdc"}}) assert.NoError(t, err, "Failed to generate contract") // Check file exists @@ -162,7 +162,7 @@ func TestGenerateNewScript(t *testing.T) { _, state, _ := util.TestMocks(t) generator := NewGenerator("cadence", state, logger, false) - err := generator.Create(TemplateMap{"script": "TestScript"}) + err := generator.Create(TemplateMap{"script": []string{"TestScript"}}) assert.NoError(t, err, "Failed to generate contract") content, err := state.ReaderWriter().ReadFile("cadence/scripts/TestScript.cdc") @@ -181,7 +181,7 @@ func TestGenerateNewTransaction(t *testing.T) { _, state, _ := util.TestMocks(t) generator := NewGenerator("cadence", state, logger, false) - err := generator.Create(TemplateMap{"transaction": "TestTransaction"}) + err := generator.Create(TemplateMap{"transaction": []string{"TestTransaction"}}) assert.NoError(t, err, "Failed to generate contract") content, err := state.ReaderWriter().ReadFile("cadence/transactions/TestTransaction.cdc") @@ -201,7 +201,7 @@ func TestGenerateNewWithDirFlag(t *testing.T) { _, state, _ := util.TestMocks(t) generator := NewGenerator("customDir", state, logger, false) - err := generator.Create(TemplateMap{"contract": "TestContract"}) + err := generator.Create(TemplateMap{"contract": []string{"TestContract"}}) assert.NoError(t, err, "Failed to generate contract") content, err := state.ReaderWriter().ReadFile("customDir/contracts/TestContract.cdc") diff --git a/internal/super/setup.go b/internal/super/setup.go index 28f1082c2..685823eff 100644 --- a/internal/super/setup.go +++ b/internal/super/setup.go @@ -155,9 +155,9 @@ func startInteractiveSetup( directoryPath := filepath.Join(tempDir, "cadence") templates := TemplateMap{ - "contract": "DefaultContract", - "script": "DefaultScripts", - "transaction": "DefaultTransaction", + "contract": []string{"DefaultContract"}, + "script": []string{"DefaultScripts"}, + "transaction": []string{"DefaultTransaction"}, } generator := NewGenerator(directoryPath, state, logger, true) From 857a4839e146e48bd3758b0fe691a55e66a5a547 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Fri, 3 May 2024 12:09:41 -0700 Subject: [PATCH 50/86] Make private --- internal/super/generate.go | 44 +++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/internal/super/generate.go b/internal/super/generate.go index 578f7ed69..11c759b05 100644 --- a/internal/super/generate.go +++ b/internal/super/generate.go @@ -142,18 +142,18 @@ func generateScript( type TemplateMap map[string][]string type Generator struct { - Directory string - State *flowkit.State - Logger output.Logger - DisableLogs bool + directory string + state *flowkit.State + logger output.Logger + disableLogs bool } func NewGenerator(directory string, state *flowkit.State, logger output.Logger, disableLogs bool) *Generator { return &Generator{ - Directory: directory, - State: state, - Logger: logger, - DisableLogs: disableLogs, + directory: directory, + state: state, + logger: logger, + disableLogs: disableLogs, } } @@ -181,8 +181,8 @@ func (g *Generator) generate(templateType, name string) error { var testsBasePath = "tests" var err error - if g.Directory != "" { - rootDir = g.Directory + if g.directory != "" { + rootDir = g.directory } switch templateType { @@ -218,44 +218,44 @@ func (g *Generator) generate(templateType, name string) error { filenameWithBasePath := filepath.Join(rootDir, basePath, filename) // Check file existence - if _, err := g.State.ReaderWriter().ReadFile(filenameWithBasePath); err == nil { + if _, err := g.state.ReaderWriter().ReadFile(filenameWithBasePath); err == nil { return fmt.Errorf("file already exists: %s", filenameWithBasePath) } // Ensure the directory exists - if err := g.State.ReaderWriter().MkdirAll(directoryWithBasePath, 0755); err != nil { + if err := g.state.ReaderWriter().MkdirAll(directoryWithBasePath, 0755); err != nil { return fmt.Errorf("error creating directories: %w", err) } // Write files - err = g.State.ReaderWriter().WriteFile(filenameWithBasePath, []byte(fileToWrite), 0644) + err = g.state.ReaderWriter().WriteFile(filenameWithBasePath, []byte(fileToWrite), 0644) if err != nil { return fmt.Errorf("error writing file: %w", err) } - if !g.DisableLogs { - g.Logger.Info(fmt.Sprintf("Generated new %s: %s at %s", templateType, name, filenameWithBasePath)) + if !g.disableLogs { + g.logger.Info(fmt.Sprintf("Generated new %s: %s at %s", templateType, name, filenameWithBasePath)) } if generateFlags.SkipTests != true && templateType == ContractType { testDirectoryWithBasePath := filepath.Join(rootDir, testsBasePath) testFilenameWithBasePath := filepath.Join(rootDir, testsBasePath, util.AddCDCExtension(fmt.Sprintf("%s_test", name))) - if _, err := g.State.ReaderWriter().ReadFile(testFilenameWithBasePath); err == nil { + if _, err := g.state.ReaderWriter().ReadFile(testFilenameWithBasePath); err == nil { return fmt.Errorf("file already exists: %s", testFilenameWithBasePath) } - if err := g.State.ReaderWriter().MkdirAll(testDirectoryWithBasePath, 0755); err != nil { + if err := g.state.ReaderWriter().MkdirAll(testDirectoryWithBasePath, 0755); err != nil { return fmt.Errorf("error creating test directory: %w", err) } - err := g.State.ReaderWriter().WriteFile(testFilenameWithBasePath, []byte(testFileToWrite), 0644) + err := g.state.ReaderWriter().WriteFile(testFilenameWithBasePath, []byte(testFileToWrite), 0644) if err != nil { return fmt.Errorf("error writing test file: %w", err) } - if !g.DisableLogs { - g.Logger.Info(fmt.Sprintf("Generated new test file: %s at %s", name, testFilenameWithBasePath)) + if !g.disableLogs { + g.logger.Info(fmt.Sprintf("Generated new test file: %s at %s", name, testFilenameWithBasePath)) } } @@ -285,8 +285,8 @@ func (g *Generator) updateContractsState(name, location string) error { Aliases: aliases, } - g.State.Contracts().AddOrUpdate(contract) - err := g.State.SaveDefault() + g.state.Contracts().AddOrUpdate(contract) + err := g.state.SaveDefault() if err != nil { return fmt.Errorf("error saving to flow.json: %w", err) } From d17f617086fd7ab72a05ce40a54692f8cec2c46a Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Fri, 3 May 2024 14:02:08 -0700 Subject: [PATCH 51/86] Change contract state to relative path --- internal/super/generate.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/internal/super/generate.go b/internal/super/generate.go index 11c759b05..839e38753 100644 --- a/internal/super/generate.go +++ b/internal/super/generate.go @@ -216,6 +216,7 @@ func (g *Generator) generate(templateType, name string) error { directoryWithBasePath := filepath.Join(rootDir, basePath) filenameWithBasePath := filepath.Join(rootDir, basePath, filename) + relativeFilenameWithBasePath := filepath.Join(basePath, filename) // Check file existence if _, err := g.state.ReaderWriter().ReadFile(filenameWithBasePath); err == nil { @@ -260,7 +261,7 @@ func (g *Generator) generate(templateType, name string) error { } if templateType == ContractType { - err := g.updateContractsState(name, filenameWithBasePath) + err := g.updateContractsState(name, relativeFilenameWithBasePath) if err != nil { return err } From 73d1f46d62b97b5ee780394fe10ea4394cd1fd1b Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Mon, 6 May 2024 10:34:06 -0700 Subject: [PATCH 52/86] Misc messaging improvements --- internal/config/init.go | 2 -- internal/prompt/select-options.go | 2 +- internal/super/setup.go | 3 +++ 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/internal/config/init.go b/internal/config/init.go index c7ea5fe47..a9015985e 100644 --- a/internal/config/init.go +++ b/internal/config/init.go @@ -65,8 +65,6 @@ type InitConfigParameters struct { // InitializeConfiguration creates the Flow configuration json file based on the provided parameters. func InitializeConfiguration(params InitConfigParameters, logger output.Logger, readerWriter flowkit.ReaderWriter) (*flowkit.State, error) { - logger.Info("⚠️Notice: for starting a new project prefer using 'flow setup'.") - sigAlgo := crypto.StringToSignatureAlgorithm(params.ServiceKeySigAlgo) if sigAlgo == crypto.UnknownSignatureAlgorithm { return nil, fmt.Errorf("invalid signature algorithm: %s", params.ServiceKeySigAlgo) diff --git a/internal/prompt/select-options.go b/internal/prompt/select-options.go index 63c4c06e1..747a37c75 100644 --- a/internal/prompt/select-options.go +++ b/internal/prompt/select-options.go @@ -81,7 +81,7 @@ func (m optionSelectModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { func (m optionSelectModel) View() string { var b strings.Builder - b.WriteString(fmt.Sprintf("%s.\n", m.message)) + b.WriteString(fmt.Sprintf("%s\n", m.message)) b.WriteString("Use arrow keys to navigate, space to select, enter to confirm, q to quit:\n\n") for i, choice := range m.choices { if m.cursor == i { diff --git a/internal/super/setup.go b/internal/super/setup.go index 685823eff..355df45cb 100644 --- a/internal/super/setup.go +++ b/internal/super/setup.go @@ -21,6 +21,7 @@ package super import ( "bytes" "fmt" + "github.com/onflow/flow-cli/internal/util" "io" "os" "path/filepath" @@ -197,6 +198,8 @@ func startInteractiveSetup( } } + logger.Info(util.MessageWithEmojiPrefix("🔄", "Installing selected core contracts and dependencies...")) + // Add the selected core contracts as dependencies installer, err := dependencymanager.NewDependencyInstaller(logger, state, false, tempDir, dependencymanager.Flags{}) if err != nil { From c12bb771f632305b3ee8c68c951f3fa6d4aeb735 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Mon, 6 May 2024 10:44:40 -0700 Subject: [PATCH 53/86] Go imports fix --- internal/super/setup.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/internal/super/setup.go b/internal/super/setup.go index 355df45cb..39585f854 100644 --- a/internal/super/setup.go +++ b/internal/super/setup.go @@ -21,11 +21,12 @@ package super import ( "bytes" "fmt" - "github.com/onflow/flow-cli/internal/util" "io" "os" "path/filepath" + "github.com/onflow/flow-cli/internal/util" + flowsdk "github.com/onflow/flow-go-sdk" "golang.org/x/exp/slices" From c8402c30a690c259bacd132388b64d835761b287 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Mon, 6 May 2024 11:24:40 -0700 Subject: [PATCH 54/86] Fix blocking command error --- internal/super/setup.go | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/internal/super/setup.go b/internal/super/setup.go index 39585f854..5c8241efd 100644 --- a/internal/super/setup.go +++ b/internal/super/setup.go @@ -21,6 +21,8 @@ package super import ( "bytes" "fmt" + "github.com/onflow/flow-go-sdk/crypto" + "github.com/spf13/afero" "io" "os" "path/filepath" @@ -65,15 +67,15 @@ var SetupCommand = &command.Command{ GroupID: "super", }, Flags: &setupFlags, - RunS: create, + Run: create, } func create( args []string, _ command.GlobalFlags, logger output.Logger, + _ flowkit.ReaderWriter, _ flowkit.Services, - state *flowkit.State, ) (command.Result, error) { var targetDir string var err error @@ -89,7 +91,7 @@ func create( return nil, err } } else { - targetDir, err = startInteractiveSetup(args, logger, state) + targetDir, err = startInteractiveSetup(args, logger) if err != nil { return nil, err } @@ -101,11 +103,18 @@ func create( func startInteractiveSetup( args []string, logger output.Logger, - state *flowkit.State, ) (string, error) { var targetDir string var err error + rw := afero.Afero{ + Fs: afero.NewOsFs(), + } + state, err := flowkit.Init(rw, crypto.ECDSA_P256, crypto.SHA3_256) + if err != nil { + os.Exit(1) + } + // Ask for project name if not given if len(args) < 1 { userInput, err := prompt.RunTextInput("Enter the name of your project", "Type your project name here...") From 95bee6c3455d67cfdecbb51c8dd15c9fd2f8ce15 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Mon, 6 May 2024 11:25:43 -0700 Subject: [PATCH 55/86] Run goimports fix --- internal/super/setup.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/internal/super/setup.go b/internal/super/setup.go index 5c8241efd..fadcff6c3 100644 --- a/internal/super/setup.go +++ b/internal/super/setup.go @@ -21,12 +21,13 @@ package super import ( "bytes" "fmt" - "github.com/onflow/flow-go-sdk/crypto" - "github.com/spf13/afero" "io" "os" "path/filepath" + "github.com/onflow/flow-go-sdk/crypto" + "github.com/spf13/afero" + "github.com/onflow/flow-cli/internal/util" flowsdk "github.com/onflow/flow-go-sdk" From 7a79071ebf1eef9cd9d05639b04a37fcca47429d Mon Sep 17 00:00:00 2001 From: Chase Fleming Date: Mon, 6 May 2024 11:50:52 -0700 Subject: [PATCH 56/86] Update internal/super/setup.go Co-authored-by: Jordan Ribbink --- internal/super/setup.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/internal/super/setup.go b/internal/super/setup.go index fadcff6c3..e6f065687 100644 --- a/internal/super/setup.go +++ b/internal/super/setup.go @@ -112,9 +112,7 @@ func startInteractiveSetup( Fs: afero.NewOsFs(), } state, err := flowkit.Init(rw, crypto.ECDSA_P256, crypto.SHA3_256) - if err != nil { - os.Exit(1) - } + return err // Ask for project name if not given if len(args) < 1 { From a0d92b357ecafd4dd0649ecd648139595f159dd1 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Mon, 6 May 2024 11:52:46 -0700 Subject: [PATCH 57/86] Fix error --- internal/super/setup.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/internal/super/setup.go b/internal/super/setup.go index e6f065687..b5a854e23 100644 --- a/internal/super/setup.go +++ b/internal/super/setup.go @@ -112,7 +112,9 @@ func startInteractiveSetup( Fs: afero.NewOsFs(), } state, err := flowkit.Init(rw, crypto.ECDSA_P256, crypto.SHA3_256) - return err + if err != nil { + return "", err + } // Ask for project name if not given if len(args) < 1 { From fdece34101c46e1bab2ac88e90f9986eb3246ac6 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Mon, 6 May 2024 14:46:39 -0700 Subject: [PATCH 58/86] Generate contract in account if given --- internal/super/generate.go | 64 ++++++++++++++++++++++++++------- internal/super/generate_test.go | 39 ++++++++++++++------ internal/super/setup.go | 12 +++++-- 3 files changed, 90 insertions(+), 25 deletions(-) diff --git a/internal/super/generate.go b/internal/super/generate.go index 839e38753..590bf6080 100644 --- a/internal/super/generate.go +++ b/internal/super/generate.go @@ -110,7 +110,8 @@ func generateContract( state *flowkit.State, ) (result command.Result, err error) { generator := NewGenerator(DefaultCadenceDirectory, state, logger, false) - err = generator.Create(TemplateMap{ContractType: []string{args[0]}}) + contract := Contract{Name: args[0], Account: args[1]} + err = generator.Create(TemplateMap{ContractType: []TemplateItem{contract}}) return nil, err } @@ -122,7 +123,8 @@ func generateTransaction( state *flowkit.State, ) (result command.Result, err error) { generator := NewGenerator(DefaultCadenceDirectory, state, logger, false) - err = generator.Create(TemplateMap{TransactionType: []string{args[0]}}) + transaction := OtherTemplate{Name: args[0]} + err = generator.Create(TemplateMap{TransactionType: []TemplateItem{transaction}}) return nil, err } @@ -134,12 +136,50 @@ func generateScript( state *flowkit.State, ) (result command.Result, err error) { generator := NewGenerator(DefaultCadenceDirectory, state, logger, false) - err = generator.Create(TemplateMap{ScriptType: []string{args[0]}}) + script := OtherTemplate{Name: args[0]} + err = generator.Create(TemplateMap{ScriptType: []TemplateItem{script}}) return nil, err } -// TemplateMap defines a map of template types to their specific names -type TemplateMap map[string][]string +// TemplateItem is an interface for different template types +type TemplateItem interface { + GetName() string + GetAccount() string +} + +// Contract contains properties for contracts +type Contract struct { + Name string + Account string +} + +// GetName returns the name of the contract +func (c Contract) GetName() string { + return c.Name +} + +// GetAccount returns the account of the contract +func (c Contract) GetAccount() string { + return c.Account +} + +// OtherTemplate contains only a name property for scripts and transactions +type OtherTemplate struct { + Name string +} + +// GetName returns the name of the script or transaction +func (o OtherTemplate) GetName() string { + return o.Name +} + +// GetAccount returns an empty string for scripts and transactions +func (o OtherTemplate) GetAccount() string { + return "" +} + +// TemplateMap holds all templates with flexibility +type TemplateMap map[string][]TemplateItem type Generator struct { directory string @@ -158,9 +198,9 @@ func NewGenerator(directory string, state *flowkit.State, logger output.Logger, } func (g *Generator) Create(typeNames TemplateMap) error { - for templateType, names := range typeNames { - for _, name := range names { - err := g.generate(templateType, name) + for templateType, items := range typeNames { + for _, item := range items { + err := g.generate(templateType, item.GetName(), item.GetAccount()) if err != nil { return err } @@ -169,7 +209,7 @@ func (g *Generator) Create(typeNames TemplateMap) error { return nil } -func (g *Generator) generate(templateType, name string) error { +func (g *Generator) generate(templateType, name, account string) error { name = util.StripCDCExtension(name) filename := util.AddCDCExtension(name) @@ -214,9 +254,9 @@ func (g *Generator) generate(templateType, name string) error { return fmt.Errorf("invalid template type: %s", templateType) } - directoryWithBasePath := filepath.Join(rootDir, basePath) - filenameWithBasePath := filepath.Join(rootDir, basePath, filename) - relativeFilenameWithBasePath := filepath.Join(basePath, filename) + directoryWithBasePath := filepath.Join(rootDir, basePath, account) + filenameWithBasePath := filepath.Join(rootDir, basePath, account, filename) + relativeFilenameWithBasePath := filepath.Join(basePath, account, filename) // Check file existence if _, err := g.state.ReaderWriter().ReadFile(filenameWithBasePath); err == nil { diff --git a/internal/super/generate_test.go b/internal/super/generate_test.go index 5a9400cc0..f1f6f2b70 100644 --- a/internal/super/generate_test.go +++ b/internal/super/generate_test.go @@ -37,7 +37,7 @@ func TestGenerateNewContract(t *testing.T) { generator := NewGenerator("cadence", state, logger, false) // Test contract generation - err := generator.Create(TemplateMap{"contract": []string{"TestContract"}}) + err := generator.Create(TemplateMap{"contract": []TemplateItem{Contract{Name: "TestContract", Account: ""}}}) assert.NoError(t, err, "Failed to generate contract") fileContent, err := state.ReaderWriter().ReadFile("cadence/contracts/TestContract.cdc") @@ -73,12 +73,31 @@ access(all) fun testContract() { // Test file already exists scenario generatorTwo := NewGenerator("cadence", state, logger, false) - err = generatorTwo.Create(TemplateMap{"contract": []string{"TestContract"}}) + err = generatorTwo.Create(TemplateMap{"contract": []TemplateItem{Contract{Name: "TestContract", Account: ""}}}) assert.Error(t, err) expectedError := fmt.Sprintf("file already exists: %s", filepath.FromSlash("cadence/contracts/TestContract.cdc")) assert.Equal(t, expectedError, err.Error()) } +func TestGenerateContractWithAccount(t *testing.T) { + logger := output.NewStdoutLogger(output.NoneLog) + _, state, _ := util.TestMocks(t) + + generator := NewGenerator("cadence", state, logger, false) + + // Test contract generation + err := generator.Create(TemplateMap{"contract": []TemplateItem{Contract{Name: "TestContract", Account: "example-account"}}}) + assert.NoError(t, err, "Failed to generate contract") + + fileContent, err := state.ReaderWriter().ReadFile("cadence/contracts/example-account/TestContract.cdc") + assert.NoError(t, err, "Failed to read generated file") + assert.NotNil(t, fileContent) + + testContent, err := state.ReaderWriter().ReadFile("cadence/tests/TestContract_test.cdc") + assert.NoError(t, err, "Failed to read generated file") + assert.NotNil(t, testContent) +} + func TestGenerateNewContractSkipTests(t *testing.T) { logger := output.NewStdoutLogger(output.NoneLog) _, state, _ := util.TestMocks(t) @@ -91,7 +110,7 @@ func TestGenerateNewContractSkipTests(t *testing.T) { }) // Test contract generation - err := generator.Create(TemplateMap{"contract": []string{"TestContract"}}) + err := generator.Create(TemplateMap{"contract": []TemplateItem{Contract{Name: "TestContract", Account: ""}}}) assert.NoError(t, err, "Failed to generate contract") fileContent, err := state.ReaderWriter().ReadFile("cadence/contracts/TestContract.cdc") @@ -109,7 +128,7 @@ func TestGenerateNewContractWithCDCExtension(t *testing.T) { // Test contract generation generator := NewGenerator("cadence", state, logger, false) - err := generator.Create(TemplateMap{"contract": []string{"Tester.cdc"}}) + err := generator.Create(TemplateMap{"contract": []TemplateItem{Contract{Name: "Tester.cdc", Account: ""}}}) assert.NoError(t, err, "Failed to generate contract") fileContent, err := state.ReaderWriter().ReadFile("cadence/contracts/Tester.cdc") @@ -127,7 +146,7 @@ func TestGenerateNewContractFileAlreadyExists(t *testing.T) { // Test contract generation generator := NewGenerator("cadence", state, logger, false) - err := generator.Create(TemplateMap{"contract": []string{"TestContract"}}) + err := generator.Create(TemplateMap{"contract": []TemplateItem{Contract{Name: "TestContract", Account: ""}}}) assert.NoError(t, err, "Failed to generate contract") //// Check if the file exists in the correct directory @@ -137,7 +156,7 @@ func TestGenerateNewContractFileAlreadyExists(t *testing.T) { // Test file already exists scenario generatorTwo := NewGenerator("cadence", state, logger, false) - err = generatorTwo.Create(TemplateMap{"contract": []string{"TestContract"}}) + err = generatorTwo.Create(TemplateMap{"contract": []TemplateItem{Contract{Name: "TestContract", Account: ""}}}) assert.Error(t, err) expectedError := fmt.Sprintf("file already exists: %s", filepath.FromSlash("cadence/contracts/TestContract.cdc")) assert.Equal(t, expectedError, err.Error()) @@ -148,7 +167,7 @@ func TestGenerateNewContractWithFileExtension(t *testing.T) { _, state, _ := util.TestMocks(t) generator := NewGenerator("cadence", state, logger, false) - err := generator.Create(TemplateMap{"contract": []string{"TestContract.cdc"}}) + err := generator.Create(TemplateMap{"contract": []TemplateItem{Contract{Name: "TestContract.cdc", Account: ""}}}) assert.NoError(t, err, "Failed to generate contract") // Check file exists @@ -162,7 +181,7 @@ func TestGenerateNewScript(t *testing.T) { _, state, _ := util.TestMocks(t) generator := NewGenerator("cadence", state, logger, false) - err := generator.Create(TemplateMap{"script": []string{"TestScript"}}) + err := generator.Create(TemplateMap{"script": []TemplateItem{OtherTemplate{Name: "TestScript"}}}) assert.NoError(t, err, "Failed to generate contract") content, err := state.ReaderWriter().ReadFile("cadence/scripts/TestScript.cdc") @@ -181,7 +200,7 @@ func TestGenerateNewTransaction(t *testing.T) { _, state, _ := util.TestMocks(t) generator := NewGenerator("cadence", state, logger, false) - err := generator.Create(TemplateMap{"transaction": []string{"TestTransaction"}}) + err := generator.Create(TemplateMap{"transaction": []TemplateItem{OtherTemplate{Name: "TestTransaction"}}}) assert.NoError(t, err, "Failed to generate contract") content, err := state.ReaderWriter().ReadFile("cadence/transactions/TestTransaction.cdc") @@ -201,7 +220,7 @@ func TestGenerateNewWithDirFlag(t *testing.T) { _, state, _ := util.TestMocks(t) generator := NewGenerator("customDir", state, logger, false) - err := generator.Create(TemplateMap{"contract": []string{"TestContract"}}) + err := generator.Create(TemplateMap{"contract": []TemplateItem{Contract{Name: "TestContract", Account: ""}}}) assert.NoError(t, err, "Failed to generate contract") content, err := state.ReaderWriter().ReadFile("customDir/contracts/TestContract.cdc") diff --git a/internal/super/setup.go b/internal/super/setup.go index b5a854e23..6089aa8be 100644 --- a/internal/super/setup.go +++ b/internal/super/setup.go @@ -167,9 +167,15 @@ func startInteractiveSetup( directoryPath := filepath.Join(tempDir, "cadence") templates := TemplateMap{ - "contract": []string{"DefaultContract"}, - "script": []string{"DefaultScripts"}, - "transaction": []string{"DefaultTransaction"}, + "contract": []TemplateItem{ + Contract{Name: "DefaultContract", Account: "example-account"}, + }, + "script": []TemplateItem{ + OtherTemplate{Name: "DefaultScripts"}, + }, + "transaction": []TemplateItem{ + OtherTemplate{Name: "DefaultTransaction"}, + }, } generator := NewGenerator(directoryPath, state, logger, true) From 42e4c2ab6da94509f0f711e80468ffc0969b6f3f Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Mon, 6 May 2024 16:00:43 -0700 Subject: [PATCH 59/86] Don't require flag to start emulator with `flow dev` --- internal/super/dev.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/super/dev.go b/internal/super/dev.go index 045b25b51..97265870f 100644 --- a/internal/super/dev.go +++ b/internal/super/dev.go @@ -38,7 +38,7 @@ import ( ) type flagsDev struct { - StartEmulator bool `default:"false" flag:"start-emulator" info:"Start emulator if not already running"` + StartEmulator bool `default:"true" flag:"start-emulator" info:"Start emulator if not already running"` } var devFlags = flagsDev{} From 1fdb27b58cfc2628bd68af5cac20ea8fbd120edc Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Mon, 6 May 2024 16:07:16 -0700 Subject: [PATCH 60/86] Change to disable flag --- internal/super/dev.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/super/dev.go b/internal/super/dev.go index 97265870f..7917dd9d2 100644 --- a/internal/super/dev.go +++ b/internal/super/dev.go @@ -38,7 +38,7 @@ import ( ) type flagsDev struct { - StartEmulator bool `default:"true" flag:"start-emulator" info:"Start emulator if not already running"` + DisableEmulator bool `default:"false" flag:"disable-emulator" info:"Disable the emulator from running by default"` } var devFlags = flagsDev{} @@ -72,7 +72,7 @@ func dev( return nil, err } - if devFlags.StartEmulator { + if !devFlags.DisableEmulator { privateKey, err := serviceAccount.Key.PrivateKey() if err != nil { return nil, fmt.Errorf("failed to get private key: %s", err) From 303b468d8381302f2a5b7f2c57510cf0d88f5601 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Tue, 7 May 2024 11:08:17 -0700 Subject: [PATCH 61/86] Change emulator key to saving in target dir --- cmd/flow/main.go | 2 +- go.mod | 4 +- go.sum | 8 +- internal/accounts/create-interactive.go | 2 +- internal/config/config.go | 2 +- internal/config/init.go | 203 +++++++++++++----------- internal/emulator/start.go | 2 +- internal/quick/init.go | 27 ++-- internal/super/setup.go | 11 +- internal/util/test.go | 2 +- 10 files changed, 133 insertions(+), 130 deletions(-) diff --git a/cmd/flow/main.go b/cmd/flow/main.go index 63ac4f8d3..493aa4692 100644 --- a/cmd/flow/main.go +++ b/cmd/flow/main.go @@ -87,7 +87,7 @@ func main() { } // quick commands - quick.InitCommand.AddToParent(cmd) + //quick.InitCommand.AddToParent(cmd) quick.DeployCommand.AddToParent(cmd) quick.RunCommand.AddToParent(cmd) diff --git a/go.mod b/go.mod index 707652995..02bbf45b1 100644 --- a/go.mod +++ b/go.mod @@ -16,12 +16,12 @@ require ( github.com/onflow/cadence-tools/lint v0.14.2 github.com/onflow/cadence-tools/test v0.14.7 github.com/onflow/fcl-dev-wallet v0.7.4 - github.com/onflow/flixkit-go v1.1.3 + github.com/onflow/flixkit-go v1.1.4-0.20240507174933-7a1de7bbf70f github.com/onflow/flow-core-contracts/lib/go/templates v1.2.4-0.20231016154253-a00dbf7c061f github.com/onflow/flow-emulator v0.62.1 github.com/onflow/flow-go v0.33.2-0.20240412174857-015156b297b5 github.com/onflow/flow-go-sdk v0.46.3 - github.com/onflow/flowkit v1.17.3 + github.com/onflow/flowkit v1.17.4-0.20240507180449-b565ca87f6b8 github.com/onflowser/flowser/v3 v3.1.3 github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c github.com/pkg/errors v0.9.1 diff --git a/go.sum b/go.sum index fb3856c2e..a94ffa91e 100644 --- a/go.sum +++ b/go.sum @@ -936,8 +936,8 @@ github.com/onflow/crypto v0.25.1 h1:0txy2PKPMM873JbpxQNbJmuOJtD56bfs48RQfm0ts5A= github.com/onflow/crypto v0.25.1/go.mod h1:C8FbaX0x8y+FxWjbkHy0Q4EASCDR9bSPWZqlpCLYyVI= github.com/onflow/fcl-dev-wallet v0.7.4 h1:vI6t3U0AO88R/Iitn5KsnniSpbN9Lqsqwvi9EJT4C0k= github.com/onflow/fcl-dev-wallet v0.7.4/go.mod h1:kc42jkiuoPJmxMRFjfbRO9XvnR/3XLheaOerxVMDTiw= -github.com/onflow/flixkit-go v1.1.3 h1:td94mkklIwXvDP075D0eofPE04oKse24PxvFTyOvMJI= -github.com/onflow/flixkit-go v1.1.3/go.mod h1:qOYI1l7r3gSPk6luTnk95ni020UeTY+E48GuB3Tl0xk= +github.com/onflow/flixkit-go v1.1.4-0.20240507174933-7a1de7bbf70f h1:8UEBHYC6mgc2c7U3p2ZoC3R6gupn1oqU61/jURZTsjI= +github.com/onflow/flixkit-go v1.1.4-0.20240507174933-7a1de7bbf70f/go.mod h1:KUk8ODCdwNYF8PBYdu+VBTTrZ1IPWKvVJsdsGsEAtA0= github.com/onflow/flow-core-contracts/lib/go/contracts v1.2.4-0.20231016154253-a00dbf7c061f h1:S8yIZw9LFXfYD1V5H9BiixihHw3GrXVPrmfplSzYaww= github.com/onflow/flow-core-contracts/lib/go/contracts v1.2.4-0.20231016154253-a00dbf7c061f/go.mod h1:jM6GMAL+m0hjusUgiYDNrixPQ6b9s8xjoJQoEu5bHQI= github.com/onflow/flow-core-contracts/lib/go/templates v1.2.4-0.20231016154253-a00dbf7c061f h1:Ep+Mpo2miWMe4pjPGIaEvEzshRep30dvNgxqk+//FrQ= @@ -957,8 +957,8 @@ github.com/onflow/flow-nft/lib/go/contracts v1.1.0/go.mod h1:YsvzYng4htDgRB9sa9j github.com/onflow/flow/protobuf/go/flow v0.2.2/go.mod h1:gQxYqCfkI8lpnKsmIjwtN2mV/N2PIwc1I+RUK4HPIc8= github.com/onflow/flow/protobuf/go/flow v0.4.0 h1:5TGmPwRmnSt7aawgtPGF9ehoGHHir9Cy9LVoAiU9t/E= github.com/onflow/flow/protobuf/go/flow v0.4.0/go.mod h1:NA2pX2nw8zuaxfKphhKsk00kWLwfd+tv8mS23YXO4Sk= -github.com/onflow/flowkit v1.17.3 h1:0Fi3tLnieWOYq95A3ySk3TZ0GUPtKaX8ofssgve9e58= -github.com/onflow/flowkit v1.17.3/go.mod h1:laapt1diM4Pbqt0dotKMH+LbUAOEqgugpH1p4+sPhcw= +github.com/onflow/flowkit v1.17.4-0.20240507180449-b565ca87f6b8 h1:59gqw1cXdvyV+jYbItoqULLxcA1MWrTSzcSsgRIXEto= +github.com/onflow/flowkit v1.17.4-0.20240507180449-b565ca87f6b8/go.mod h1:laapt1diM4Pbqt0dotKMH+LbUAOEqgugpH1p4+sPhcw= github.com/onflow/go-ethereum v1.13.4 h1:iNO86fm8RbBbhZ87ZulblInqCdHnAQVY8okBrNsTevc= github.com/onflow/go-ethereum v1.13.4/go.mod h1:cE/gEUkAffhwbVmMJYz+t1dAfVNHNwZCgc3BWtZxBGY= github.com/onflow/nft-storefront/lib/go/contracts v0.0.0-20221222181731-14b90207cead h1:2j1Unqs76Z1b95Gu4C3Y28hzNUHBix7wL490e61SMSw= diff --git a/internal/accounts/create-interactive.go b/internal/accounts/create-interactive.go index 3adc60083..3b94070f4 100644 --- a/internal/accounts/create-interactive.go +++ b/internal/accounts/create-interactive.go @@ -54,7 +54,7 @@ func createInteractive(state *flowkit.State) (*accountResult, error) { log := output.NewStdoutLogger(output.InfoLog) name := prompt.AccountNamePrompt(state.Accounts().Names()) networkName, selectedNetwork := prompt.CreateAccountNetworkPrompt() - privateFile := accounts.PrivateKeyFile(name) + privateFile := accounts.PrivateKeyFile(name, "") // create new gateway based on chosen network gw, err := gateway.NewGrpcGateway(selectedNetwork) diff --git a/internal/config/config.go b/internal/config/config.go index 3689ca348..17835e7d0 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -29,7 +29,7 @@ var Cmd = &cobra.Command{ } func init() { - initCommand.AddToParent(Cmd) + //initCommand.AddToParent(Cmd) Cmd.AddCommand(addCmd) Cmd.AddCommand(removeCmd) } diff --git a/internal/config/init.go b/internal/config/init.go index a9015985e..30caee78e 100644 --- a/internal/config/init.go +++ b/internal/config/init.go @@ -19,39 +19,31 @@ package config import ( - "bytes" "fmt" - "os" - "github.com/onflow/flow-go-sdk/crypto" - "github.com/spf13/cobra" - "github.com/onflow/flowkit" "github.com/onflow/flowkit/config" - "github.com/onflow/flowkit/output" - - "github.com/onflow/flow-cli/internal/command" - "github.com/onflow/flow-cli/internal/util" + "os" ) -type flagsInit struct { - ServicePrivateKey string `flag:"service-private-key" info:"Service account private key"` - ServiceKeySigAlgo string `default:"ECDSA_P256" flag:"service-sig-algo" info:"Service account key signature algorithm"` - ServiceKeyHashAlgo string `default:"SHA3_256" flag:"service-hash-algo" info:"Service account key hash algorithm"` - Reset bool `default:"false" flag:"reset" info:"Reset configuration file"` - Global bool `default:"false" flag:"global" info:"Initialize global user configuration"` -} - -var InitFlag = flagsInit{} - -var initCommand = &command.Command{ - Cmd: &cobra.Command{ - Use: "init", - Short: "Initialize a new configuration", - }, - Flags: &InitFlag, - Run: Initialise, -} +//type flagsInit struct { +// ServicePrivateKey string `flag:"service-private-key" info:"Service account private key"` +// ServiceKeySigAlgo string `default:"ECDSA_P256" flag:"service-sig-algo" info:"Service account key signature algorithm"` +// ServiceKeyHashAlgo string `default:"SHA3_256" flag:"service-hash-algo" info:"Service account key hash algorithm"` +// Reset bool `default:"false" flag:"reset" info:"Reset configuration file"` +// Global bool `default:"false" flag:"global" info:"Initialize global user configuration"` +//} +// +//var InitFlag = flagsInit{} + +//var initCommand = &command.Command{ +// Cmd: &cobra.Command{ +// Use: "init", +// Short: "Initialize a new configuration", +// }, +// Flags: &InitFlag, +// Run: Initialise, +//} // InitConfigParameters holds all necessary parameters for initializing the configuration. type InitConfigParameters struct { @@ -64,7 +56,25 @@ type InitConfigParameters struct { } // InitializeConfiguration creates the Flow configuration json file based on the provided parameters. -func InitializeConfiguration(params InitConfigParameters, logger output.Logger, readerWriter flowkit.ReaderWriter) (*flowkit.State, error) { +func InitializeConfiguration(params InitConfigParameters, readerWriter flowkit.ReaderWriter) (*flowkit.State, error) { + var path string + if params.TargetDirectory != "" { + path = fmt.Sprintf("%s/flow.json", params.TargetDirectory) + + // Create the directory if it doesn't exist + err := readerWriter.MkdirAll(params.TargetDirectory, os.ModePerm) + if err != nil { + return nil, fmt.Errorf("failed to create target directory: %w", err) + } + } else { + // Otherwise, choose between the default and global paths + if params.Global { + path = config.GlobalPath() + } else { + path = config.DefaultPath + } + } + sigAlgo := crypto.StringToSignatureAlgorithm(params.ServiceKeySigAlgo) if sigAlgo == crypto.UnknownSignatureAlgorithm { return nil, fmt.Errorf("invalid signature algorithm: %s", params.ServiceKeySigAlgo) @@ -75,7 +85,7 @@ func InitializeConfiguration(params InitConfigParameters, logger output.Logger, return nil, fmt.Errorf("invalid hash algorithm: %s", params.ServiceKeyHashAlgo) } - state, err := flowkit.Init(readerWriter, sigAlgo, hashAlgo) + state, err := flowkit.Init(readerWriter, sigAlgo, hashAlgo, params.TargetDirectory) if err != nil { return nil, err } @@ -89,23 +99,23 @@ func InitializeConfiguration(params InitConfigParameters, logger output.Logger, state.SetEmulatorKey(privateKey) } - var path string - if params.TargetDirectory != "" { - path = fmt.Sprintf("%s/flow.json", params.TargetDirectory) - - // Create the directory if it doesn't exist - err := state.ReaderWriter().MkdirAll(params.TargetDirectory, os.ModePerm) - if err != nil { - return nil, fmt.Errorf("failed to create target directory: %w", err) - } - } else { - // Otherwise, choose between the default and global paths - if params.Global { - path = config.GlobalPath() - } else { - path = config.DefaultPath - } - } + //var path string + //if params.TargetDirectory != "" { + // path = fmt.Sprintf("%s/flow.json", params.TargetDirectory) + // + // // Create the directory if it doesn't exist + // err := state.ReaderWriter().MkdirAll(params.TargetDirectory, os.ModePerm) + // if err != nil { + // return nil, fmt.Errorf("failed to create target directory: %w", err) + // } + //} else { + // // Otherwise, choose between the default and global paths + // if params.Global { + // path = config.GlobalPath() + // } else { + // path = config.DefaultPath + // } + //} if config.Exists(path) && !params.Reset { return nil, fmt.Errorf( @@ -122,53 +132,54 @@ func InitializeConfiguration(params InitConfigParameters, logger output.Logger, return state, nil } -func Initialise( - _ []string, - _ command.GlobalFlags, - logger output.Logger, - readerWriter flowkit.ReaderWriter, - _ flowkit.Services, -) (command.Result, error) { - params := InitConfigParameters{ - ServicePrivateKey: InitFlag.ServicePrivateKey, - ServiceKeySigAlgo: InitFlag.ServiceKeySigAlgo, - ServiceKeyHashAlgo: InitFlag.ServiceKeyHashAlgo, - Reset: InitFlag.Reset, - Global: InitFlag.Global, - } - state, err := InitializeConfiguration(params, logger, readerWriter) - if err != nil { - return nil, err - } - - return &InitResult{State: state}, nil -} - -type InitResult struct { - *flowkit.State -} - -func (r *InitResult) JSON() any { - return r -} - -func (r *InitResult) String() string { - var b bytes.Buffer - writer := util.CreateTabWriter(&b) - account, _ := r.State.EmulatorServiceAccount() - - _, _ = fmt.Fprintf(writer, "Configuration initialized\n") - _, _ = fmt.Fprintf(writer, "Service account: %s\n\n", output.Bold("0x"+account.Address.String())) - _, _ = fmt.Fprintf(writer, - "Start emulator by running: %s \nReset configuration using: %s\n", - output.Bold("'flow emulator'"), - output.Bold("'flow init --reset'"), - ) - - _ = writer.Flush() - return b.String() -} - -func (r *InitResult) Oneliner() string { - return "" -} +// +//func Initialise( +// _ []string, +// _ command.GlobalFlags, +// logger output.Logger, +// readerWriter flowkit.ReaderWriter, +// _ flowkit.Services, +//) (command.Result, error) { +// params := InitConfigParameters{ +// ServicePrivateKey: InitFlag.ServicePrivateKey, +// ServiceKeySigAlgo: InitFlag.ServiceKeySigAlgo, +// ServiceKeyHashAlgo: InitFlag.ServiceKeyHashAlgo, +// Reset: InitFlag.Reset, +// Global: InitFlag.Global, +// } +// state, err := InitializeConfiguration(params, logger, readerWriter) +// if err != nil { +// return nil, err +// } +// +// return &InitResult{State: state}, nil +//} +// +//type InitResult struct { +// *flowkit.State +//} +// +//func (r *InitResult) JSON() any { +// return r +//} +// +//func (r *InitResult) String() string { +// var b bytes.Buffer +// writer := util.CreateTabWriter(&b) +// account, _ := r.State.EmulatorServiceAccount() +// +// _, _ = fmt.Fprintf(writer, "Configuration initialized\n") +// _, _ = fmt.Fprintf(writer, "Service account: %s\n\n", output.Bold("0x"+account.Address.String())) +// _, _ = fmt.Fprintf(writer, +// "Start emulator by running: %s \nReset configuration using: %s\n", +// output.Bold("'flow emulator'"), +// output.Bold("'flow init --reset'"), +// ) +// +// _ = writer.Flush() +// return b.String() +//} +// +//func (r *InitResult) Oneliner() string { +// return "" +//} diff --git a/internal/emulator/start.go b/internal/emulator/start.go index 1608d42c5..38420aad9 100644 --- a/internal/emulator/start.go +++ b/internal/emulator/start.go @@ -62,7 +62,7 @@ func configuredServiceKey( hashAlgo = emulator.DefaultServiceKeyHashAlgo } - state, err = flowkit.Init(loader, sigAlgo, hashAlgo) + state, err = flowkit.Init(loader, sigAlgo, hashAlgo, "") if err != nil { exitf(1, err.Error()) } else { diff --git a/internal/quick/init.go b/internal/quick/init.go index 4f9c3df52..ca00f0730 100644 --- a/internal/quick/init.go +++ b/internal/quick/init.go @@ -18,22 +18,15 @@ package quick -import ( - "github.com/spf13/cobra" - - "github.com/onflow/flow-cli/internal/command" - "github.com/onflow/flow-cli/internal/config" -) - // TODO(sideninja) workaround - init needed to be copied in order to work else there is flag duplicate error -var InitCommand = &command.Command{ - Cmd: &cobra.Command{ - Use: "init", - Short: "Initialize a new configuration", - Example: "flow project init", - GroupID: "project", - }, - Flags: &config.InitFlag, - Run: config.Initialise, // TODO(sideninja) workaround - init needed to be copied in order to work else there is flag duplicate error -} +//var InitCommand = &command.Command{ +// Cmd: &cobra.Command{ +// Use: "init", +// Short: "Initialize a new configuration", +// Example: "flow project init", +// GroupID: "project", +// }, +// Flags: &config.InitFlag, +// Run: config.Initialise, // TODO(sideninja) workaround - init needed to be copied in order to work else there is flag duplicate error +//} diff --git a/internal/super/setup.go b/internal/super/setup.go index 6089aa8be..c178f0992 100644 --- a/internal/super/setup.go +++ b/internal/super/setup.go @@ -25,7 +25,6 @@ import ( "os" "path/filepath" - "github.com/onflow/flow-go-sdk/crypto" "github.com/spf13/afero" "github.com/onflow/flow-cli/internal/util" @@ -111,10 +110,10 @@ func startInteractiveSetup( rw := afero.Afero{ Fs: afero.NewOsFs(), } - state, err := flowkit.Init(rw, crypto.ECDSA_P256, crypto.SHA3_256) - if err != nil { - return "", err - } + //state, err := flowkit.Init(rw, crypto.ECDSA_P256, crypto.SHA3_256) + //if err != nil { + // return "", err + //} // Ask for project name if not given if len(args) < 1 { @@ -153,7 +152,7 @@ func startInteractiveSetup( Global: false, TargetDirectory: tempDir, } - state, err = config.InitializeConfiguration(params, logger, state.ReaderWriter()) + state, err := config.InitializeConfiguration(params, rw) if err != nil { return "", fmt.Errorf("failed to initialize configuration: %w", err) } diff --git a/internal/util/test.go b/internal/util/test.go index 9f5be3727..189b4f1c1 100644 --- a/internal/util/test.go +++ b/internal/util/test.go @@ -39,7 +39,7 @@ var TestID = flow.HexToID("24993fc99f81641c45c0afa307e683b4f08d407d90041aa9439f4 func TestMocks(t *testing.T) (*mocks.MockServices, *flowkit.State, flowkit.ReaderWriter) { services := mocks.DefaultMockServices() rw, _ := tests.ReaderWriter() - state, err := flowkit.Init(rw, crypto.ECDSA_P256, crypto.SHA3_256) + state, err := flowkit.Init(rw, crypto.ECDSA_P256, crypto.SHA3_256, "") require.NoError(t, err) return services, state, rw From 5556267f2cd79404b52a6b99b89314ce5e542252 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Tue, 7 May 2024 11:17:44 -0700 Subject: [PATCH 62/86] Make generator saving state optional --- internal/config/init.go | 8 ++++---- internal/super/generate.go | 19 ++++++++++++------- internal/super/generate_test.go | 22 +++++++++++----------- internal/super/setup.go | 2 +- 4 files changed, 28 insertions(+), 23 deletions(-) diff --git a/internal/config/init.go b/internal/config/init.go index 30caee78e..7dc93677b 100644 --- a/internal/config/init.go +++ b/internal/config/init.go @@ -124,10 +124,10 @@ func InitializeConfiguration(params InitConfigParameters, readerWriter flowkit.R ) } - err = state.Save(path) - if err != nil { - return nil, err - } + //err = state.Save(path) + //if err != nil { + // return nil, err + //} return state, nil } diff --git a/internal/super/generate.go b/internal/super/generate.go index 590bf6080..3fb04f3c9 100644 --- a/internal/super/generate.go +++ b/internal/super/generate.go @@ -109,7 +109,7 @@ func generateContract( _ flowkit.Services, state *flowkit.State, ) (result command.Result, err error) { - generator := NewGenerator(DefaultCadenceDirectory, state, logger, false) + generator := NewGenerator(DefaultCadenceDirectory, state, logger, false, true) contract := Contract{Name: args[0], Account: args[1]} err = generator.Create(TemplateMap{ContractType: []TemplateItem{contract}}) return nil, err @@ -122,7 +122,7 @@ func generateTransaction( _ flowkit.Services, state *flowkit.State, ) (result command.Result, err error) { - generator := NewGenerator(DefaultCadenceDirectory, state, logger, false) + generator := NewGenerator(DefaultCadenceDirectory, state, logger, false, true) transaction := OtherTemplate{Name: args[0]} err = generator.Create(TemplateMap{TransactionType: []TemplateItem{transaction}}) return nil, err @@ -135,7 +135,7 @@ func generateScript( _ flowkit.Services, state *flowkit.State, ) (result command.Result, err error) { - generator := NewGenerator(DefaultCadenceDirectory, state, logger, false) + generator := NewGenerator(DefaultCadenceDirectory, state, logger, false, true) script := OtherTemplate{Name: args[0]} err = generator.Create(TemplateMap{ScriptType: []TemplateItem{script}}) return nil, err @@ -186,14 +186,16 @@ type Generator struct { state *flowkit.State logger output.Logger disableLogs bool + saveState bool } -func NewGenerator(directory string, state *flowkit.State, logger output.Logger, disableLogs bool) *Generator { +func NewGenerator(directory string, state *flowkit.State, logger output.Logger, disableLogs, saveState bool) *Generator { return &Generator{ directory: directory, state: state, logger: logger, disableLogs: disableLogs, + saveState: saveState, } } @@ -327,9 +329,12 @@ func (g *Generator) updateContractsState(name, location string) error { } g.state.Contracts().AddOrUpdate(contract) - err := g.state.SaveDefault() - if err != nil { - return fmt.Errorf("error saving to flow.json: %w", err) + + if g.saveState { + err := g.state.SaveDefault() // TODO: Support adding a target project directory + if err != nil { + return fmt.Errorf("error saving to flow.json: %w", err) + } } return nil diff --git a/internal/super/generate_test.go b/internal/super/generate_test.go index f1f6f2b70..5f799e636 100644 --- a/internal/super/generate_test.go +++ b/internal/super/generate_test.go @@ -34,7 +34,7 @@ func TestGenerateNewContract(t *testing.T) { logger := output.NewStdoutLogger(output.NoneLog) _, state, _ := util.TestMocks(t) - generator := NewGenerator("cadence", state, logger, false) + generator := NewGenerator("cadence", state, logger, false, true) // Test contract generation err := generator.Create(TemplateMap{"contract": []TemplateItem{Contract{Name: "TestContract", Account: ""}}}) @@ -72,7 +72,7 @@ access(all) fun testContract() { assert.Equal(t, expectedTestContent, util.NormalizeLineEndings(string(testContent))) // Test file already exists scenario - generatorTwo := NewGenerator("cadence", state, logger, false) + generatorTwo := NewGenerator("cadence", state, logger, false, true) err = generatorTwo.Create(TemplateMap{"contract": []TemplateItem{Contract{Name: "TestContract", Account: ""}}}) assert.Error(t, err) expectedError := fmt.Sprintf("file already exists: %s", filepath.FromSlash("cadence/contracts/TestContract.cdc")) @@ -83,7 +83,7 @@ func TestGenerateContractWithAccount(t *testing.T) { logger := output.NewStdoutLogger(output.NoneLog) _, state, _ := util.TestMocks(t) - generator := NewGenerator("cadence", state, logger, false) + generator := NewGenerator("cadence", state, logger, false, true) // Test contract generation err := generator.Create(TemplateMap{"contract": []TemplateItem{Contract{Name: "TestContract", Account: "example-account"}}}) @@ -104,7 +104,7 @@ func TestGenerateNewContractSkipTests(t *testing.T) { generateFlags.SkipTests = true - generator := NewGenerator("cadence", state, logger, false) + generator := NewGenerator("cadence", state, logger, false, true) t.Cleanup(func() { generateFlags.SkipTests = false }) @@ -127,7 +127,7 @@ func TestGenerateNewContractWithCDCExtension(t *testing.T) { _, state, _ := util.TestMocks(t) // Test contract generation - generator := NewGenerator("cadence", state, logger, false) + generator := NewGenerator("cadence", state, logger, false, true) err := generator.Create(TemplateMap{"contract": []TemplateItem{Contract{Name: "Tester.cdc", Account: ""}}}) assert.NoError(t, err, "Failed to generate contract") @@ -145,7 +145,7 @@ func TestGenerateNewContractFileAlreadyExists(t *testing.T) { _, state, _ := util.TestMocks(t) // Test contract generation - generator := NewGenerator("cadence", state, logger, false) + generator := NewGenerator("cadence", state, logger, false, true) err := generator.Create(TemplateMap{"contract": []TemplateItem{Contract{Name: "TestContract", Account: ""}}}) assert.NoError(t, err, "Failed to generate contract") @@ -155,7 +155,7 @@ func TestGenerateNewContractFileAlreadyExists(t *testing.T) { assert.NotNil(t, content) // Test file already exists scenario - generatorTwo := NewGenerator("cadence", state, logger, false) + generatorTwo := NewGenerator("cadence", state, logger, false, true) err = generatorTwo.Create(TemplateMap{"contract": []TemplateItem{Contract{Name: "TestContract", Account: ""}}}) assert.Error(t, err) expectedError := fmt.Sprintf("file already exists: %s", filepath.FromSlash("cadence/contracts/TestContract.cdc")) @@ -166,7 +166,7 @@ func TestGenerateNewContractWithFileExtension(t *testing.T) { logger := output.NewStdoutLogger(output.NoneLog) _, state, _ := util.TestMocks(t) - generator := NewGenerator("cadence", state, logger, false) + generator := NewGenerator("cadence", state, logger, false, true) err := generator.Create(TemplateMap{"contract": []TemplateItem{Contract{Name: "TestContract.cdc", Account: ""}}}) assert.NoError(t, err, "Failed to generate contract") @@ -180,7 +180,7 @@ func TestGenerateNewScript(t *testing.T) { logger := output.NewStdoutLogger(output.NoneLog) _, state, _ := util.TestMocks(t) - generator := NewGenerator("cadence", state, logger, false) + generator := NewGenerator("cadence", state, logger, false, true) err := generator.Create(TemplateMap{"script": []TemplateItem{OtherTemplate{Name: "TestScript"}}}) assert.NoError(t, err, "Failed to generate contract") @@ -199,7 +199,7 @@ func TestGenerateNewTransaction(t *testing.T) { logger := output.NewStdoutLogger(output.NoneLog) _, state, _ := util.TestMocks(t) - generator := NewGenerator("cadence", state, logger, false) + generator := NewGenerator("cadence", state, logger, false, true) err := generator.Create(TemplateMap{"transaction": []TemplateItem{OtherTemplate{Name: "TestTransaction"}}}) assert.NoError(t, err, "Failed to generate contract") @@ -219,7 +219,7 @@ func TestGenerateNewWithDirFlag(t *testing.T) { logger := output.NewStdoutLogger(output.NoneLog) _, state, _ := util.TestMocks(t) - generator := NewGenerator("customDir", state, logger, false) + generator := NewGenerator("customDir", state, logger, false, true) err := generator.Create(TemplateMap{"contract": []TemplateItem{Contract{Name: "TestContract", Account: ""}}}) assert.NoError(t, err, "Failed to generate contract") diff --git a/internal/super/setup.go b/internal/super/setup.go index c178f0992..1eef725b3 100644 --- a/internal/super/setup.go +++ b/internal/super/setup.go @@ -177,7 +177,7 @@ func startInteractiveSetup( }, } - generator := NewGenerator(directoryPath, state, logger, true) + generator := NewGenerator(directoryPath, state, logger, true, false) err = generator.Create(templates) if err != nil { return "", err From b2c896b2bf1860d31ff5fd17404a11289aba6b77 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Tue, 7 May 2024 11:20:09 -0700 Subject: [PATCH 63/86] Change setup to init --- internal/super/setup.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/internal/super/setup.go b/internal/super/setup.go index 1eef725b3..bcb73fd28 100644 --- a/internal/super/setup.go +++ b/internal/super/setup.go @@ -58,9 +58,10 @@ type flagsSetup struct { var setupFlags = flagsSetup{} +// TODO: Add --config-only flag var SetupCommand = &command.Command{ Cmd: &cobra.Command{ - Use: "setup ", + Use: "init ", Short: "Start a new Flow project", Example: "flow setup my-project", Args: cobra.MaximumNArgs(1), From d2b8a6ec1ee8f7bb80bb8ad34660ae2bcba516d9 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Tue, 7 May 2024 11:26:47 -0700 Subject: [PATCH 64/86] Change messaging --- internal/super/setup.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/internal/super/setup.go b/internal/super/setup.go index bcb73fd28..e29f12dd0 100644 --- a/internal/super/setup.go +++ b/internal/super/setup.go @@ -215,6 +215,7 @@ func startInteractiveSetup( } } + logger.Info("") logger.Info(util.MessageWithEmojiPrefix("🔄", "Installing selected core contracts and dependencies...")) // Add the selected core contracts as dependencies @@ -284,8 +285,9 @@ func (s *setupResult) String() string { out.WriteString(fmt.Sprintf("%s Congrats! your project was created.\n\n", output.SuccessEmoji())) out.WriteString("Start development by following these steps:\n") out.WriteString(fmt.Sprintf("1. '%s' to change to your new project,\n", output.Bold(fmt.Sprintf("cd %s", relDir)))) - out.WriteString(fmt.Sprintf("2. '%s' or run Flowser to start the emulator,\n", output.Bold("flow emulator"))) - out.WriteString(fmt.Sprintf("3. '%s' to start developing.\n\n", output.Bold("flow dev"))) + //out.WriteString(fmt.Sprintf("2. '%s' or run Flowser to start the emulator,\n", output.Bold("flow emulator"))) + out.WriteString(fmt.Sprintf("2. '%s' to start developing.\n", output.Bold("flow dev"))) + out.WriteString(fmt.Sprintf("3. '%s' to test your project.\n\n", output.Bold("flow test"))) out.WriteString(fmt.Sprintf("You should also read README.md to learn more about the development process!\n")) return out.String() From 4b39f4140f3ead98cb39d13a11106afd85724af0 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Tue, 7 May 2024 11:44:23 -0700 Subject: [PATCH 65/86] Remove example account --- cmd/flow/main.go | 42 +++++++++++++++++++---------------------- internal/super/setup.go | 2 +- 2 files changed, 20 insertions(+), 24 deletions(-) diff --git a/cmd/flow/main.go b/cmd/flow/main.go index 493aa4692..5a9e39714 100644 --- a/cmd/flow/main.go +++ b/cmd/flow/main.go @@ -20,10 +20,6 @@ package main import ( - "fmt" - "os" - "strings" - "github.com/onflow/flow-cli/internal/dependencymanager" "github.com/spf13/cobra" @@ -62,25 +58,25 @@ func main() { // If output is set to json, do not append any message if outputFlag != "json" { - width := 80 - url := "https://cadence-lang.org/docs/cadence_migration_guide" - - // Function to center text within a given width - centerText := func(text string, width int) string { - space := (width - len(text)) / 2 - if space < 0 { - space = 0 - } - return fmt.Sprintf("%s%s%s", strings.Repeat(" ", space), text, strings.Repeat(" ", space)) - } - - fmt.Fprintln(os.Stderr, strings.Repeat("+", width)) - fmt.Fprintln(os.Stderr, centerText("⚠ Upgrade to Cadence 1.0", width)) - fmt.Fprintln(os.Stderr, centerText("The Crescendo network upgrade, including Cadence 1.0, is coming soon.", width)) - fmt.Fprintln(os.Stderr, centerText("You may need to update your existing contracts to support this change.", width)) - fmt.Fprintln(os.Stderr, centerText("Please visit our migration guide here:", width)) - fmt.Fprintln(os.Stderr, centerText(url, width)) - fmt.Fprintln(os.Stderr, strings.Repeat("+", width)) + //width := 80 + //url := "https://cadence-lang.org/docs/cadence_migration_guide" + // + //// Function to center text within a given width + //centerText := func(text string, width int) string { + // space := (width - len(text)) / 2 + // if space < 0 { + // space = 0 + // } + // return fmt.Sprintf("%s%s%s", strings.Repeat(" ", space), text, strings.Repeat(" ", space)) + //} + + //fmt.Fprintln(os.Stderr, strings.Repeat("+", width)) + //fmt.Fprintln(os.Stderr, centerText("⚠ Upgrade to Cadence 1.0", width)) + //fmt.Fprintln(os.Stderr, centerText("The Crescendo network upgrade, including Cadence 1.0, is coming soon.", width)) + //fmt.Fprintln(os.Stderr, centerText("You may need to update your existing contracts to support this change.", width)) + //fmt.Fprintln(os.Stderr, centerText("Please visit our migration guide here:", width)) + //fmt.Fprintln(os.Stderr, centerText(url, width)) + //fmt.Fprintln(os.Stderr, strings.Repeat("+", width)) } }, diff --git a/internal/super/setup.go b/internal/super/setup.go index e29f12dd0..41ae69466 100644 --- a/internal/super/setup.go +++ b/internal/super/setup.go @@ -168,7 +168,7 @@ func startInteractiveSetup( templates := TemplateMap{ "contract": []TemplateItem{ - Contract{Name: "DefaultContract", Account: "example-account"}, + Contract{Name: "DefaultContract", Account: ""}, }, "script": []TemplateItem{ OtherTemplate{Name: "DefaultScripts"}, From 6e4b5d7bf4d6b7204fdf0700a6a245be64c2a2b1 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Tue, 7 May 2024 12:06:51 -0700 Subject: [PATCH 66/86] Update message --- internal/prompt/select-options.go | 2 +- internal/super/setup.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/prompt/select-options.go b/internal/prompt/select-options.go index 747a37c75..a1732873f 100644 --- a/internal/prompt/select-options.go +++ b/internal/prompt/select-options.go @@ -82,7 +82,7 @@ func (m optionSelectModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { func (m optionSelectModel) View() string { var b strings.Builder b.WriteString(fmt.Sprintf("%s\n", m.message)) - b.WriteString("Use arrow keys to navigate, space to select, enter to confirm, q to quit:\n\n") + b.WriteString("Use arrow keys to navigate, space to select, enter to confirm or skip, q to quit:\n\n") for i, choice := range m.choices { if m.cursor == i { b.WriteString("> ") diff --git a/internal/super/setup.go b/internal/super/setup.go index 41ae69466..d28b91312 100644 --- a/internal/super/setup.go +++ b/internal/super/setup.go @@ -186,7 +186,7 @@ func startInteractiveSetup( // Prompt to ask which core contracts should be installed sc := systemcontracts.SystemContractsForChain(flowGo.Mainnet) - promptMessage := "Select the core contracts you'd like to install:" + promptMessage := "Select any core contracts you would like to install or skip to continue." contractNames := make([]string, 0) From 867ebbf490a52929ff03ea7ef8d9cf4884da6fa1 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Thu, 9 May 2024 12:31:20 -0700 Subject: [PATCH 67/86] Undo comment out --- cmd/flow/main.go | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/cmd/flow/main.go b/cmd/flow/main.go index 5a9e39714..1978f427e 100644 --- a/cmd/flow/main.go +++ b/cmd/flow/main.go @@ -20,7 +20,10 @@ package main import ( + "fmt" "github.com/onflow/flow-cli/internal/dependencymanager" + "os" + "strings" "github.com/spf13/cobra" @@ -58,25 +61,25 @@ func main() { // If output is set to json, do not append any message if outputFlag != "json" { - //width := 80 - //url := "https://cadence-lang.org/docs/cadence_migration_guide" - // - //// Function to center text within a given width - //centerText := func(text string, width int) string { - // space := (width - len(text)) / 2 - // if space < 0 { - // space = 0 - // } - // return fmt.Sprintf("%s%s%s", strings.Repeat(" ", space), text, strings.Repeat(" ", space)) - //} - - //fmt.Fprintln(os.Stderr, strings.Repeat("+", width)) - //fmt.Fprintln(os.Stderr, centerText("⚠ Upgrade to Cadence 1.0", width)) - //fmt.Fprintln(os.Stderr, centerText("The Crescendo network upgrade, including Cadence 1.0, is coming soon.", width)) - //fmt.Fprintln(os.Stderr, centerText("You may need to update your existing contracts to support this change.", width)) - //fmt.Fprintln(os.Stderr, centerText("Please visit our migration guide here:", width)) - //fmt.Fprintln(os.Stderr, centerText(url, width)) - //fmt.Fprintln(os.Stderr, strings.Repeat("+", width)) + width := 80 + url := "https://cadence-lang.org/docs/cadence_migration_guide" + + // Function to center text within a given width + centerText := func(text string, width int) string { + space := (width - len(text)) / 2 + if space < 0 { + space = 0 + } + return fmt.Sprintf("%s%s%s", strings.Repeat(" ", space), text, strings.Repeat(" ", space)) + } + + fmt.Fprintln(os.Stderr, strings.Repeat("+", width)) + fmt.Fprintln(os.Stderr, centerText("⚠ Upgrade to Cadence 1.0", width)) + fmt.Fprintln(os.Stderr, centerText("The Crescendo network upgrade, including Cadence 1.0, is coming soon.", width)) + fmt.Fprintln(os.Stderr, centerText("You may need to update your existing contracts to support this change.", width)) + fmt.Fprintln(os.Stderr, centerText("Please visit our migration guide here:", width)) + fmt.Fprintln(os.Stderr, centerText(url, width)) + fmt.Fprintln(os.Stderr, strings.Repeat("+", width)) } }, From 34f451689b74fe2e9912738a4efeaf10fb5cac1c Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Thu, 9 May 2024 12:32:10 -0700 Subject: [PATCH 68/86] Remove --- internal/config/init.go | 75 ----------------------------------------- 1 file changed, 75 deletions(-) diff --git a/internal/config/init.go b/internal/config/init.go index 7dc93677b..5fd9dd0b9 100644 --- a/internal/config/init.go +++ b/internal/config/init.go @@ -99,24 +99,6 @@ func InitializeConfiguration(params InitConfigParameters, readerWriter flowkit.R state.SetEmulatorKey(privateKey) } - //var path string - //if params.TargetDirectory != "" { - // path = fmt.Sprintf("%s/flow.json", params.TargetDirectory) - // - // // Create the directory if it doesn't exist - // err := state.ReaderWriter().MkdirAll(params.TargetDirectory, os.ModePerm) - // if err != nil { - // return nil, fmt.Errorf("failed to create target directory: %w", err) - // } - //} else { - // // Otherwise, choose between the default and global paths - // if params.Global { - // path = config.GlobalPath() - // } else { - // path = config.DefaultPath - // } - //} - if config.Exists(path) && !params.Reset { return nil, fmt.Errorf( "configuration already exists at: %s, if you want to reset configuration use the reset flag", @@ -124,62 +106,5 @@ func InitializeConfiguration(params InitConfigParameters, readerWriter flowkit.R ) } - //err = state.Save(path) - //if err != nil { - // return nil, err - //} - return state, nil } - -// -//func Initialise( -// _ []string, -// _ command.GlobalFlags, -// logger output.Logger, -// readerWriter flowkit.ReaderWriter, -// _ flowkit.Services, -//) (command.Result, error) { -// params := InitConfigParameters{ -// ServicePrivateKey: InitFlag.ServicePrivateKey, -// ServiceKeySigAlgo: InitFlag.ServiceKeySigAlgo, -// ServiceKeyHashAlgo: InitFlag.ServiceKeyHashAlgo, -// Reset: InitFlag.Reset, -// Global: InitFlag.Global, -// } -// state, err := InitializeConfiguration(params, logger, readerWriter) -// if err != nil { -// return nil, err -// } -// -// return &InitResult{State: state}, nil -//} -// -//type InitResult struct { -// *flowkit.State -//} -// -//func (r *InitResult) JSON() any { -// return r -//} -// -//func (r *InitResult) String() string { -// var b bytes.Buffer -// writer := util.CreateTabWriter(&b) -// account, _ := r.State.EmulatorServiceAccount() -// -// _, _ = fmt.Fprintf(writer, "Configuration initialized\n") -// _, _ = fmt.Fprintf(writer, "Service account: %s\n\n", output.Bold("0x"+account.Address.String())) -// _, _ = fmt.Fprintf(writer, -// "Start emulator by running: %s \nReset configuration using: %s\n", -// output.Bold("'flow emulator'"), -// output.Bold("'flow init --reset'"), -// ) -// -// _ = writer.Flush() -// return b.String() -//} -// -//func (r *InitResult) Oneliner() string { -// return "" -//} From a6cdb6a21f4df98909286c118c384f83e2f40b3f Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Thu, 9 May 2024 12:37:50 -0700 Subject: [PATCH 69/86] Remove old code --- cmd/flow/main.go | 1 - 1 file changed, 1 deletion(-) diff --git a/cmd/flow/main.go b/cmd/flow/main.go index 1978f427e..07f341882 100644 --- a/cmd/flow/main.go +++ b/cmd/flow/main.go @@ -86,7 +86,6 @@ func main() { } // quick commands - //quick.InitCommand.AddToParent(cmd) quick.DeployCommand.AddToParent(cmd) quick.RunCommand.AddToParent(cmd) From 801bf6ca29b62fbeaf26058a18152b7c66ba123f Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Thu, 9 May 2024 12:38:18 -0700 Subject: [PATCH 70/86] Run goimports fix --- cmd/flow/main.go | 3 ++- internal/config/init.go | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/cmd/flow/main.go b/cmd/flow/main.go index 07f341882..3d5e08b9a 100644 --- a/cmd/flow/main.go +++ b/cmd/flow/main.go @@ -21,10 +21,11 @@ package main import ( "fmt" - "github.com/onflow/flow-cli/internal/dependencymanager" "os" "strings" + "github.com/onflow/flow-cli/internal/dependencymanager" + "github.com/spf13/cobra" "github.com/onflow/flow-cli/internal/accounts" diff --git a/internal/config/init.go b/internal/config/init.go index 5fd9dd0b9..50c48edac 100644 --- a/internal/config/init.go +++ b/internal/config/init.go @@ -20,10 +20,11 @@ package config import ( "fmt" + "os" + "github.com/onflow/flow-go-sdk/crypto" "github.com/onflow/flowkit" "github.com/onflow/flowkit/config" - "os" ) //type flagsInit struct { From eb7ed3a5ec6b6abf02394c419b6ab0baae694158 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Thu, 9 May 2024 13:07:49 -0700 Subject: [PATCH 71/86] Fix test --- internal/cadence/lint_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/cadence/lint_test.go b/internal/cadence/lint_test.go index 99d025b55..0759c6f62 100644 --- a/internal/cadence/lint_test.go +++ b/internal/cadence/lint_test.go @@ -311,7 +311,7 @@ func setupMockState(t *testing.T) *flowkit.State { }`), 0644) rw := afero.Afero{Fs: mockFs} - state, err := flowkit.Init(rw, crypto.ECDSA_P256, crypto.SHA3_256) + state, err := flowkit.Init(rw, crypto.ECDSA_P256, crypto.SHA3_256, "") require.NoError(t, err) // Mock flowkit contracts From 40dd8652c4d9ec38e5ac597fb757596e072d657d Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Thu, 9 May 2024 13:08:13 -0700 Subject: [PATCH 72/86] Fix test --- internal/super/flix_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/super/flix_test.go b/internal/super/flix_test.go index b8215c140..4a5e8325f 100644 --- a/internal/super/flix_test.go +++ b/internal/super/flix_test.go @@ -221,7 +221,7 @@ func Test_GenerateFlixPrefill(t *testing.T) { var rw = afero.Afero{Fs: mockFS} err := rw.WriteFile(cadenceFile, []byte(CADENCE_SCRIPT), 0644) assert.NoError(t, err) - state, _ := flowkit.Init(rw, crypto.ECDSA_P256, crypto.SHA3_256) + state, _ := flowkit.Init(rw, crypto.ECDSA_P256, crypto.SHA3_256, "") mockFlixService := new(MockFlixService) ctx := context.Background() From 805009bb7b0eca524d573b29ef77b55852047acd Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Wed, 15 May 2024 13:23:49 -0700 Subject: [PATCH 73/86] Fix lint --- internal/config/init.go | 1 - internal/dependencymanager/dependencyinstaller.go | 8 ++++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/internal/config/init.go b/internal/config/init.go index e853806ba..1cdc05e4c 100644 --- a/internal/config/init.go +++ b/internal/config/init.go @@ -26,7 +26,6 @@ import ( "github.com/onflow/flowkit/accounts" "github.com/onflow/flow-go-sdk/crypto" - "github.com/spf13/cobra" "github.com/onflow/flowkit" "github.com/onflow/flowkit/config" diff --git a/internal/dependencymanager/dependencyinstaller.go b/internal/dependencymanager/dependencyinstaller.go index 1bfa9d084..378f1b5c7 100644 --- a/internal/dependencymanager/dependencyinstaller.go +++ b/internal/dependencymanager/dependencyinstaller.go @@ -107,8 +107,8 @@ type DependencyInstaller struct { Gateways map[string]gateway.Gateway Logger output.Logger State *flowkit.State - SaveState bool - TargetDir string + SaveState bool + TargetDir string SkipDeployments bool SkipAlias bool logs categorizedLogs @@ -143,8 +143,8 @@ func NewDependencyInstaller(logger output.Logger, state *flowkit.State, saveStat Gateways: gateways, Logger: logger, State: state, - SaveState: saveState, - TargetDir: targetDir, + SaveState: saveState, + TargetDir: targetDir, SkipDeployments: flags.skipDeployments, SkipAlias: flags.skipAlias, initialContractsState: *state.Contracts(), // Copy at this point in time From 7e71c5e7d0e17263df0c2fb15c9d16d17ed6ed8a Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Wed, 15 May 2024 13:24:55 -0700 Subject: [PATCH 74/86] Remove --- internal/config/init.go | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/internal/config/init.go b/internal/config/init.go index 1cdc05e4c..a03fd2883 100644 --- a/internal/config/init.go +++ b/internal/config/init.go @@ -27,29 +27,9 @@ import ( "github.com/onflow/flow-go-sdk/crypto" - "github.com/onflow/flowkit" "github.com/onflow/flowkit/config" ) -//type flagsInit struct { -// ServicePrivateKey string `flag:"service-private-key" info:"Service account private key"` -// ServiceKeySigAlgo string `default:"ECDSA_P256" flag:"service-sig-algo" info:"Service account key signature algorithm"` -// ServiceKeyHashAlgo string `default:"SHA3_256" flag:"service-hash-algo" info:"Service account key hash algorithm"` -// Reset bool `default:"false" flag:"reset" info:"Reset configuration file"` -// Global bool `default:"false" flag:"global" info:"Initialize global user configuration"` -//} -// -//var InitFlag = flagsInit{} - -//var initCommand = &command.Command{ -// Cmd: &cobra.Command{ -// Use: "init", -// Short: "Initialize a new configuration", -// }, -// Flags: &InitFlag, -// Run: Initialise, -//} - // InitConfigParameters holds all necessary parameters for initializing the configuration. type InitConfigParameters struct { ServicePrivateKey string From 87750b5912dbd4a1035586bd2b477d077fdbd360 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Thu, 16 May 2024 09:51:09 -0700 Subject: [PATCH 75/86] Run goimports fix --- internal/dependencymanager/dependencyinstaller.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/internal/dependencymanager/dependencyinstaller.go b/internal/dependencymanager/dependencyinstaller.go index ace34f608..7bffd52f4 100644 --- a/internal/dependencymanager/dependencyinstaller.go +++ b/internal/dependencymanager/dependencyinstaller.go @@ -107,8 +107,8 @@ type DependencyInstaller struct { Gateways map[string]gateway.Gateway Logger output.Logger State *flowkit.State - SaveState bool - TargetDir string + SaveState bool + TargetDir string SkipDeployments bool SkipAlias bool logs categorizedLogs @@ -142,8 +142,8 @@ func NewDependencyInstaller(logger output.Logger, state *flowkit.State, saveStat Gateways: gateways, Logger: logger, State: state, - SaveState: saveState, - TargetDir: targetDir, + SaveState: saveState, + TargetDir: targetDir, SkipDeployments: flags.skipDeployments, SkipAlias: flags.skipAlias, dependencies: make(map[string]config.Dependency), From d1bd91b276f2d30feeb54100bdda6afa627d6fb9 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Thu, 16 May 2024 09:59:52 -0700 Subject: [PATCH 76/86] Fix tests --- internal/dependencymanager/dependencyinstaller_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/internal/dependencymanager/dependencyinstaller_test.go b/internal/dependencymanager/dependencyinstaller_test.go index a99932981..b99a1dc50 100644 --- a/internal/dependencymanager/dependencyinstaller_test.go +++ b/internal/dependencymanager/dependencyinstaller_test.go @@ -166,6 +166,7 @@ func TestDependencyInstallerAdd(t *testing.T) { TargetDir: "", SkipDeployments: true, SkipAlias: true, + dependencies: make(map[string]config.Dependency), } dep := config.Dependency{ @@ -237,6 +238,7 @@ func TestDependencyInstallerAddMany(t *testing.T) { TargetDir: "", SkipDeployments: true, SkipAlias: true, + dependencies: make(map[string]config.Dependency), } err := di.AddMany(dependencies) From 5c5b9c1d663d4c9bb154eb9b99b02c3d6df5974e Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Thu, 16 May 2024 10:53:41 -0700 Subject: [PATCH 77/86] Prompt if they'd like to install core contracts --- internal/super/setup.go | 60 +++++++++++++++++++++++------------------ 1 file changed, 34 insertions(+), 26 deletions(-) diff --git a/internal/super/setup.go b/internal/super/setup.go index d28b91312..1111a0653 100644 --- a/internal/super/setup.go +++ b/internal/super/setup.go @@ -21,27 +21,23 @@ package super import ( "bytes" "fmt" + "github.com/onflow/flow-cli/internal/dependencymanager" + "github.com/onflow/flow-cli/internal/util" + flowsdk "github.com/onflow/flow-go-sdk" + "github.com/onflow/flow-go/fvm/systemcontracts" + flowGo "github.com/onflow/flow-go/model/flow" + flowkitConfig "github.com/onflow/flowkit/config" + "golang.org/x/exp/slices" "io" "os" "path/filepath" "github.com/spf13/afero" - "github.com/onflow/flow-cli/internal/util" - - flowsdk "github.com/onflow/flow-go-sdk" - "golang.org/x/exp/slices" - "github.com/onflow/flow-cli/internal/prompt" - "github.com/onflow/flow-go/fvm/systemcontracts" - flowGo "github.com/onflow/flow-go/model/flow" - flowkitConfig "github.com/onflow/flowkit/config" - "github.com/spf13/cobra" - "github.com/onflow/flow-cli/internal/dependencymanager" - "github.com/onflow/flowkit" "github.com/onflow/flowkit/output" @@ -184,6 +180,29 @@ func startInteractiveSetup( return "", err } + msg := "Would you like to install any core contracts and their dependencies?" + if prompt.GenericBoolPrompt(msg) { + err := installCoreContracts(logger, state, tempDir) + if err != nil { + return "", err + } + } + + err = state.Save(filepath.Join(tempDir, "flow.json")) + if err != nil { + return "", err + } + + // Move the temp directory to the target directory + err = os.Rename(tempDir, targetDir) + if err != nil { + return "", fmt.Errorf("failed to move temp directory to target directory: %w", err) + } + + return targetDir, nil +} + +func installCoreContracts(logger output.Logger, state *flowkit.State, tempDir string) error { // Prompt to ask which core contracts should be installed sc := systemcontracts.SystemContractsForChain(flowGo.Mainnet) promptMessage := "Select any core contracts you would like to install or skip to continue." @@ -196,7 +215,7 @@ func startInteractiveSetup( selectedContractNames, err := prompt.RunSelectOptions(contractNames, promptMessage) if err != nil { - return "", fmt.Errorf("error running dependency selection: %v\n", err) + return fmt.Errorf("error running dependency selection: %v\n", err) } var dependencies []flowkitConfig.Dependency @@ -221,25 +240,14 @@ func startInteractiveSetup( // Add the selected core contracts as dependencies installer, err := dependencymanager.NewDependencyInstaller(logger, state, false, tempDir, dependencymanager.Flags{}) if err != nil { - return "", err + return err } if err := installer.AddMany(dependencies); err != nil { - return "", err + return err } - err = state.Save(filepath.Join(tempDir, "flow.json")) - if err != nil { - return "", err - } - - // Move the temp directory to the target directory - err = os.Rename(tempDir, targetDir) - if err != nil { - return "", fmt.Errorf("failed to move temp directory to target directory: %w", err) - } - - return targetDir, nil + return nil } // getTargetDirectory checks if the specified directory path is suitable for use. From 8fec985cb5904e72436c3c142b60820f9585058f Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Thu, 16 May 2024 10:57:18 -0700 Subject: [PATCH 78/86] Run goimports fix --- internal/super/setup.go | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/internal/super/setup.go b/internal/super/setup.go index 1111a0653..a4e0599c1 100644 --- a/internal/super/setup.go +++ b/internal/super/setup.go @@ -21,16 +21,18 @@ package super import ( "bytes" "fmt" - "github.com/onflow/flow-cli/internal/dependencymanager" - "github.com/onflow/flow-cli/internal/util" + "io" + "os" + "path/filepath" + flowsdk "github.com/onflow/flow-go-sdk" "github.com/onflow/flow-go/fvm/systemcontracts" flowGo "github.com/onflow/flow-go/model/flow" flowkitConfig "github.com/onflow/flowkit/config" "golang.org/x/exp/slices" - "io" - "os" - "path/filepath" + + "github.com/onflow/flow-cli/internal/dependencymanager" + "github.com/onflow/flow-cli/internal/util" "github.com/spf13/afero" From 1f68ca86940a106ecbb898272f13f7442b419cee Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Fri, 17 May 2024 10:28:09 -0700 Subject: [PATCH 79/86] Fix emulator key gen target dir --- internal/config/init.go | 2 +- internal/super/setup.go | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/internal/config/init.go b/internal/config/init.go index a03fd2883..b48bcce2e 100644 --- a/internal/config/init.go +++ b/internal/config/init.go @@ -75,7 +75,7 @@ func InitializeConfiguration(params InitConfigParameters, readerWriter flowkit.R return nil, err } - emulatorAccount, err := accounts.NewEmulatorAccount(readerWriter, crypto.ECDSA_P256, crypto.SHA3_256, "") + emulatorAccount, err := accounts.NewEmulatorAccount(readerWriter, crypto.ECDSA_P256, crypto.SHA3_256, params.TargetDirectory) if err != nil { return nil, err } diff --git a/internal/super/setup.go b/internal/super/setup.go index a4e0599c1..bea088daa 100644 --- a/internal/super/setup.go +++ b/internal/super/setup.go @@ -109,10 +109,6 @@ func startInteractiveSetup( rw := afero.Afero{ Fs: afero.NewOsFs(), } - //state, err := flowkit.Init(rw, crypto.ECDSA_P256, crypto.SHA3_256) - //if err != nil { - // return "", err - //} // Ask for project name if not given if len(args) < 1 { From 67fd36b225c72473c8452922ea5379fb903e6e66 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Fri, 17 May 2024 10:48:36 -0700 Subject: [PATCH 80/86] Add config only flag --- internal/super/setup.go | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/internal/super/setup.go b/internal/super/setup.go index bea088daa..46915f4aa 100644 --- a/internal/super/setup.go +++ b/internal/super/setup.go @@ -73,7 +73,7 @@ func create( args []string, _ command.GlobalFlags, logger output.Logger, - _ flowkit.ReaderWriter, + readerWriter flowkit.ReaderWriter, _ flowkit.Services, ) (command.Result, error) { var targetDir string @@ -89,6 +89,19 @@ func create( if err != nil { return nil, err } + } else if setupFlags.ConfigOnly { + if len(args) > 0 { + return nil, fmt.Errorf("project name not required when using --config-only flag") + } + + err = createConfigOnly("", readerWriter) + if err != nil { + return nil, err + } + + logger.Info(util.MessageWithEmojiPrefix("🎉", "Configuration created successfully!")) + + return nil, nil } else { targetDir, err = startInteractiveSetup(args, logger) if err != nil { @@ -99,6 +112,27 @@ func create( return &setupResult{targetDir: targetDir}, nil } +func createConfigOnly(targetDir string, readerWriter flowkit.ReaderWriter) error { + params := config.InitConfigParameters{ + ServiceKeySigAlgo: "ECDSA_P256", + ServiceKeyHashAlgo: "SHA3_256", + Reset: false, + Global: false, + TargetDirectory: targetDir, + } + state, err := config.InitializeConfiguration(params, readerWriter) + if err != nil { + return err + } + + err = state.SaveDefault() + if err != nil { + return err + } + + return nil +} + func startInteractiveSetup( args []string, logger output.Logger, From 2e88c4e55a825918c6013f44ba32a5e5ffc0a1cb Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Mon, 20 May 2024 15:33:11 -0700 Subject: [PATCH 81/86] Setup alternative template options for generation --- internal/prompt/spinner.go | 19 +++++ internal/super/generate.go | 82 +++++++++++++++---- internal/super/generate_test.go | 4 +- internal/super/setup.go | 16 +++- .../super/templates/contract_counter.cdc.tmpl | 31 +++++++ .../super/templates/script_counter.cdc.tmpl | 6 ++ .../templates/transaction_counter.cdc.tmpl | 16 ++++ 7 files changed, 153 insertions(+), 21 deletions(-) create mode 100644 internal/prompt/spinner.go create mode 100644 internal/super/templates/contract_counter.cdc.tmpl create mode 100644 internal/super/templates/script_counter.cdc.tmpl create mode 100644 internal/super/templates/transaction_counter.cdc.tmpl diff --git a/internal/prompt/spinner.go b/internal/prompt/spinner.go new file mode 100644 index 000000000..427487e60 --- /dev/null +++ b/internal/prompt/spinner.go @@ -0,0 +1,19 @@ +/* + * Flow CLI + * + * Copyright 2019 Dapper Labs, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package prompt diff --git a/internal/super/generate.go b/internal/super/generate.go index 3fb04f3c9..2da87192e 100644 --- a/internal/super/generate.go +++ b/internal/super/generate.go @@ -123,7 +123,7 @@ func generateTransaction( state *flowkit.State, ) (result command.Result, err error) { generator := NewGenerator(DefaultCadenceDirectory, state, logger, false, true) - transaction := OtherTemplate{Name: args[0]} + transaction := ScriptTemplate{Name: args[0]} err = generator.Create(TemplateMap{TransactionType: []TemplateItem{transaction}}) return nil, err } @@ -136,7 +136,7 @@ func generateScript( state *flowkit.State, ) (result command.Result, err error) { generator := NewGenerator(DefaultCadenceDirectory, state, logger, false, true) - script := OtherTemplate{Name: args[0]} + script := ScriptTemplate{Name: args[0]} err = generator.Create(TemplateMap{ScriptType: []TemplateItem{script}}) return nil, err } @@ -144,13 +144,15 @@ func generateScript( // TemplateItem is an interface for different template types type TemplateItem interface { GetName() string + GetTemplate() string GetAccount() string } // Contract contains properties for contracts type Contract struct { - Name string - Account string + Name string + Template string + Account string } // GetName returns the name of the contract @@ -158,23 +160,67 @@ func (c Contract) GetName() string { return c.Name } +// GetTemplate returns the template of the contract +func (c Contract) GetTemplate() string { + if c.Template == "" { + return "contract_init" + } + + return c.Template +} + // GetAccount returns the account of the contract func (c Contract) GetAccount() string { return c.Account } -// OtherTemplate contains only a name property for scripts and transactions -type OtherTemplate struct { - Name string +// ScriptTemplate contains only a name property for scripts and transactions +type ScriptTemplate struct { + Name string + Template string } // GetName returns the name of the script or transaction -func (o OtherTemplate) GetName() string { +func (o ScriptTemplate) GetName() string { return o.Name } +// GetTemplate returns an empty string for scripts and transactions +func (o ScriptTemplate) GetTemplate() string { + if o.Template == "" { + return "script_init" + } + + return o.Template +} + // GetAccount returns an empty string for scripts and transactions -func (o OtherTemplate) GetAccount() string { +func (o ScriptTemplate) GetAccount() string { + return "" +} + +// TransactionTemplate contains only a name property for scripts and transactions +type TransactionTemplate struct { + Name string + Template string +} + +// GetName returns the name of the script or transaction +func (o TransactionTemplate) GetName() string { + return o.Name +} + +// GetTemplate returns an empty string for scripts and transactions +func (o TransactionTemplate) GetTemplate() string { + if o.Template == "" { + return "transaction_init" + } + + return o.Template +} + +// GetAccount returns an empty string for scripts and transactions +func (o TransactionTemplate) GetAccount() string { return "" } @@ -202,7 +248,7 @@ func NewGenerator(directory string, state *flowkit.State, logger output.Logger, func (g *Generator) Create(typeNames TemplateMap) error { for templateType, items := range typeNames { for _, item := range items { - err := g.generate(templateType, item.GetName(), item.GetAccount()) + err := g.generate(templateType, item.GetTemplate(), item.GetName(), item.GetAccount()) if err != nil { return err } @@ -211,7 +257,7 @@ func (g *Generator) Create(typeNames TemplateMap) error { return nil } -func (g *Generator) generate(templateType, name, account string) error { +func (g *Generator) generate(templateType, templateName, name, account string) error { name = util.StripCDCExtension(name) filename := util.AddCDCExtension(name) @@ -227,28 +273,32 @@ func (g *Generator) generate(templateType, name, account string) error { rootDir = g.directory } + templatePath := fmt.Sprintf("templates/%s.cdc.tmpl", templateName) + switch templateType { case ContractType: basePath = "contracts" - nameData := map[string]interface{}{"Name": name} - fileToWrite, err = processTemplate("templates/contract_init.cdc.tmpl", nameData) + fileData := map[string]interface{}{"Name": name} + fileToWrite, err = processTemplate(templatePath, fileData) if err != nil { return fmt.Errorf("error generating contract template: %w", err) } - testFileToWrite, err = processTemplate("templates/contract_init_test.cdc.tmpl", nameData) + testFileToWrite, err = processTemplate("templates/contract_init_test.cdc.tmpl", fileData) if err != nil { return fmt.Errorf("error generating contract test template: %w", err) } case ScriptType: basePath = "scripts" - fileToWrite, err = processTemplate("templates/script_init.cdc.tmpl", nil) + fileData := map[string]interface{}{"Name": name} + fileToWrite, err = processTemplate(templatePath, fileData) if err != nil { return fmt.Errorf("error generating script template: %w", err) } case TransactionType: basePath = "transactions" - fileToWrite, err = processTemplate("templates/transaction_init.cdc.tmpl", nil) + fileData := map[string]interface{}{"Name": name} + fileToWrite, err = processTemplate(templatePath, fileData) if err != nil { return fmt.Errorf("error generating transaction template: %w", err) } diff --git a/internal/super/generate_test.go b/internal/super/generate_test.go index 5f799e636..6839b3514 100644 --- a/internal/super/generate_test.go +++ b/internal/super/generate_test.go @@ -181,7 +181,7 @@ func TestGenerateNewScript(t *testing.T) { _, state, _ := util.TestMocks(t) generator := NewGenerator("cadence", state, logger, false, true) - err := generator.Create(TemplateMap{"script": []TemplateItem{OtherTemplate{Name: "TestScript"}}}) + err := generator.Create(TemplateMap{"script": []TemplateItem{ScriptTemplate{Name: "TestScript"}}}) assert.NoError(t, err, "Failed to generate contract") content, err := state.ReaderWriter().ReadFile("cadence/scripts/TestScript.cdc") @@ -200,7 +200,7 @@ func TestGenerateNewTransaction(t *testing.T) { _, state, _ := util.TestMocks(t) generator := NewGenerator("cadence", state, logger, false, true) - err := generator.Create(TemplateMap{"transaction": []TemplateItem{OtherTemplate{Name: "TestTransaction"}}}) + err := generator.Create(TemplateMap{"transaction": []TemplateItem{TransactionTemplate{Name: "TestTransaction"}}}) assert.NoError(t, err, "Failed to generate contract") content, err := state.ReaderWriter().ReadFile("cadence/transactions/TestTransaction.cdc") diff --git a/internal/super/setup.go b/internal/super/setup.go index 46915f4aa..a81f8860f 100644 --- a/internal/super/setup.go +++ b/internal/super/setup.go @@ -196,13 +196,23 @@ func startInteractiveSetup( templates := TemplateMap{ "contract": []TemplateItem{ - Contract{Name: "DefaultContract", Account: ""}, + Contract{ + Name: "Counter", + Template: "contract_counter", + Account: "", + }, }, "script": []TemplateItem{ - OtherTemplate{Name: "DefaultScripts"}, + ScriptTemplate{ + Name: "GetCounter", + Template: "script_counter", + }, }, "transaction": []TemplateItem{ - OtherTemplate{Name: "DefaultTransaction"}, + TransactionTemplate{ + Name: "IncrementCounter", + Template: "transaction_counter", + }, }, } diff --git a/internal/super/templates/contract_counter.cdc.tmpl b/internal/super/templates/contract_counter.cdc.tmpl new file mode 100644 index 000000000..d0a3fc781 --- /dev/null +++ b/internal/super/templates/contract_counter.cdc.tmpl @@ -0,0 +1,31 @@ +access(all) contract {{ .Name }} { + + access(all) var count: Int + + // Event to be emitted when the counter is incremented + access(all) event CounterIncremented(newCount: Int) + + // Event to be emitted when the counter is decremented + access(all) event CounterDecremented(newCount: Int) + + init() { + self.count = 0 + } + + // Public function to increment the counter + access(all) fun increment() { + self.count = self.count + 1 + emit CounterIncremented(newCount: self.count) + } + + // Public function to decrement the counter + access(all) fun decrement() { + self.count = self.count - 1 + emit CounterDecremented(newCount: self.count) + } + + // Public function to get the current count + view access(all) fun getCount(): Int { + return self.count + } +} \ No newline at end of file diff --git a/internal/super/templates/script_counter.cdc.tmpl b/internal/super/templates/script_counter.cdc.tmpl new file mode 100644 index 000000000..79f4fcd97 --- /dev/null +++ b/internal/super/templates/script_counter.cdc.tmpl @@ -0,0 +1,6 @@ +import "{{ .Name }}" + +access(all) +fun main(): String { + return {{ .Name }}.greeting +} \ No newline at end of file diff --git a/internal/super/templates/transaction_counter.cdc.tmpl b/internal/super/templates/transaction_counter.cdc.tmpl new file mode 100644 index 000000000..056b47065 --- /dev/null +++ b/internal/super/templates/transaction_counter.cdc.tmpl @@ -0,0 +1,16 @@ +import "{{ .Name }}" + +transaction { + prepare(signer: auth(Account) &Account) { + // Borrow a reference to the {{ .Name }} contract's public capability + let counterRef = signer.borrow<&{{ .Name }}>(from: /storage/counter) + ?? panic("Could not borrow reference to the counter") + + // Call the increment function on the Counter contract + counterRef.increment() + } + + execute { + log("Counter incremented successfully") + } +} \ No newline at end of file From 56aca93d0c6cc87f0c8c221952cc147be7f33f11 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Mon, 20 May 2024 15:42:12 -0700 Subject: [PATCH 82/86] Change how data is handled in templates --- internal/super/generate.go | 36 ++++++++++++++++--- internal/super/setup.go | 2 ++ .../super/templates/script_counter.cdc.tmpl | 4 +-- .../templates/transaction_counter.cdc.tmpl | 4 +-- 4 files changed, 38 insertions(+), 8 deletions(-) diff --git a/internal/super/generate.go b/internal/super/generate.go index 2da87192e..9251e0b6e 100644 --- a/internal/super/generate.go +++ b/internal/super/generate.go @@ -146,6 +146,7 @@ type TemplateItem interface { GetName() string GetTemplate() string GetAccount() string + GetData() map[string]interface{} } // Contract contains properties for contracts @@ -153,6 +154,7 @@ type Contract struct { Name string Template string Account string + Data map[string]interface{} } // GetName returns the name of the contract @@ -174,10 +176,16 @@ func (c Contract) GetAccount() string { return c.Account } +// GetData returns the data of the contract +func (c Contract) GetData() map[string]interface{} { + return c.Data +} + // ScriptTemplate contains only a name property for scripts and transactions type ScriptTemplate struct { Name string Template string + Data map[string]interface{} } // GetName returns the name of the script or transaction @@ -199,10 +207,16 @@ func (o ScriptTemplate) GetAccount() string { return "" } +// GetData returns the data of the script or transaction +func (o ScriptTemplate) GetData() map[string]interface{} { + return o.Data +} + // TransactionTemplate contains only a name property for scripts and transactions type TransactionTemplate struct { Name string Template string + Data map[string]interface{} } // GetName returns the name of the script or transaction @@ -224,6 +238,11 @@ func (o TransactionTemplate) GetAccount() string { return "" } +// GetData returns the data of the script or transaction +func (o TransactionTemplate) GetData() map[string]interface{} { + return o.Data +} + // TemplateMap holds all templates with flexibility type TemplateMap map[string][]TemplateItem @@ -248,7 +267,7 @@ func NewGenerator(directory string, state *flowkit.State, logger output.Logger, func (g *Generator) Create(typeNames TemplateMap) error { for templateType, items := range typeNames { for _, item := range items { - err := g.generate(templateType, item.GetTemplate(), item.GetName(), item.GetAccount()) + err := g.generate(templateType, item.GetTemplate(), item.GetName(), item.GetAccount(), item.GetData()) if err != nil { return err } @@ -257,7 +276,7 @@ func (g *Generator) Create(typeNames TemplateMap) error { return nil } -func (g *Generator) generate(templateType, templateName, name, account string) error { +func (g *Generator) generate(templateType, templateName, name, account string, data map[string]interface{}) error { name = util.StripCDCExtension(name) filename := util.AddCDCExtension(name) @@ -279,6 +298,9 @@ func (g *Generator) generate(templateType, templateName, name, account string) e case ContractType: basePath = "contracts" fileData := map[string]interface{}{"Name": name} + for k, v := range data { + fileData[k] = v + } fileToWrite, err = processTemplate(templatePath, fileData) if err != nil { return fmt.Errorf("error generating contract template: %w", err) @@ -290,14 +312,20 @@ func (g *Generator) generate(templateType, templateName, name, account string) e } case ScriptType: basePath = "scripts" - fileData := map[string]interface{}{"Name": name} + fileData := map[string]interface{}{} + for k, v := range data { + fileData[k] = v + } fileToWrite, err = processTemplate(templatePath, fileData) if err != nil { return fmt.Errorf("error generating script template: %w", err) } case TransactionType: basePath = "transactions" - fileData := map[string]interface{}{"Name": name} + fileData := map[string]interface{}{} + for k, v := range data { + fileData[k] = v + } fileToWrite, err = processTemplate(templatePath, fileData) if err != nil { return fmt.Errorf("error generating transaction template: %w", err) diff --git a/internal/super/setup.go b/internal/super/setup.go index a81f8860f..af6f362dc 100644 --- a/internal/super/setup.go +++ b/internal/super/setup.go @@ -206,12 +206,14 @@ func startInteractiveSetup( ScriptTemplate{ Name: "GetCounter", Template: "script_counter", + Data: map[string]interface{}{"ContractName": "Counter"}, }, }, "transaction": []TemplateItem{ TransactionTemplate{ Name: "IncrementCounter", Template: "transaction_counter", + Data: map[string]interface{}{"ContractName": "Counter"}, }, }, } diff --git a/internal/super/templates/script_counter.cdc.tmpl b/internal/super/templates/script_counter.cdc.tmpl index 79f4fcd97..c334a2aa2 100644 --- a/internal/super/templates/script_counter.cdc.tmpl +++ b/internal/super/templates/script_counter.cdc.tmpl @@ -1,6 +1,6 @@ -import "{{ .Name }}" +import "{{ .ContractName }}" access(all) fun main(): String { - return {{ .Name }}.greeting + return {{ .ContractName }}.greeting } \ No newline at end of file diff --git a/internal/super/templates/transaction_counter.cdc.tmpl b/internal/super/templates/transaction_counter.cdc.tmpl index 056b47065..ee2e10a46 100644 --- a/internal/super/templates/transaction_counter.cdc.tmpl +++ b/internal/super/templates/transaction_counter.cdc.tmpl @@ -1,9 +1,9 @@ -import "{{ .Name }}" +import "{{ .ContractName }}" transaction { prepare(signer: auth(Account) &Account) { // Borrow a reference to the {{ .Name }} contract's public capability - let counterRef = signer.borrow<&{{ .Name }}>(from: /storage/counter) + let counterRef = signer.borrow<&{{ .ContractName }}>(from: /storage/counter) ?? panic("Could not borrow reference to the counter") // Call the increment function on the Counter contract From eab6b33c602117704918935f05514811315cfa56 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Mon, 20 May 2024 15:44:32 -0700 Subject: [PATCH 83/86] Remove --- internal/prompt/spinner.go | 19 ------------------- 1 file changed, 19 deletions(-) delete mode 100644 internal/prompt/spinner.go diff --git a/internal/prompt/spinner.go b/internal/prompt/spinner.go deleted file mode 100644 index 427487e60..000000000 --- a/internal/prompt/spinner.go +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Flow CLI - * - * Copyright 2019 Dapper Labs, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package prompt From 95a9bf586cb7df585a12ee4287e8cba8cbef728c Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Tue, 21 May 2024 14:36:42 -0700 Subject: [PATCH 84/86] Revert messaging --- internal/super/setup.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/super/setup.go b/internal/super/setup.go index af6f362dc..006a45069 100644 --- a/internal/super/setup.go +++ b/internal/super/setup.go @@ -337,9 +337,9 @@ func (s *setupResult) String() string { out.WriteString(fmt.Sprintf("%s Congrats! your project was created.\n\n", output.SuccessEmoji())) out.WriteString("Start development by following these steps:\n") out.WriteString(fmt.Sprintf("1. '%s' to change to your new project,\n", output.Bold(fmt.Sprintf("cd %s", relDir)))) - //out.WriteString(fmt.Sprintf("2. '%s' or run Flowser to start the emulator,\n", output.Bold("flow emulator"))) - out.WriteString(fmt.Sprintf("2. '%s' to start developing.\n", output.Bold("flow dev"))) - out.WriteString(fmt.Sprintf("3. '%s' to test your project.\n\n", output.Bold("flow test"))) + out.WriteString(fmt.Sprintf("2. '%s' or run Flowser to start the emulator,\n", output.Bold("flow emulator"))) + out.WriteString(fmt.Sprintf("3. '%s' to start developing.\n", output.Bold("flow dev"))) + out.WriteString(fmt.Sprintf("4. '%s' to test your project.\n\n", output.Bold("flow test"))) out.WriteString(fmt.Sprintf("You should also read README.md to learn more about the development process!\n")) return out.String() From 18790b968acd60d13cd3de93506e380da7c76589 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Wed, 22 May 2024 10:01:31 -0700 Subject: [PATCH 85/86] Continue merge --- go.mod | 2 +- go.sum | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index 8916fc2b0..817476e7f 100644 --- a/go.mod +++ b/go.mod @@ -260,7 +260,7 @@ require ( golang.org/x/oauth2 v0.18.0 // indirect golang.org/x/sync v0.6.0 // indirect golang.org/x/sys v0.18.0 // indirect - golang.org/x/term v0.17.0 // indirect + golang.org/x/term v0.18.0 // indirect golang.org/x/text v0.14.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.17.0 // indirect diff --git a/go.sum b/go.sum index 4d42510c3..3f7bc7892 100644 --- a/go.sum +++ b/go.sum @@ -1591,7 +1591,7 @@ golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= -golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= +golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= From b15c32bf63b38af634a79246ccef0715ea25f1d0 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Thu, 23 May 2024 09:02:18 -0700 Subject: [PATCH 86/86] Remove comments --- internal/config/config.go | 1 - internal/quick/init.go | 32 -------------------------------- 2 files changed, 33 deletions(-) delete mode 100644 internal/quick/init.go diff --git a/internal/config/config.go b/internal/config/config.go index 17835e7d0..84b4eae78 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -29,7 +29,6 @@ var Cmd = &cobra.Command{ } func init() { - //initCommand.AddToParent(Cmd) Cmd.AddCommand(addCmd) Cmd.AddCommand(removeCmd) } diff --git a/internal/quick/init.go b/internal/quick/init.go deleted file mode 100644 index ca00f0730..000000000 --- a/internal/quick/init.go +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Flow CLI - * - * Copyright 2019 Dapper Labs, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package quick - -// TODO(sideninja) workaround - init needed to be copied in order to work else there is flag duplicate error - -//var InitCommand = &command.Command{ -// Cmd: &cobra.Command{ -// Use: "init", -// Short: "Initialize a new configuration", -// Example: "flow project init", -// GroupID: "project", -// }, -// Flags: &config.InitFlag, -// Run: config.Initialise, // TODO(sideninja) workaround - init needed to be copied in order to work else there is flag duplicate error -//}