Skip to content

Commit

Permalink
Merge pull request #1565 from onflow/bastian/update-stable-cadence-2
Browse files Browse the repository at this point in the history
  • Loading branch information
turbolent authored May 3, 2024
2 parents ec35d53 + 82b037a commit b12cc0a
Show file tree
Hide file tree
Showing 10 changed files with 153 additions and 49 deletions.
15 changes: 12 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@ on:
- master
- 'feature/**'

# We need to set this explicitly to make sure the CI works on Windows
# Default shell does not terminate on error in GitHub Actions
# https://github.com/actions/runner-images/issues/6668
defaults:
run:
shell: bash

jobs:
test:
strategy:
Expand All @@ -22,7 +29,7 @@ jobs:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- uses: actions/setup-go@v4
- uses: actions/setup-go@v5
with:
go-version: "1.20"
- name: Run tests
Expand All @@ -35,17 +42,19 @@ jobs:
with:
file: ./coverage.txt
flags: unittests
token: ${{ secrets.CODECOV_TOKEN }}
if: matrix.os == 'ubuntu-latest'

lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-go@v4
- uses: actions/setup-go@v5
with:
go-version: "1.20"
- name: generate
run: make generate
- uses: golangci/golangci-lint-action@v3.7.0
- uses: golangci/golangci-lint-action@v5.1.0
with:
version: v1.52.2
only-new-issues: true
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ You can also release manually although this is not recommended:

To make the new version the default version that is installed

- Change `version.txt` and commit it
- **DEPRECATED** Change `version.txt` and commit it. (This file is no longer user for versions of the Flow CLI later than v1.18.0, although it should still be maintained to support older versions of the CLI for a while)

## Adding a scaffold
You can add your own scaffold by creating a GitHub repository containing the scaffold content and then making a PR
Expand Down
8 changes: 2 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ binary: $(BINARY)

.PHONY: install-tools
install-tools:
cd ${GOPATH}; \
mkdir -p ${GOPATH}; \
cd '${GOPATH}'; \
mkdir -p '${GOPATH}'; \
GO111MODULE=on go install github.com/axw/gocov/gocov@latest; \
GO111MODULE=on go install github.com/matm/gocov-html/cmd/gocov-html@latest; \
GO111MODULE=on go install github.com/sanderhahn/gozip/cmd/gozip@latest; \
Expand Down Expand Up @@ -86,10 +86,6 @@ publish:
clean:
rm ./cmd/flow/flow*

.PHONY: install-linter
install-linter:
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b ${GOPATH}/bin v1.47.2

.PHONY: lint
lint: generate
golangci-lint run -v ./...
Expand Down
20 changes: 17 additions & 3 deletions internal/command/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ func checkVersion(logger output.Logger) {
return
}

resp, err := http.Get("https://raw.githubusercontent.com/onflow/flow-cli/master/version.txt")
resp, err := http.Get("https://formulae.brew.sh/api/formula/flow-cli.json")
if err != nil || resp.StatusCode >= 400 {
return
}
Expand All @@ -285,11 +285,25 @@ func checkVersion(logger output.Logger) {
}(resp.Body)

body, _ := io.ReadAll(resp.Body)
latestVersion := strings.TrimSpace(string(body))
var data map[string]interface{}
err = json.Unmarshal(body, &data)
if err != nil {
return
}

versions, ok := data["versions"].(map[string]interface{})
if !ok {
return
}

latestVersion, ok := versions["stable"].(string)
if !ok {
return
}

