Skip to content

Commit 35fafd3

Browse files
authored
feat(main): Filter list-available to latest (#368)
Signed-off-by: Akhil Repala <[email protected]>
1 parent fdafaaa commit 35fafd3

File tree

3 files changed

+88
-18
lines changed

3 files changed

+88
-18
lines changed

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ Available Commands:
103103
Flags:
104104
-D, --debug enable debug logging
105105
-h, --help help for cardano-up
106+
-v, --verbose Show all available versions of packages
106107
107108
Use "cardano-up [command] --help" for more information about a command.
108109
```
@@ -157,7 +158,8 @@ Lists installed packages in the active context, or all contexts with `-A`
157158

158159
### `list-available`
159160

160-
List all packages available for install
161+
By default `list-available` lists only the latest version of each package available for install.
162+
Use the `--verbose` or `(-v)` flag to display all available versions of each package.
161163

162164
### `logs`
163165

cmd/cardano-up/list.go

Lines changed: 60 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919
"log/slog"
2020

2121
"github.com/blinklabs-io/cardano-up/pkgmgr"
22+
"github.com/hashicorp/go-version"
2223
"github.com/spf13/cobra"
2324
)
2425

@@ -27,12 +28,14 @@ var listFlags = struct {
2728
}{}
2829

2930
func listAvailableCommand() *cobra.Command {
30-
return &cobra.Command{
31+
cmd := &cobra.Command{
3132
Use: "list-available",
3233
Short: "List available packages",
3334
Run: func(cmd *cobra.Command, args []string) {
3435
pm := createPackageManager()
3536
packages := pm.AvailablePackages()
37+
verbose, _ := cmd.Flags().GetBool("verbose")
38+
3639
slog.Info("Available packages:\n")
3740
slog.Info(
3841
fmt.Sprintf(
@@ -42,28 +45,35 @@ func listAvailableCommand() *cobra.Command {
4245
"Description",
4346
),
4447
)
45-
for _, tmpPackage := range packages {
46-
slog.Info(
47-
fmt.Sprintf(
48-
"%-20s %-12s %s",
49-
tmpPackage.Name,
50-
tmpPackage.Version,
51-
tmpPackage.Description,
52-
),
53-
)
54-
if len(tmpPackage.Dependencies) > 0 {
55-
tmpOutput := " Requires: "
56-
for idx, dep := range tmpPackage.Dependencies {
57-
tmpOutput += dep
58-
if idx < len(tmpPackage.Dependencies)-1 {
59-
tmpOutput += ` | `
48+
if verbose {
49+
// show all versions of packages
50+
for _, tmpPackage := range packages {
51+
printPackageInfo(tmpPackage)
52+
}
53+
} else {
54+
// Shows only latest version of each package
55+
latestPackages := make(map[string]int)
56+
order := make([]string, 0)
57+
for index, pkg := range packages {
58+
packageName := pkg.Name
59+
packageVersion := pkg.Version
60+
existingIndex, exists := latestPackages[packageName]
61+
if !exists || compareVersions(packageVersion, packages[existingIndex].Version) {
62+
if !exists {
63+
order = append(order, packageName)
6064
}
65+
latestPackages[packageName] = index
6166
}
62-
slog.Info(tmpOutput)
67+
}
68+
for _, name := range order {
69+
printPackageInfo(packages[latestPackages[name]])
6370
}
6471
}
6572
},
6673
}
74+
// Added a verbose flag
75+
cmd.Flags().BoolP("verbose", "v", false, "Show all versions of packages")
76+
return cmd
6777
}
6878

6979
func listCommand() *cobra.Command {
@@ -111,3 +121,36 @@ func listCommand() *cobra.Command {
111121
BoolVarP(&listFlags.all, "all", "A", false, "show packages from all contexts (defaults to only active context)")
112122
return listCmd
113123
}
124+
125+
// Prints packge details
126+
func printPackageInfo(pkg pkgmgr.Package) {
127+
slog.Info(
128+
fmt.Sprintf(
129+
"%-20s %-12s %s",
130+
pkg.Name,
131+
pkg.Version,
132+
pkg.Description,
133+
),
134+
)
135+
if len(pkg.Dependencies) > 0 {
136+
tmpOutput := " Requires: "
137+
for idx, dep := range pkg.Dependencies {
138+
tmpOutput += dep
139+
if idx < len(pkg.Dependencies)-1 {
140+
tmpOutput += ` | `
141+
}
142+
}
143+
slog.Info(tmpOutput)
144+
}
145+
}
146+
147+
// Compare semantic version of packages
148+
func compareVersions(v1 string, v2 string) bool {
149+
ver1, err1 := version.NewVersion(v1)
150+
ver2, err2 := version.NewVersion(v2)
151+
152+
if err1 != nil || err2 != nil {
153+
return v1 > v2
154+
}
155+
return ver1.GreaterThan(ver2)
156+
}

cmd/cardano-up/list_test.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package main
2+
3+
import "testing"
4+
5+
func TestCompareVersions(t *testing.T) {
6+
cases := []struct {
7+
v1, v2 string
8+
expected bool
9+
}{
10+
{"10.1.1", "2.0.0", true},
11+
{"1.10.0", "1.9.0", true},
12+
{"1.2.3", "1.2.3", false},
13+
{"0.9.5", "1.0.0", false},
14+
}
15+
16+
for _, tc := range cases {
17+
result := compareVersions(tc.v1, tc.v2)
18+
if result == tc.expected {
19+
t.Logf("Test Passed: compareVersions(%s, %s) = %v (Expected: %v)\n", tc.v1, tc.v2, result, tc.expected)
20+
21+
} else {
22+
t.Errorf("Test Failed: compareVersions(%s, %s) = %v; Expected %v", tc.v1, tc.v2, result, tc.expected)
23+
}
24+
}
25+
}

0 commit comments

Comments
 (0)