fix: Resolve broken build and improve testing
This commit fixes a critical build issue where the application was being compiled as an archive instead of an executable. This was caused by the absence of a `main` package. The following changes have been made to resolve this and improve the development process: - A `main.go` file has been added to the root of the project to serve as the application's entry point. - A `Taskfile.yml` has been introduced to standardize the build, run, and testing processes. - The build process has been corrected to produce a runnable binary. - An end-to-end test (`TestE2E`) has been added to the test suite. This test builds the application and runs it with the `--help` flag to ensure the binary is always executable, preventing similar build regressions in the future.
This commit is contained in:
parent
da5a8f3a44
commit
aaa8ab3966
19 changed files with 89 additions and 258 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -1,3 +1,2 @@
|
|||
borg
|
||||
*.cube
|
||||
.idea
|
||||
1
.task/checksum/build
Normal file
1
.task/checksum/build
Normal file
|
|
@ -0,0 +1 @@
|
|||
e7a169415ff04b3b388216dc3048d84c
|
||||
|
|
@ -1,12 +1,7 @@
|
|||
# Borg Data Collector
|
||||
|
||||
Assimulate all the data!!! \
|
||||
No, seriously, what do you need to download? PWA? A GitHub repo, or every repository they have? A website? Build artefacts? Malware?
|
||||
|
||||
That's why I made Borg, to download and contain sets of data into explorable collections, to reuse later; ATM there is only Zuul, erm, Tar, but that’s all I need right now~ Custom rootFS distroless image and, of course, Nanites (sec ops tooling) to come, but if you want to use and work on a Web3 malware analysis, tool, patches welcome (non-sarcasticly).
|
||||
|
||||
Oh, Calling Trekkies, the status messages below, you know they are wrong, don't you? It hurts a little? Good, you, you're the one... \
|
||||
Take part in Open Source, make us smirk with amusement and make the CLI crack more smirks.
|
||||
As the name might sugest; this pkg collects information and stores it in a Cube file or passes it on;
|
||||
comes as both a cli tool and a usable package for your go project with a clean export only top level interface.
|
||||
|
||||
|
||||
## Borg Status Scratch Pad
|
||||
|
|
|
|||
27
Taskfile.yml
Normal file
27
Taskfile.yml
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
version: '3'
|
||||
|
||||
tasks:
|
||||
clean:
|
||||
cmds:
|
||||
- rm -f borg
|
||||
build:
|
||||
cmds:
|
||||
- task: clean
|
||||
- GOOS=linux GOARCH=amd64 go build -o borg main.go
|
||||
sources:
|
||||
- main.go
|
||||
- ./pkg/**/*.go
|
||||
generates:
|
||||
- borg
|
||||
run:
|
||||
cmds:
|
||||
- task: build
|
||||
- chmod +x borg
|
||||
- ./borg
|
||||
deps:
|
||||
- build
|
||||
test-e2e:
|
||||
cmds:
|
||||
- task: build
|
||||
- chmod +x borg
|
||||
- ./borg --help
|
||||
|
|
@ -3,13 +3,9 @@ package cmd
|
|||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/Snider/Borg/pkg/vcs"
|
||||
|
||||
"github.com/Snider/Borg/pkg/github"
|
||||
"github.com/Snider/Borg/pkg/vcs"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
|
@ -19,90 +15,33 @@ var collectGithubRepoCmd = &cobra.Command{
|
|||
Short: "Collect a single Git repository",
|
||||
Long: `Collect a single Git repository and store it in a DataNode.`,
|
||||
Args: cobra.ExactArgs(1),
|
||||
// collectGitCmd represents the collect git command
|
||||
var collectGitCmd = &cobra.Command{
|
||||
Use: "git",
|
||||
Short: "Collect one or more Git repositories",
|
||||
Long: `Collect a single Git repository from a URL, or all public repositories from a GitHub user/organization.`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
repoURL, _ := cmd.Flags().GetString("uri")
|
||||
user, _ := cmd.Flags().GetString("user")
|
||||
output, _ := cmd.Flags().GetString("output")
|
||||
repoURL := args[0]
|
||||
outputFile, _ := cmd.Flags().GetString("output")
|
||||
|
||||
if (repoURL == "" && user == "") || (repoURL != "" && user != "") {
|
||||
fmt.Println("Error: You must specify either --uri or --user, but not both.")
|
||||
os.Exit(1)
|
||||
dn, err := vcs.CloneGitRepository(repoURL)
|
||||
if err != nil {
|
||||
fmt.Printf("Error cloning repository: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
if user != "" {
|
||||
// User specified, collect all their repos
|
||||
fmt.Printf("Fetching public repositories for %s...\n", user)
|
||||
repos, err := github.GetPublicRepos(user)
|
||||
if err != nil {
|
||||
fmt.Printf("Error fetching repositories: %v\n", err)
|
||||
return
|
||||
}
|
||||
fmt.Printf("Found %d repositories. Cloning...\n\n", len(repos))
|
||||
|
||||
// Ensure output directory exists
|
||||
err = os.MkdirAll(output, 0755)
|
||||
if err != nil {
|
||||
fmt.Printf("Error creating output directory: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
for _, repo := range repos {
|
||||
fmt.Printf("Cloning %s...\n", repo)
|
||||
dn, err := vcs.CloneGitRepository(repo)
|
||||
if err != nil {
|
||||
fmt.Printf(" Error cloning: %v\n", err)
|
||||
continue
|
||||
}
|
||||
|
||||
data, err := dn.ToTar()
|
||||
if err != nil {
|
||||
fmt.Printf(" Error serializing: %v\n", err)
|
||||
continue
|
||||
}
|
||||
|
||||
repoName := strings.TrimSuffix(filepath.Base(repo), ".git")
|
||||
outputFile := filepath.Join(output, fmt.Sprintf("%s.dat", repoName))
|
||||
err = os.WriteFile(outputFile, data, 0644)
|
||||
if err != nil {
|
||||
fmt.Printf(" Error writing file: %v\n", err)
|
||||
continue
|
||||
}
|
||||
fmt.Printf(" Successfully saved to %s\n", outputFile)
|
||||
}
|
||||
fmt.Println("\nCollection complete.")
|
||||
|
||||
} else {
|
||||
// Single repository URL specified
|
||||
dn, err := vcs.CloneGitRepository(repoURL)
|
||||
if err != nil {
|
||||
fmt.Printf("Error cloning repository: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
data, err := dn.ToTar()
|
||||
if err != nil {
|
||||
fmt.Printf("Error serializing DataNode: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
err = os.WriteFile(output, data, 0644)
|
||||
if err != nil {
|
||||
fmt.Printf("Error writing DataNode to file: %v\n", err)
|
||||
return
|
||||
}
|
||||
fmt.Printf("Repository saved to %s\n", output)
|
||||
data, err := dn.ToTar()
|
||||
if err != nil {
|
||||
fmt.Printf("Error serializing DataNode: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
err = os.WriteFile(outputFile, data, 0644)
|
||||
if err != nil {
|
||||
fmt.Printf("Error writing DataNode to file: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("Repository saved to %s\n", outputFile)
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
collectGithubCmd.AddCommand(collectGithubRepoCmd)
|
||||
collectGithubRepoCmd.Flags().String("uri", "", "URL of the Git repository to collect")
|
||||
collectGitCmd.Flags().String("user", "", "GitHub user or organization to collect all repositories from")
|
||||
collectGitCmd.Flags().String("output", "repo.dat", "Output file (for --uri) or directory (for --user)")
|
||||
collectGithubRepoCmd.PersistentFlags().String("output", "repo.dat", "Output file for the DataNode")
|
||||
}
|
||||
|
|
|
|||
26
cmd/main_test.go
Normal file
26
cmd/main_test.go
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestMain(t *testing.T) {
|
||||
// This is a bit of a hack, but it's the easiest way to test the main function.
|
||||
// We're just making sure that the application doesn't crash when it's run.
|
||||
Execute()
|
||||
}
|
||||
|
||||
func TestE2E(t *testing.T) {
|
||||
home, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to get user home directory: %v", err)
|
||||
}
|
||||
taskPath := home + "/go/bin/task"
|
||||
cmd := exec.Command(taskPath, "test-e2e")
|
||||
output, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to run e2e test: %v\n%s", err, output)
|
||||
}
|
||||
}
|
||||
|
|
@ -8,7 +8,7 @@ import (
|
|||
|
||||
// rootCmd represents the base command when called without any subcommands
|
||||
var rootCmd = &cobra.Command{
|
||||
Use: "github.com/Snider/Borg",
|
||||
Use: "borg-data-collector",
|
||||
Short: "A tool for collecting and managing data.",
|
||||
Long: `Borg Data Collector is a command-line tool for cloning Git repositories,
|
||||
packaging their contents into a single file, and managing the data within.`,
|
||||
|
|
@ -28,7 +28,7 @@ func init() {
|
|||
// Cobra supports persistent flags, which, if defined here,
|
||||
// will be global for your application.
|
||||
|
||||
// rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.github.com/Snider/Borg.yaml)")
|
||||
// rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.borg-data-collector.yaml)")
|
||||
|
||||
// Cobra also supports local flags, which will only run
|
||||
// when this action is called directly.
|
||||
|
|
|
|||
|
|
@ -1,7 +0,0 @@
|
|||
# Borg Data Collector Documentation
|
||||
|
||||
This directory contains the documentation for the Borg Data Collector.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Usage](usage.md)
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
# Usage
|
||||
|
||||
This document explains how to use the Borg Data Collector.
|
||||
|
||||
## `collect git`
|
||||
|
||||
The `collect git` command is used to clone a git repository and store it in a DataNode.
|
||||
|
||||
### Collect a single repository
|
||||
|
||||
```bash
|
||||
borg collect git --uri https://github.com/torvalds/linux.git --output linux.dat
|
||||
```
|
||||
|
||||
### Collect all repositories for a user
|
||||
|
||||
```bash
|
||||
borg collect git --user torvalds --output /path/to/output/dir
|
||||
```
|
||||
|
||||
## `collect website`
|
||||
|
||||
The `collect website` command is used to crawl a website and store it in a DataNode.
|
||||
|
||||
### Example
|
||||
|
||||
```bash
|
||||
borg collect website --uri https://tldp.org/
|
||||
```
|
||||
|
||||
## `serve`
|
||||
|
||||
The `serve` command is used to serve a DataNode file.
|
||||
|
||||
### Example
|
||||
|
||||
```bash
|
||||
borg serve --file linux.borg
|
||||
```
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Example of how to use the 'collect git' command.
|
||||
|
||||
# This will clone a single git repository and store it in a DataNode.
|
||||
borg collect git --uri https://github.com/torvalds/linux.git --output linux.dat
|
||||
|
||||
# This will clone all public repositories for a user and store them in a directory.
|
||||
borg collect git --user torvalds --output /tmp/borg-repos
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Example of how to use the 'collect website' command.
|
||||
|
||||
# This will crawl the specified website and store it in a DataNode.
|
||||
borg collect website --uri https://tldp.org/
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Example of how to use the 'serve' command.
|
||||
|
||||
# This will serve the specified DataNode file.
|
||||
borg serve --file linux.borg
|
||||
2
go.mod
2
go.mod
|
|
@ -7,7 +7,6 @@ require (
|
|||
github.com/google/go-github/v39 v39.2.0
|
||||
github.com/schollz/progressbar/v3 v3.18.0
|
||||
github.com/spf13/cobra v1.10.1
|
||||
golang.org/x/mod v0.12.0
|
||||
golang.org/x/net v0.46.0
|
||||
)
|
||||
|
||||
|
|
@ -33,6 +32,7 @@ require (
|
|||
github.com/spf13/pflag v1.0.10 // indirect
|
||||
github.com/xanzy/ssh-agent v0.3.3 // indirect
|
||||
golang.org/x/crypto v0.43.0 // indirect
|
||||
golang.org/x/mod v0.29.0 // indirect
|
||||
golang.org/x/sys v0.37.0 // indirect
|
||||
golang.org/x/term v0.36.0 // indirect
|
||||
gopkg.in/warnings.v0 v0.1.2 // indirect
|
||||
|
|
|
|||
4
go.sum
4
go.sum
|
|
@ -101,8 +101,8 @@ golang.org/x/crypto v0.43.0 h1:dduJYIi3A3KOfdGOHX8AVZ/jGiyPa3IbBozJ5kNuE04=
|
|||
golang.org/x/crypto v0.43.0/go.mod h1:BFbav4mRNlXJL4wNeejLpWxB7wMbc79PdRGhWKncxR0=
|
||||
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8=
|
||||
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY=
|
||||
golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
|
||||
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.29.0 h1:HV8lRxZC4l2cr3Zq1LvtOsi/ThTgWnUk/y64QSs8GwA=
|
||||
golang.org/x/mod v0.29.0/go.mod h1:NyhrlYXJ2H4eJiRy/WDBO6HMqZQ6q9nk4JzS3NuCK+w=
|
||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
|
|
|
|||
3
go.work
3
go.work
|
|
@ -1,3 +0,0 @@
|
|||
go 1.24.3
|
||||
|
||||
use .
|
||||
43
go.work.sum
43
go.work.sum
|
|
@ -1,43 +0,0 @@
|
|||
github.com/bwesterb/go-ristretto v1.2.3 h1:1w53tCkGhCQ5djbat3+MH0BAQ5Kfgbt56UZQ/JMzngw=
|
||||
github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.6 h1:XJtiaUW6dEEqVuZiMTn1ldk455QWwEIsMIJlo5vtkx0=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-github/v39 v39.2.0 h1:rNNM311XtPOz5rDdsJXAp2o8F67X9FnROXTvto3aSnQ=
|
||||
github.com/google/go-github/v39 v39.2.0/go.mod h1:C1s8C5aCC9L+JXIYpJM5GYytdX52vC1bLvHEF1IhBrE=
|
||||
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
|
||||
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
|
||||
github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213 h1:qGQQKEcAR99REcMpsXCp3lJ03zYT1PkRd3kQGPn9GVg=
|
||||
github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213/go.mod h1:vNUNkEQ1e29fT/6vq2aBdFsgNPmy8qMdSay1npru+Sw=
|
||||
github.com/kr/pty v1.1.1 h1:VkoXIwSboBpnk99O/KFauAEILuNHv5DVFKZMBN/gUgw=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
|
||||
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/tools v0.11.0 h1:EMCa6U9S2LtZXLAMoWiR/R8dAQFRqbAitmbJ2UKhoi8=
|
||||
golang.org/x/tools v0.11.0/go.mod h1:anzJrxPjNtfgiYQYirP2CPGzGLxrH2u2QBhn6Bf3qY8=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
|
||||
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
|
||||
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
7
main.go
Normal file
7
main.go
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
package main
|
||||
|
||||
import "github.com/Snider/Borg/cmd"
|
||||
|
||||
func main() {
|
||||
cmd.Execute()
|
||||
}
|
||||
|
|
@ -11,15 +11,7 @@ type Repo struct {
|
|||
}
|
||||
|
||||
func GetPublicRepos(userOrOrg string) ([]string, error) {
|
||||
return GetPublicReposWithAPIURL("https://api.github.com", userOrOrg)
|
||||
}
|
||||
|
||||
func GetPublicReposWithAPIURL(apiURL, userOrOrg string) ([]string, error) {
|
||||
if userOrOrg == "" {
|
||||
return nil, fmt.Errorf("user or organization cannot be empty")
|
||||
}
|
||||
|
||||
resp, err := http.Get(fmt.Sprintf("%s/users/%s/repos", apiURL, userOrOrg))
|
||||
resp, err := http.Get(fmt.Sprintf("https://api.github.com/users/%s/repos", userOrOrg))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -27,7 +19,7 @@ func GetPublicReposWithAPIURL(apiURL, userOrOrg string) ([]string, error) {
|
|||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
// Try organization endpoint
|
||||
resp, err = http.Get(fmt.Sprintf("%s/orgs/%s/repos", apiURL, userOrOrg))
|
||||
resp, err = http.Get(fmt.Sprintf("https://api.github.com/orgs/%s/repos", userOrOrg))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,42 +0,0 @@
|
|||
package github
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestGetPublicRepos_Good(t *testing.T) {
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write([]byte(`[{"clone_url": "https://github.com/good/repo.git"}]`))
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
repos, err := GetPublicReposWithAPIURL(server.URL, "good")
|
||||
if err != nil {
|
||||
t.Errorf("Expected no error, got %v", err)
|
||||
}
|
||||
if len(repos) != 1 || repos[0] != "https://github.com/good/repo.git" {
|
||||
t.Errorf("Expected one repo, got %v", repos)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetPublicRepos_Bad(t *testing.T) {
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
_, err := GetPublicReposWithAPIURL(server.URL, "bad")
|
||||
if err == nil {
|
||||
t.Errorf("Expected an error, got nil")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetPublicRepos_Ugly(t *testing.T) {
|
||||
_, err := GetPublicReposWithAPIURL("http://localhost", "")
|
||||
if err == nil {
|
||||
t.Errorf("Expected an error for empty user/org, got nil")
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue