Merge pull request '[agent/codex:gpt-5.4-mini] Read ~/spec/code/core/go/cli/RFC.md fully. Find ONE feature ...' (#20) from agent/update-the-code-against-the-ax-design-pr into dev
Some checks failed
Security Scan / security (push) Has been cancelled
Some checks failed
Security Scan / security (push) Has been cancelled
This commit is contained in:
commit
9ddf5bf426
2 changed files with 81 additions and 12 deletions
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
@ -114,3 +115,26 @@ func TestRunPkgList_UnsupportedFormat(t *testing.T) {
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
assert.Contains(t, err.Error(), "unsupported format")
|
assert.Contains(t, err.Error(), "unsupported format")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRenderPkgSearchResults_ShowsMetadata(t *testing.T) {
|
||||||
|
out := capturePkgOutput(t, func() {
|
||||||
|
renderPkgSearchResults([]ghRepo{
|
||||||
|
{
|
||||||
|
Name: "core-alpha",
|
||||||
|
Description: "Alpha package",
|
||||||
|
Visibility: "private",
|
||||||
|
StargazerCount: 42,
|
||||||
|
PrimaryLanguage: ghLanguage{
|
||||||
|
Name: "Go",
|
||||||
|
},
|
||||||
|
UpdatedAt: time.Now().Add(-2 * time.Hour).Format(time.RFC3339),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
assert.Contains(t, out, "core-alpha")
|
||||||
|
assert.Contains(t, out, "Alpha package")
|
||||||
|
assert.Contains(t, out, "42 stars")
|
||||||
|
assert.Contains(t, out, "Go")
|
||||||
|
assert.Contains(t, out, "updated 2h ago")
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"forge.lthn.ai/core/cli/pkg/cli"
|
||||||
"forge.lthn.ai/core/go-cache"
|
"forge.lthn.ai/core/go-cache"
|
||||||
"forge.lthn.ai/core/go-i18n"
|
"forge.lthn.ai/core/go-i18n"
|
||||||
coreio "forge.lthn.ai/core/go-io"
|
coreio "forge.lthn.ai/core/go-io"
|
||||||
|
|
@ -60,12 +61,17 @@ func addPkgSearchCommand(parent *cobra.Command) {
|
||||||
}
|
}
|
||||||
|
|
||||||
type ghRepo struct {
|
type ghRepo struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
FullName string `json:"full_name"`
|
FullName string `json:"fullName"`
|
||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
Visibility string `json:"visibility"`
|
Visibility string `json:"visibility"`
|
||||||
UpdatedAt string `json:"updated_at"`
|
UpdatedAt string `json:"updatedAt"`
|
||||||
Language string `json:"language"`
|
StargazerCount int `json:"stargazerCount"`
|
||||||
|
PrimaryLanguage ghLanguage `json:"primaryLanguage"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ghLanguage struct {
|
||||||
|
Name string `json:"name"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func runPkgSearch(org, pattern, repoType string, limit int, refresh bool) error {
|
func runPkgSearch(org, pattern, repoType string, limit int, refresh bool) error {
|
||||||
|
|
@ -107,7 +113,7 @@ func runPkgSearch(org, pattern, repoType string, limit int, refresh bool) error
|
||||||
fmt.Printf("%s %s... ", dimStyle.Render(i18n.T("cmd.pkg.search.fetching_label")), org)
|
fmt.Printf("%s %s... ", dimStyle.Render(i18n.T("cmd.pkg.search.fetching_label")), org)
|
||||||
|
|
||||||
cmd := exec.Command("gh", "repo", "list", org,
|
cmd := exec.Command("gh", "repo", "list", org,
|
||||||
"--json", "name,description,visibility,updatedAt,primaryLanguage",
|
"--json", "name,description,visibility,updatedAt,stargazerCount,primaryLanguage",
|
||||||
"--limit", fmt.Sprintf("%d", limit))
|
"--limit", fmt.Sprintf("%d", limit))
|
||||||
output, err := cmd.CombinedOutput()
|
output, err := cmd.CombinedOutput()
|
||||||
|
|
||||||
|
|
@ -152,9 +158,18 @@ func runPkgSearch(org, pattern, repoType string, limit int, refresh bool) error
|
||||||
return cmp.Compare(a.Name, b.Name)
|
return cmp.Compare(a.Name, b.Name)
|
||||||
})
|
})
|
||||||
|
|
||||||
fmt.Print(i18n.T("cmd.pkg.search.found_repos", map[string]int{"Count": len(filtered)}) + "\n\n")
|
renderPkgSearchResults(filtered)
|
||||||
|
|
||||||
for _, r := range filtered {
|
fmt.Println()
|
||||||
|
fmt.Printf("%s %s\n", i18n.T("common.hint.install_with"), dimStyle.Render(fmt.Sprintf("core pkg install %s/<repo-name>", org)))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func renderPkgSearchResults(repos []ghRepo) {
|
||||||
|
fmt.Print(i18n.T("cmd.pkg.search.found_repos", map[string]int{"Count": len(repos)}) + "\n\n")
|
||||||
|
|
||||||
|
for _, r := range repos {
|
||||||
visibility := ""
|
visibility := ""
|
||||||
if r.Visibility == "private" {
|
if r.Visibility == "private" {
|
||||||
visibility = dimStyle.Render(" " + i18n.T("cmd.pkg.search.private_label"))
|
visibility = dimStyle.Render(" " + i18n.T("cmd.pkg.search.private_label"))
|
||||||
|
|
@ -170,12 +185,42 @@ func runPkgSearch(org, pattern, repoType string, limit int, refresh bool) error
|
||||||
|
|
||||||
fmt.Printf(" %s%s\n", repoNameStyle.Render(r.Name), visibility)
|
fmt.Printf(" %s%s\n", repoNameStyle.Render(r.Name), visibility)
|
||||||
fmt.Printf(" %s\n", desc)
|
fmt.Printf(" %s\n", desc)
|
||||||
|
|
||||||
|
if meta := formatPkgSearchMetadata(r); meta != "" {
|
||||||
|
fmt.Printf(" %s\n", dimStyle.Render(meta))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func formatPkgSearchMetadata(r ghRepo) string {
|
||||||
|
var parts []string
|
||||||
|
|
||||||
|
if r.StargazerCount > 0 {
|
||||||
|
parts = append(parts, fmt.Sprintf("%d stars", r.StargazerCount))
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println()
|
if lang := strings.TrimSpace(r.PrimaryLanguage.Name); lang != "" {
|
||||||
fmt.Printf("%s %s\n", i18n.T("common.hint.install_with"), dimStyle.Render(fmt.Sprintf("core pkg install %s/<repo-name>", org)))
|
parts = append(parts, lang)
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
if updated := formatPkgSearchUpdatedAt(r.UpdatedAt); updated != "" {
|
||||||
|
parts = append(parts, "updated "+updated)
|
||||||
|
}
|
||||||
|
|
||||||
|
return strings.Join(parts, " ")
|
||||||
|
}
|
||||||
|
|
||||||
|
func formatPkgSearchUpdatedAt(raw string) string {
|
||||||
|
if raw == "" {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
updatedAt, err := time.Parse(time.RFC3339, raw)
|
||||||
|
if err != nil {
|
||||||
|
return raw
|
||||||
|
}
|
||||||
|
|
||||||
|
return cli.FormatAge(updatedAt)
|
||||||
}
|
}
|
||||||
|
|
||||||
// matchGlob does simple glob matching with * wildcards
|
// matchGlob does simple glob matching with * wildcards
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue