added github source search functionality
This commit is contained in:
parent
3fb40239fa
commit
85250a1b96
23
README.md
23
README.md
@ -65,6 +65,9 @@ Remove packages:\
|
||||
Search for packages:\
|
||||
```upm search nginx```
|
||||
|
||||
Search for source code:\
|
||||
```upm source nginx``` # Search GitHub for source code repositories
|
||||
|
||||
Update package lists:\
|
||||
```upm update```
|
||||
|
||||
@ -115,6 +118,13 @@ Install using snap:\
|
||||
Install using flatpak:\
|
||||
```upm -u flatpak install org.mozilla.firefox```
|
||||
|
||||
### Source Code Search
|
||||
|
||||
Search for source code repositories:
|
||||
`upm source nginx`
|
||||
|
||||
This command searches GitHub for source code repositories related to the specified package.
|
||||
|
||||
## Project Structure
|
||||
```
|
||||
upm-universalpackagemanager/
|
||||
@ -146,3 +156,16 @@ Supernets, PP4L, DigitalGangster
|
||||
## Support
|
||||
|
||||
If you encounter any issues or have questions, please file an issue on the git.supernets.org repository.
|
||||
|
||||
Commands:
|
||||
install <package1[@version]> [package2[@version]...] - Install packages
|
||||
remove <package1> [package2...] - Remove packages
|
||||
search <term> - Search for packages
|
||||
source <term> - Search GitHub for source code
|
||||
|
||||
Examples:
|
||||
upm install nginx@1.18.0
|
||||
upm -u snap install firefox
|
||||
upm repo add https://repo.example.com
|
||||
upm show-deps nginx
|
||||
upm source nginx # Find source code repositories
|
8
go.mod
8
go.mod
@ -1,15 +1,15 @@
|
||||
module git.supernets.org/e/managerofmanagers
|
||||
module upm
|
||||
|
||||
go 1.22
|
||||
|
||||
require (
|
||||
github.com/briandowns/spinner v1.23.0
|
||||
github.com/fatih/color v1.16.0
|
||||
github.com/briandowns/spinner v1.23.2
|
||||
github.com/fatih/color v1.18.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
golang.org/x/sys v0.14.0 // indirect
|
||||
golang.org/x/sys v0.25.0 // indirect
|
||||
golang.org/x/term v0.1.0 // indirect
|
||||
)
|
||||
|
12
go.sum
12
go.sum
@ -1,7 +1,7 @@
|
||||
github.com/briandowns/spinner v1.23.0 h1:alDF2guRWqa/FOZZYWjlMIx2L6H0wyewPxo/CH4Pt2A=
|
||||
github.com/briandowns/spinner v1.23.0/go.mod h1:rPG4gmXeN3wQV/TsAY4w8lPdIM6RX3yqeBQJSrbXjuE=
|
||||
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
|
||||
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
|
||||
github.com/briandowns/spinner v1.23.2 h1:Zc6ecUnI+YzLmJniCfDNaMbW0Wid1d5+qcTq4L2FW8w=
|
||||
github.com/briandowns/spinner v1.23.2/go.mod h1:LaZeM4wm2Ywy6vO571mvhQNRcWfRUnXOs0RcKV0wYKM=
|
||||
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
|
||||
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
@ -9,7 +9,7 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=
|
||||
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
|
||||
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.1.0 h1:g6Z6vPFA9dYBAF7DWcH6sCcOntplXsDKcliusYijMlw=
|
||||
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
|
12
main.go
12
main.go
@ -9,7 +9,7 @@ import (
|
||||
|
||||
"github.com/fatih/color"
|
||||
"github.com/briandowns/spinner"
|
||||
"git.supernets.org/e/managerofmanagers/pkg_manager"
|
||||
"upm/pkg_manager"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -274,6 +274,16 @@ func handleCommand(pm *pkg_manager.Manager, args []string) {
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
case "source":
|
||||
if len(cmdArgs) == 0 {
|
||||
fmt.Fprintln(os.Stderr, "Error: package name required")
|
||||
os.Exit(1)
|
||||
}
|
||||
if err := pm.HandleSource(cmdArgs[0]); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Failed to search source: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
default:
|
||||
fmt.Fprintf(os.Stderr, "Unknown command: %s\n", command)
|
||||
printUsage()
|
||||
|
60
pkg_manager/github.go
Normal file
60
pkg_manager/github.go
Normal file
@ -0,0 +1,60 @@
|
||||
package pkg_manager
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"time"
|
||||
)
|
||||
|
||||
type GitHubRepo struct {
|
||||
FullName string `json:"full_name"`
|
||||
Description string `json:"description"`
|
||||
HTMLURL string `json:"html_url"`
|
||||
Stars int `json:"stargazers_count"`
|
||||
Language string `json:"language"`
|
||||
}
|
||||
|
||||
type GitHubSearchResponse struct {
|
||||
TotalCount int `json:"total_count"`
|
||||
Items []GitHubRepo `json:"items"`
|
||||
}
|
||||
|
||||
func SearchGitHubSource(query string) ([]GitHubRepo, error) {
|
||||
baseURL := "https://api.github.com/search/repositories"
|
||||
|
||||
// Create search query
|
||||
params := url.Values{}
|
||||
params.Add("q", query)
|
||||
params.Add("sort", "stars")
|
||||
params.Add("order", "desc")
|
||||
params.Add("per_page", "5") // Limit to top 5 results
|
||||
|
||||
client := &http.Client{Timeout: 10 * time.Second}
|
||||
|
||||
req, err := http.NewRequest("GET", baseURL+"?"+params.Encode(), nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error creating request: %w", err)
|
||||
}
|
||||
|
||||
req.Header.Set("Accept", "application/vnd.github.v3+json")
|
||||
req.Header.Set("User-Agent", "UPM-Package-Manager")
|
||||
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error making request: %w", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return nil, fmt.Errorf("GitHub API returned status: %d", resp.StatusCode)
|
||||
}
|
||||
|
||||
var searchResp GitHubSearchResponse
|
||||
if err := json.NewDecoder(resp.Body).Decode(&searchResp); err != nil {
|
||||
return nil, fmt.Errorf("error decoding response: %w", err)
|
||||
}
|
||||
|
||||
return searchResp.Items, nil
|
||||
}
|
@ -6,6 +6,9 @@ import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/briandowns/spinner"
|
||||
)
|
||||
|
||||
// PackageManager interface defines common operations
|
||||
@ -24,6 +27,7 @@ type PackageManager interface {
|
||||
AutoRemove() error
|
||||
CheckDependencies(pkg string) error
|
||||
ShowDependencies(pkg string) error
|
||||
HandleSource(appName string) error
|
||||
}
|
||||
|
||||
// Manager represents a concrete package manager
|
||||
@ -423,4 +427,37 @@ func DetectPackageManager() (*Manager, error) {
|
||||
// NeedsSudo returns whether this package manager needs sudo
|
||||
func (m *Manager) NeedsSudo() bool {
|
||||
return m.needsSudo && os.Geteuid() != 0
|
||||
}
|
||||
|
||||
func (m *Manager) HandleSource(appName string) error {
|
||||
fmt.Printf("Searching source code for %s...\n", appName)
|
||||
|
||||
s := spinner.New(spinner.CharSets[9], 100*time.Millisecond)
|
||||
s.Start()
|
||||
|
||||
repos, err := SearchGitHubSource(appName)
|
||||
s.Stop()
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("error searching GitHub: %w", err)
|
||||
}
|
||||
|
||||
if len(repos) == 0 {
|
||||
fmt.Printf("No source code repositories found for '%s'\n", appName)
|
||||
return nil
|
||||
}
|
||||
|
||||
fmt.Printf("\nFound %d source code repositories:\n\n", len(repos))
|
||||
|
||||
for i, repo := range repos {
|
||||
fmt.Printf("%d. %s\n", i+1, repo.FullName)
|
||||
if repo.Description != "" {
|
||||
fmt.Printf(" Description: %s\n", repo.Description)
|
||||
}
|
||||
fmt.Printf(" Language: %s\n", repo.Language)
|
||||
fmt.Printf(" Stars: %d\n", repo.Stars)
|
||||
fmt.Printf(" URL: %s\n\n", repo.HTMLURL)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
Loading…
Reference in New Issue
Block a user