if currentVersion != latestVersion {
logger.Info(fmt.Sprintf(
"\n%s Version warning: a new version of Flow CLI is available (%s).\n"+
"\n%s Version warning: a new version of Flow CLI is available (v%s).\n"+
" Read the installation guide for upgrade instructions: https://docs.onflow.org/flow-cli/install\n",
output.WarningEmoji(),
strings.ReplaceAll(latestVersion, "\n", ""),
Expand Down
52 changes: 43 additions & 9 deletions internal/dependencymanager/dependencyinstaller.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,28 +50,37 @@ import (
type categorizedLogs struct {
fileSystemActions []string
stateUpdates []string
issues []string
}

func (cl *categorizedLogs) LogAll(logger output.Logger) {
logger.Info(util.MessageWithEmojiPrefix("📝", "Dependency Manager Actions Summary"))
logger.Info("") // Add a line break after the section

if len(cl.fileSystemActions) > 0 {
logger.Info("🗃️ File System Actions:")
logger.Info(util.MessageWithEmojiPrefix("🗃️", "File System Actions:"))
for _, msg := range cl.fileSystemActions {
logger.Info(util.MessageWithEmojiPrefix("✅", msg))
logger.Info(msg)
}
logger.Info("") // Add a line break after the section
}

if len(cl.stateUpdates) > 0 {
logger.Info("💾 State Updates:")
logger.Info(util.MessageWithEmojiPrefix("💾", "State Updates:"))
for _, msg := range cl.stateUpdates {
logger.Info(util.MessageWithEmojiPrefix("✅", msg))
logger.Info(msg)
}
logger.Info("") // Add a line break after the section
}

if len(cl.issues) > 0 {
logger.Info(util.MessageWithEmojiPrefix("⚠️", "Issues:"))
for _, msg := range cl.issues {
logger.Info(msg)
}
logger.Info("")
}

if len(cl.fileSystemActions) == 0 && len(cl.stateUpdates) == 0 {
logger.Info(util.MessageWithEmojiPrefix("👍", "Zero changes were made. Everything looks good."))
}
Expand Down Expand Up @@ -286,7 +295,8 @@ func (di *DependencyInstaller) handleFileSystem(contractAddr, contractName, cont
return fmt.Errorf("failed to create contract file: %w", err)
}

di.logs.fileSystemActions = append(di.logs.fileSystemActions, fmt.Sprintf("%s from %s on %s installed", contractName, contractAddr, networkName))
msg := util.MessageWithEmojiPrefix("✅️", fmt.Sprintf("Contract %s from %s on %s installed", contractName, contractAddr, networkName))
di.logs.fileSystemActions = append(di.logs.fileSystemActions, msg)
}

return nil
Expand All @@ -303,6 +313,20 @@ func isCoreContract(contractName string) bool {
return false
}

// checkForContractConflicts checks if a contract with the same name already exists in the state and adds a warning
func (di *DependencyInstaller) checkForContractConflicts(contractName string) error {
_, err := di.State.Contracts().ByName(contractName)
if err != nil {
return nil
} else {
if !isCoreContract(contractName) {
msg := util.MessageWithEmojiPrefix("❌", fmt.Sprintf("Contract named %s already exists in flow.json", contractName))
di.logs.issues = append(di.logs.issues, msg)
}
return nil
}
}

func (di *DependencyInstaller) handleFoundContract(networkName, contractAddr, assignedName, contractName string, program *project.Program) error {
hash := sha256.New()
hash.Write(program.CodeWithUnprocessedImports())
Expand Down Expand Up @@ -330,7 +354,14 @@ func (di *DependencyInstaller) handleFoundContract(networkName, contractAddr, as
}
}

err := di.handleFileSystem(contractAddr, contractName, contractData, networkName)
//// This needs to happen before dependency state is updated
err := di.checkForContractConflicts(assignedName)
if err != nil {
di.Logger.Error(fmt.Sprintf("Error checking for contract conflicts: %v", err))
return err
}

err = di.handleFileSystem(contractAddr, contractName, contractData, networkName)
if err != nil {
return fmt.Errorf("error handling file system: %w", err)
}
Expand All @@ -349,7 +380,8 @@ func (di *DependencyInstaller) handleFoundContract(networkName, contractAddr, as
return err
}

di.logs.stateUpdates = append(di.logs.stateUpdates, fmt.Sprintf("%s added to emulator deployments", contractName))
msg := util.MessageWithEmojiPrefix("✅", fmt.Sprintf("%s added to emulator deployments", contractName))
di.logs.stateUpdates = append(di.logs.stateUpdates, msg)
}

// If the contract is not a core contract and the user does not want to skip aliasing, then prompt for an alias
Expand All @@ -360,7 +392,8 @@ func (di *DependencyInstaller) handleFoundContract(networkName, contractAddr, as
return err
}

di.logs.stateUpdates = append(di.logs.stateUpdates, fmt.Sprintf("Alias added for %s on %s", contractName, networkName))
msg := util.MessageWithEmojiPrefix("✅", fmt.Sprintf("Alias added for %s on %s", contractName, networkName))
di.logs.stateUpdates = append(di.logs.stateUpdates, msg)
}

return nil
Expand Down Expand Up @@ -430,7 +463,8 @@ func (di *DependencyInstaller) updateDependencyState(networkName, contractAddres
di.State.Contracts().AddDependencyAsContract(dep, networkName)

if isNewDep {
di.logs.stateUpdates = append(di.logs.stateUpdates, fmt.Sprintf("%s added to flow.json", dep.Name))
msg := util.MessageWithEmojiPrefix("✅", fmt.Sprintf("%s added to flow.json", dep.Name))
di.logs.stateUpdates = append(di.logs.stateUpdates, msg)
}

return nil
Expand Down
18 changes: 11 additions & 7 deletions internal/super/generate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
package super

import (
"fmt"
"path/filepath"
"testing"

"github.com/onflow/flow-cli/internal/util"
Expand Down Expand Up @@ -64,13 +66,14 @@ access(all) fun testContract() {
Test.expect(err, Test.beNil())
}`

assert.Equal(t, expectedContent, string(fileContent))
assert.Equal(t, expectedTestContent, string(testContent))
assert.Equal(t, expectedContent, util.NormalizeLineEndings(string(fileContent)))
assert.Equal(t, expectedTestContent, util.NormalizeLineEndings(string(testContent)))

// Test file already exists scenario
_, err = generateNew([]string{"TestContract"}, "contract", logger, state)
assert.Error(t, err)
assert.Equal(t, "file already exists: cadence/contracts/TestContract.cdc", err.Error())
expectedError := fmt.Sprintf("file already exists: %s", filepath.FromSlash("cadence/contracts/TestContract.cdc"))
assert.Equal(t, expectedError, err.Error())
}

func TestGenerateNewContractSkipTests(t *testing.T) {
Expand Down Expand Up @@ -129,7 +132,8 @@ func TestGenerateNewContractFileAlreadyExists(t *testing.T) {
// Test file already exists scenario
_, err = generateNew([]string{"TestContract"}, "contract", logger, state)
assert.Error(t, err)
assert.Equal(t, "file already exists: cadence/contracts/TestContract.cdc", err.Error())
expectedError := fmt.Sprintf("file already exists: %s", filepath.FromSlash("cadence/contracts/TestContract.cdc"))
assert.Equal(t, expectedError, err.Error())
}

func TestGenerateNewContractWithFileExtension(t *testing.T) {
Expand Down Expand Up @@ -160,7 +164,7 @@ func TestGenerateNewScript(t *testing.T) {
fun main() {
// Script details here
}`
assert.Equal(t, expectedContent, string(content))
assert.Equal(t, expectedContent, util.NormalizeLineEndings(string(content)))
}

func TestGenerateNewTransaction(t *testing.T) {
Expand All @@ -179,7 +183,7 @@ func TestGenerateNewTransaction(t *testing.T) {
execute {}
}`
assert.Equal(t, expectedContent, string(content))
assert.Equal(t, expectedContent, util.NormalizeLineEndings(string(content)))
}

func TestGenerateNewWithDirFlag(t *testing.T) {
Expand All @@ -200,5 +204,5 @@ func TestGenerateNewWithDirFlag(t *testing.T) {
contract TestContract {
init() {}
}`
assert.Equal(t, expectedContent, string(content))
assert.Equal(t, expectedContent, util.NormalizeLineEndings(string(content)))
}
69 changes: 56 additions & 13 deletions internal/test/test.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ const helperScriptSubstr = "_helper"
// scripts and transactions are excluded from coverage report.
const contractsCoverCode = "contracts"

// The default glob pattern to find test files.
const defaultTestSuffix = "_test.cdc"

type flagsTests struct {
Cover bool `default:"false" flag:"cover" info:"Use the cover flag to calculate coverage report"`
CoverProfile string `default:"coverage.json" flag:"coverprofile" info:"Filename to write the calculated coverage report. Supported extensions are .json and .lcov"`
Expand All @@ -74,10 +77,14 @@ var testFlags = flagsTests{}

var TestCommand = &command.Command{
Cmd: &cobra.Command{
Use: "test <filename>",
Short: "Run Cadence tests",
Example: `flow test script.cdc`,
Args: cobra.MinimumNArgs(1),
Use: "test [files...]",
Short: "Run Cadence tests",
Example: `# Run tests in files matching default pattern **/*_test.cdc
flow test
# Run tests in the specified files
flow test test1.cdc test2.cdc`,
Args: cobra.ArbitraryArgs,
GroupID: "tools",
},
Flags: &testFlags,
Expand All @@ -101,8 +108,19 @@ func run(
)
}

var filenames []string
if len(args) == 0 {
var err error
filenames, err = findAllTestFiles(".")
if err != nil {
return nil, fmt.Errorf("error loading script files: %w", err)
}
} else {
filenames = args
}

testFiles := make(map[string][]byte, 0)
for _, filename := range args {
for _, filename := range filenames {
code, err := state.ReadFile(filename)
if err != nil {
return nil, fmt.Errorf("error loading script file: %w", err)
Expand Down Expand Up @@ -341,14 +359,18 @@ func (r *result) String() string {
var b bytes.Buffer
writer := util.CreateTabWriter(&b)

for scriptPath, testResult := range r.Results {
_, _ = fmt.Fprint(writer, cdcTests.PrettyPrintResults(testResult, scriptPath))
}
if r.CoverageReport != nil {
_, _ = fmt.Fprint(writer, r.CoverageReport.String())
}
if r.RandomSeed > 0 {
_, _ = fmt.Fprintf(writer, "\nSeed: %d", r.RandomSeed)
if len(r.Results) == 0 {
_, _ = fmt.Fprint(writer, "No tests found")
} else {
for scriptPath, testResult := range r.Results {
_, _ = fmt.Fprint(writer, cdcTests.PrettyPrintResults(testResult, scriptPath))
}
if r.CoverageReport != nil {
_, _ = fmt.Fprint(writer, r.CoverageReport.String())
}
if r.RandomSeed > 0 {
_, _ = fmt.Fprintf(writer, "\nSeed: %d", r.RandomSeed)
}
}

_ = writer.Flush()
Expand Down Expand Up @@ -382,3 +404,24 @@ func (r *result) Oneliner() string {
func (r *result) ExitCode() int {
return r.exitCode
}

func findAllTestFiles(baseDir string) ([]string, error) {
var filenames []string
err := filepath.Walk(baseDir, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}

if !strings.HasSuffix(path, defaultTestSuffix) {
return nil
}

filenames = append(filenames, path)
return nil
})
if err != nil {
return nil, err
}

return filenames, nil
}
Loading

0 comments on commit b12cc0a

Please sign in to comment.