From 394f7520de61e1b2f1384e345fbafa29f72cf658 Mon Sep 17 00:00:00 2001 From: Silvano Cerza Date: Thu, 20 Oct 2022 17:13:34 +0200 Subject: [PATCH 1/4] Change lib deps CLI command output to sorted alphabetically --- cli/lib/check_deps.go | 9 ++++- commands/lib/resolve_deps.go | 4 +++ internal/integrationtest/lib/lib_test.go | 42 ++++++++++++++++++++++++ 3 files changed, 54 insertions(+), 1 deletion(-) diff --git a/cli/lib/check_deps.go b/cli/lib/check_deps.go index 7a420001f62..4ebc989a5bf 100644 --- a/cli/lib/check_deps.go +++ b/cli/lib/check_deps.go @@ -19,6 +19,7 @@ import ( "context" "fmt" "os" + "sort" "github.com/arduino/arduino-cli/cli/arguments" "github.com/arduino/arduino-cli/cli/errorcodes" @@ -81,13 +82,19 @@ func (dr checkDepResult) Data() interface{} { func (dr checkDepResult) String() string { res := "" - for _, dep := range dr.deps.GetDependencies() { + deps := dr.deps.Dependencies + sort.Slice(deps, func(i, j int) bool { + return deps[i].Name > deps[j].Name && + deps[i].VersionInstalled > deps[j].VersionInstalled + }) + for _, dep := range deps { res += outputDep(dep) } return res } func outputDep(dep *rpc.LibraryDependencyStatus) string { + res := "" green := color.New(color.FgGreen) red := color.New(color.FgRed) diff --git a/commands/lib/resolve_deps.go b/commands/lib/resolve_deps.go index dc18591a0c5..eee45e81d61 100644 --- a/commands/lib/resolve_deps.go +++ b/commands/lib/resolve_deps.go @@ -18,6 +18,7 @@ package lib import ( "context" "errors" + "sort" "github.com/arduino/arduino-cli/arduino" "github.com/arduino/arduino-cli/arduino/libraries" @@ -74,5 +75,8 @@ func LibraryResolveDependencies(ctx context.Context, req *rpc.LibraryResolveDepe VersionInstalled: installed, }) } + sort.Slice(res, func(i, j int) bool { + return res[i].Name < res[j].Name + }) return &rpc.LibraryResolveDependenciesResponse{Dependencies: res}, nil } diff --git a/internal/integrationtest/lib/lib_test.go b/internal/integrationtest/lib/lib_test.go index 0300de3c2ea..fe6ae264f0e 100644 --- a/internal/integrationtest/lib/lib_test.go +++ b/internal/integrationtest/lib/lib_test.go @@ -16,6 +16,7 @@ package lib_test import ( + "strings" "testing" "github.com/arduino/arduino-cli/internal/integrationtest" @@ -136,3 +137,44 @@ func TestDuplicateLibInstallDetection(t *testing.T) { require.Error(t, err) require.Contains(t, string(stdErr), "The library ArduinoOTA has multiple installations") } + +func TestLibDepsOutput(t *testing.T) { + env, cli := integrationtest.CreateArduinoCLIWithEnvironment(t) + defer env.CleanUp() + + // Updates index for cores and libraries + _, _, err := cli.Run("core", "update-index") + require.NoError(t, err) + _, _, err = cli.Run("lib", "update-index") + require.NoError(t, err) + + // Install some libraries that are dependencies of another library + _, _, err = cli.Run("lib", "install", "MKRWAN@1.1.0") + require.NoError(t, err) + _, _, err = cli.Run("lib", "install", "WiFi101@0.16.1") + require.NoError(t, err) + + stdOut, _, err := cli.Run("lib", "deps", "Arduino_ConnectionHandler@0.6.6", "--no-color") + require.NoError(t, err) + lines := strings.Split(strings.TrimSpace(string(stdOut)), "\n") + require.Len(t, lines, 7) + require.Equal(t, "✓ MKRWAN 1.1.0 is already installed.", lines[0]) + require.Equal(t, "✓ WiFi101 0.16.1 is already installed.", lines[1]) + require.Equal(t, "✕ Arduino_ConnectionHandler 0.6.6 must be installed.", lines[2]) + require.Equal(t, "✕ Arduino_DebugUtils 1.3.0 must be installed.", lines[3]) + require.Equal(t, "✕ MKRGSM 1.5.0 must be installed.", lines[4]) + require.Equal(t, "✕ MKRNB 1.5.1 must be installed.", lines[5]) + require.Equal(t, "✕ WiFiNINA 1.8.13 must be installed.", lines[6]) + + stdOut, _, err = cli.Run("lib", "deps", "Arduino_ConnectionHandler@0.6.6", "--format", "json") + require.NoError(t, err) + expectedOutput := `{"dependencies":[ + {"name":"Arduino_ConnectionHandler","version_required":"0.6.6"}, + {"name":"Arduino_DebugUtils","version_required":"1.3.0"}, + {"name":"MKRGSM","version_required":"1.5.0"}, + {"name":"MKRNB","version_required":"1.5.1"}, + {"name":"MKRWAN","version_required":"1.1.0","version_installed":"1.1.0"}, + {"name":"WiFi101","version_required":"0.16.1","version_installed":"0.16.1"}, + {"name":"WiFiNINA","version_required":"1.8.13"}]}` + require.JSONEq(t, expectedOutput, string(stdOut)) +} From 43ba63f4b8dbaf97481f8545836ca5c97c3114b4 Mon Sep 17 00:00:00 2001 From: Silvano Cerza Date: Fri, 21 Oct 2022 11:08:50 +0200 Subject: [PATCH 2/4] Fix plain text output not sorted correctly --- cli/lib/check_deps.go | 12 +++++++-- internal/integrationtest/lib/lib_test.go | 34 +++++++++++++----------- 2 files changed, 29 insertions(+), 17 deletions(-) diff --git a/cli/lib/check_deps.go b/cli/lib/check_deps.go index 4ebc989a5bf..0604fa15eb8 100644 --- a/cli/lib/check_deps.go +++ b/cli/lib/check_deps.go @@ -83,10 +83,18 @@ func (dr checkDepResult) Data() interface{} { func (dr checkDepResult) String() string { res := "" deps := dr.deps.Dependencies + + // Sort depedencies alphabetically and then puts installed ones on top sort.Slice(deps, func(i, j int) bool { - return deps[i].Name > deps[j].Name && - deps[i].VersionInstalled > deps[j].VersionInstalled + return deps[i].Name < deps[j].Name + }) + sort.SliceStable(deps, func(i, j int) bool { + if deps[i].VersionInstalled != "" && deps[j].VersionInstalled == "" { + return true + } + return false }) + for _, dep := range deps { res += outputDep(dep) } diff --git a/internal/integrationtest/lib/lib_test.go b/internal/integrationtest/lib/lib_test.go index fe6ae264f0e..519253312d3 100644 --- a/internal/integrationtest/lib/lib_test.go +++ b/internal/integrationtest/lib/lib_test.go @@ -149,32 +149,36 @@ func TestLibDepsOutput(t *testing.T) { require.NoError(t, err) // Install some libraries that are dependencies of another library - _, _, err = cli.Run("lib", "install", "MKRWAN@1.1.0") + _, _, err = cli.Run("lib", "install", "Arduino_DebugUtils@1.3.0") require.NoError(t, err) - _, _, err = cli.Run("lib", "install", "WiFi101@0.16.1") + _, _, err = cli.Run("lib", "install", "MKRGSM@1.5.0") + require.NoError(t, err) + _, _, err = cli.Run("lib", "install", "MKRNB@1.5.1") + require.NoError(t, err) + _, _, err = cli.Run("lib", "install", "WiFiNINA@1.8.13") require.NoError(t, err) stdOut, _, err := cli.Run("lib", "deps", "Arduino_ConnectionHandler@0.6.6", "--no-color") require.NoError(t, err) lines := strings.Split(strings.TrimSpace(string(stdOut)), "\n") require.Len(t, lines, 7) - require.Equal(t, "✓ MKRWAN 1.1.0 is already installed.", lines[0]) - require.Equal(t, "✓ WiFi101 0.16.1 is already installed.", lines[1]) - require.Equal(t, "✕ Arduino_ConnectionHandler 0.6.6 must be installed.", lines[2]) - require.Equal(t, "✕ Arduino_DebugUtils 1.3.0 must be installed.", lines[3]) - require.Equal(t, "✕ MKRGSM 1.5.0 must be installed.", lines[4]) - require.Equal(t, "✕ MKRNB 1.5.1 must be installed.", lines[5]) - require.Equal(t, "✕ WiFiNINA 1.8.13 must be installed.", lines[6]) + require.Equal(t, "✓ Arduino_DebugUtils 1.3.0 is already installed.", lines[0]) + require.Equal(t, "✓ MKRGSM 1.5.0 is already installed.", lines[1]) + require.Equal(t, "✓ MKRNB 1.5.1 is already installed.", lines[2]) + require.Equal(t, "✓ WiFiNINA 1.8.13 is already installed.", lines[3]) + require.Equal(t, "✕ Arduino_ConnectionHandler 0.6.6 must be installed.", lines[4]) + require.Equal(t, "✕ MKRWAN 1.1.0 must be installed.", lines[5]) + require.Equal(t, "✕ WiFi101 0.16.1 must be installed.", lines[6]) stdOut, _, err = cli.Run("lib", "deps", "Arduino_ConnectionHandler@0.6.6", "--format", "json") require.NoError(t, err) expectedOutput := `{"dependencies":[ {"name":"Arduino_ConnectionHandler","version_required":"0.6.6"}, - {"name":"Arduino_DebugUtils","version_required":"1.3.0"}, - {"name":"MKRGSM","version_required":"1.5.0"}, - {"name":"MKRNB","version_required":"1.5.1"}, - {"name":"MKRWAN","version_required":"1.1.0","version_installed":"1.1.0"}, - {"name":"WiFi101","version_required":"0.16.1","version_installed":"0.16.1"}, - {"name":"WiFiNINA","version_required":"1.8.13"}]}` + {"name":"Arduino_DebugUtils","version_required":"1.3.0","version_installed":"1.3.0"}, + {"name":"MKRGSM","version_required":"1.5.0","version_installed":"1.5.0"}, + {"name":"MKRNB","version_required":"1.5.1","version_installed":"1.5.1"}, + {"name":"MKRWAN","version_required":"1.1.0"}, + {"name":"WiFi101","version_required":"0.16.1"}, + {"name":"WiFiNINA","version_required":"1.8.13","version_installed":"1.8.13"}]}` require.JSONEq(t, expectedOutput, string(stdOut)) } From 5c16f95bd14f69bfb79240d6294ccd358135f5b9 Mon Sep 17 00:00:00 2001 From: Silvano Cerza Date: Fri, 21 Oct 2022 14:27:54 +0200 Subject: [PATCH 3/4] Simplify deps sorting --- cli/lib/check_deps.go | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/cli/lib/check_deps.go b/cli/lib/check_deps.go index 0604fa15eb8..ae2c6f4141c 100644 --- a/cli/lib/check_deps.go +++ b/cli/lib/check_deps.go @@ -89,10 +89,7 @@ func (dr checkDepResult) String() string { return deps[i].Name < deps[j].Name }) sort.SliceStable(deps, func(i, j int) bool { - if deps[i].VersionInstalled != "" && deps[j].VersionInstalled == "" { - return true - } - return false + return deps[i].VersionInstalled != "" && deps[j].VersionInstalled == "" }) for _, dep := range deps { @@ -102,7 +99,6 @@ func (dr checkDepResult) String() string { } func outputDep(dep *rpc.LibraryDependencyStatus) string { - res := "" green := color.New(color.FgGreen) red := color.New(color.FgRed) From 473a7a5bbc06a04cd6387bf971a129aa7392ffdf Mon Sep 17 00:00:00 2001 From: Silvano Cerza Date: Fri, 21 Oct 2022 14:49:15 +0200 Subject: [PATCH 4/4] Reworked test to prevent future breakages --- internal/integrationtest/lib/lib_test.go | 57 +++++++++++++++--------- 1 file changed, 37 insertions(+), 20 deletions(-) diff --git a/internal/integrationtest/lib/lib_test.go b/internal/integrationtest/lib/lib_test.go index 519253312d3..c409a43f855 100644 --- a/internal/integrationtest/lib/lib_test.go +++ b/internal/integrationtest/lib/lib_test.go @@ -16,6 +16,7 @@ package lib_test import ( + "encoding/json" "strings" "testing" @@ -149,36 +150,52 @@ func TestLibDepsOutput(t *testing.T) { require.NoError(t, err) // Install some libraries that are dependencies of another library - _, _, err = cli.Run("lib", "install", "Arduino_DebugUtils@1.3.0") + _, _, err = cli.Run("lib", "install", "Arduino_DebugUtils") require.NoError(t, err) - _, _, err = cli.Run("lib", "install", "MKRGSM@1.5.0") + _, _, err = cli.Run("lib", "install", "MKRGSM") require.NoError(t, err) - _, _, err = cli.Run("lib", "install", "MKRNB@1.5.1") + _, _, err = cli.Run("lib", "install", "MKRNB") require.NoError(t, err) - _, _, err = cli.Run("lib", "install", "WiFiNINA@1.8.13") + _, _, err = cli.Run("lib", "install", "WiFiNINA") require.NoError(t, err) stdOut, _, err := cli.Run("lib", "deps", "Arduino_ConnectionHandler@0.6.6", "--no-color") require.NoError(t, err) lines := strings.Split(strings.TrimSpace(string(stdOut)), "\n") require.Len(t, lines, 7) - require.Equal(t, "✓ Arduino_DebugUtils 1.3.0 is already installed.", lines[0]) - require.Equal(t, "✓ MKRGSM 1.5.0 is already installed.", lines[1]) - require.Equal(t, "✓ MKRNB 1.5.1 is already installed.", lines[2]) - require.Equal(t, "✓ WiFiNINA 1.8.13 is already installed.", lines[3]) - require.Equal(t, "✕ Arduino_ConnectionHandler 0.6.6 must be installed.", lines[4]) - require.Equal(t, "✕ MKRWAN 1.1.0 must be installed.", lines[5]) - require.Equal(t, "✕ WiFi101 0.16.1 must be installed.", lines[6]) + require.Regexp(t, `^✓ Arduino_DebugUtils \d+\.\d+\.\d+ is already installed\.$`, lines[0]) + require.Regexp(t, `^✓ MKRGSM \d+\.\d+\.\d+ is already installed\.$`, lines[1]) + require.Regexp(t, `^✓ MKRNB \d+\.\d+\.\d+ is already installed\.$`, lines[2]) + require.Regexp(t, `^✓ WiFiNINA \d+\.\d+\.\d+ is already installed\.$`, lines[3]) + require.Regexp(t, `^✕ Arduino_ConnectionHandler \d+\.\d+\.\d+ must be installed\.$`, lines[4]) + require.Regexp(t, `^✕ MKRWAN \d+\.\d+\.\d+ must be installed\.$`, lines[5]) + require.Regexp(t, `^✕ WiFi101 \d+\.\d+\.\d+ must be installed\.$`, lines[6]) stdOut, _, err = cli.Run("lib", "deps", "Arduino_ConnectionHandler@0.6.6", "--format", "json") require.NoError(t, err) - expectedOutput := `{"dependencies":[ - {"name":"Arduino_ConnectionHandler","version_required":"0.6.6"}, - {"name":"Arduino_DebugUtils","version_required":"1.3.0","version_installed":"1.3.0"}, - {"name":"MKRGSM","version_required":"1.5.0","version_installed":"1.5.0"}, - {"name":"MKRNB","version_required":"1.5.1","version_installed":"1.5.1"}, - {"name":"MKRWAN","version_required":"1.1.0"}, - {"name":"WiFi101","version_required":"0.16.1"}, - {"name":"WiFiNINA","version_required":"1.8.13","version_installed":"1.8.13"}]}` - require.JSONEq(t, expectedOutput, string(stdOut)) + + var jsonDeps struct { + Dependencies []struct { + Name string `json:"name"` + VersionRequired string `json:"version_required"` + VersionInstalled string `json:"version_installed"` + } `json:"dependencies"` + } + err = json.Unmarshal(stdOut, &jsonDeps) + require.NoError(t, err) + + require.Equal(t, "Arduino_ConnectionHandler", jsonDeps.Dependencies[0].Name) + require.Empty(t, jsonDeps.Dependencies[0].VersionInstalled) + require.Equal(t, "Arduino_DebugUtils", jsonDeps.Dependencies[1].Name) + require.Equal(t, jsonDeps.Dependencies[1].VersionInstalled, jsonDeps.Dependencies[1].VersionRequired) + require.Equal(t, "MKRGSM", jsonDeps.Dependencies[2].Name) + require.Equal(t, jsonDeps.Dependencies[2].VersionInstalled, jsonDeps.Dependencies[2].VersionRequired) + require.Equal(t, "MKRNB", jsonDeps.Dependencies[3].Name) + require.Equal(t, jsonDeps.Dependencies[3].VersionInstalled, jsonDeps.Dependencies[3].VersionRequired) + require.Equal(t, "MKRWAN", jsonDeps.Dependencies[4].Name) + require.Empty(t, jsonDeps.Dependencies[4].VersionInstalled) + require.Equal(t, "WiFi101", jsonDeps.Dependencies[5].Name) + require.Empty(t, jsonDeps.Dependencies[5].VersionInstalled) + require.Equal(t, "WiFiNINA", jsonDeps.Dependencies[6].Name) + require.Equal(t, jsonDeps.Dependencies[6].VersionInstalled, jsonDeps.Dependencies[6].VersionRequired) }