2020-07-02 19:36:10 +01:00
|
|
|
package src
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"context"
|
|
|
|
|
"fmt"
|
|
|
|
|
"os"
|
|
|
|
|
"path"
|
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
|
|
"github.com/go-git/go-git/v5"
|
|
|
|
|
"github.com/go-git/go-git/v5/config"
|
|
|
|
|
"github.com/spf13/cobra"
|
|
|
|
|
)
|
|
|
|
|
|
2020-09-18 16:50:26 -04:00
|
|
|
type PullOnlyFlags struct {
|
|
|
|
|
SourceURL string
|
|
|
|
|
}
|
2020-07-02 19:36:10 +01:00
|
|
|
|
|
|
|
|
type PullFlags struct {
|
2020-09-18 16:50:26 -04:00
|
|
|
CommonFlags
|
|
|
|
|
PullOnlyFlags
|
2020-07-02 19:36:10 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (f *PullFlags) Init(cmd *cobra.Command) {
|
2020-09-18 16:50:26 -04:00
|
|
|
f.CommonFlags.Init(cmd)
|
|
|
|
|
f.PullOnlyFlags.Init(cmd)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (f *PullOnlyFlags) Init(cmd *cobra.Command) {
|
2020-07-02 19:36:10 +01:00
|
|
|
cmd.Flags().StringVar(&f.SourceURL, "source-url", "https://github.com", "The domain to pull from")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (f *PullFlags) Validate() Validations {
|
2020-09-18 16:50:26 -04:00
|
|
|
return f.CommonFlags.Validate(true).Join(f.PullOnlyFlags.Validate())
|
2020-07-02 19:36:10 +01:00
|
|
|
}
|
|
|
|
|
|
2020-09-18 16:50:26 -04:00
|
|
|
func (f *PullOnlyFlags) Validate() Validations {
|
|
|
|
|
var validations Validations
|
|
|
|
|
return validations
|
2020-07-02 19:36:10 +01:00
|
|
|
}
|
|
|
|
|
|
2020-09-18 16:50:26 -04:00
|
|
|
func Pull(ctx context.Context, flags *PullFlags) error {
|
|
|
|
|
repoNames, err := getRepoNamesFromRepoFlags(&flags.CommonFlags)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
2020-07-02 19:36:10 +01:00
|
|
|
}
|
2020-09-18 16:50:26 -04:00
|
|
|
|
|
|
|
|
return PullManyWithGitImpl(ctx, flags.SourceURL, flags.CacheDir, repoNames, gitImplementation{})
|
2020-07-02 19:36:10 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func PullManyWithGitImpl(ctx context.Context, sourceURL, cacheDir string, repoNames []string, gitimpl GitImplementation) error {
|
|
|
|
|
for _, repoName := range repoNames {
|
|
|
|
|
if err := PullWithGitImpl(ctx, sourceURL, cacheDir, repoName, gitimpl); err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func PullWithGitImpl(ctx context.Context, sourceURL, cacheDir string, repoName string, gitimpl GitImplementation) error {
|
2020-09-18 16:50:26 -04:00
|
|
|
originRepoName, destRepoName, err := extractSourceDest(repoName)
|
2020-07-02 19:36:10 +01:00
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
2020-09-18 16:50:26 -04:00
|
|
|
|
2020-07-02 19:36:10 +01:00
|
|
|
_, err = os.Stat(cacheDir)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dst := path.Join(cacheDir, destRepoName)
|
|
|
|
|
|
|
|
|
|
if !gitimpl.RepositoryExists(dst) {
|
|
|
|
|
fmt.Fprintf(os.Stdout, "pulling %s to %s ...\n", originRepoName, dst)
|
|
|
|
|
_, err := gitimpl.CloneRepository(dst, &git.CloneOptions{
|
|
|
|
|
SingleBranch: false,
|
|
|
|
|
URL: fmt.Sprintf("%s/%s", sourceURL, originRepoName),
|
|
|
|
|
})
|
|
|
|
|
if err != nil {
|
|
|
|
|
if strings.Contains(err.Error(), "authentication required") {
|
|
|
|
|
return fmt.Errorf("could not pull %s, the repository may require authentication or does not exist", originRepoName)
|
|
|
|
|
}
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
repo, err := gitimpl.NewGitRepository(dst)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fmt.Fprintf(os.Stdout, "fetching * refs for %s ...\n", originRepoName)
|
|
|
|
|
err = repo.FetchContext(ctx, &git.FetchOptions{
|
|
|
|
|
RefSpecs: []config.RefSpec{
|
|
|
|
|
config.RefSpec("+refs/heads/*:refs/heads/*"),
|
|
|
|
|
},
|
|
|
|
|
Tags: git.AllTags,
|
|
|
|
|
})
|
|
|
|
|
if err != nil && err != git.NoErrAlreadyUpToDate {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|