From bef2897564ac13b000c0c463a1aa74d76cb9d911 Mon Sep 17 00:00:00 2001 From: Evan Maddock <5157277+EbonJaeger@users.noreply.github.com> Date: Wed, 20 Sep 2023 11:15:47 -0400 Subject: [PATCH] Switch to go-git (#39) This switches the git library to go-git, which affords a couple of benefits. Mainly, the API is much nicer to use than libgit2. Using go-git also makes it easier to build the history for a package, since we no longer use git tags. I tested this locally by building Caddy, which mixes tarbal and git sources, and gave me problems the last go-around. --------- Signed-off-by: Evan Maddock --- builder/history.go | 155 ++++++++++----------------- builder/manager.go | 7 +- builder/source/git.go | 236 +++++++++++------------------------------- cli/build.go | 2 +- go.mod | 28 ++++- go.sum | 149 ++++++++++++++++++++++---- 6 files changed, 272 insertions(+), 305 deletions(-) diff --git a/builder/history.go b/builder/history.go index 7074fed..43f1cf8 100644 --- a/builder/history.go +++ b/builder/history.go @@ -19,14 +19,16 @@ package builder import ( "encoding/xml" "errors" - "fmt" + "io" "os" "path/filepath" "regexp" "sort" "time" - git "github.com/libgit2/git2go/v34" + "github.com/go-git/go-git/v5" + "github.com/go-git/go-git/v5/plumbing" + "github.com/go-git/go-git/v5/plumbing/object" ) const ( @@ -71,28 +73,28 @@ type PackageHistory struct { // A PackageUpdate is a point in history in the git changes, which is parsed // from a git.Commit. type PackageUpdate struct { - Tag string // The associated git tag - Author string // The author name of the change - AuthorEmail string // The author email of the change - Body string // The associated message of the commit - Time time.Time // When the update took place - ObjectID string // OID stored in string form - Package *Package // Associated parsed package - IsSecurity bool // Whether this is a security update + Commit plumbing.Hash // The associated git commit + Author string // The author name of the change + AuthorEmail string // The author email of the change + Body string // The associated message of the commit + Time time.Time // When the update took place + ObjectID string // OID stored in string form + Package *Package // Associated parsed package + IsSecurity bool // Whether this is a security update } // NewPackageUpdate will attempt to parse the given commit and provide a usable // entry for the PackageHistory. -func NewPackageUpdate(tag string, commit *git.Commit, objectID string) *PackageUpdate { - signature := commit.Author() - update := &PackageUpdate{Tag: tag} - - // We duplicate. cgo makes life difficult. - update.Author = signature.Name - update.AuthorEmail = signature.Email - update.Body = commit.Message() - update.Time = signature.When - update.ObjectID = objectID +func NewPackageUpdate(commit *object.Commit, objectID string) *PackageUpdate { + signature := commit.Author + update := &PackageUpdate{ + Commit: commit.Hash, + Author: signature.Name, + AuthorEmail: signature.Email, + Body: commit.Message, + Time: signature.When, + ObjectID: objectID, + } // Attempt to identify the update type. Limit to 1 match, we only need to // know IF there is a CVE fix, not how many. @@ -105,44 +107,34 @@ func NewPackageUpdate(tag string, commit *git.Commit, objectID string) *PackageU } // CatGitBlob will return the contents of the given entry. -func CatGitBlob(repo *git.Repository, entry *git.TreeEntry) ([]byte, error) { - obj, err := repo.Lookup(entry.Id) +func CatGitBlob(repo *git.Repository, entry *object.TreeEntry) ([]byte, error) { + obj, err := repo.BlobObject(entry.Hash) if err != nil { return nil, err } - blob, err := obj.AsBlob() + reader, err := obj.Reader() if err != nil { return nil, err } - return blob.Contents(), nil + return io.ReadAll(reader) } // GetFileContents will attempt to read the entire object at path from // the given tag, within that repo. -func GetFileContents(repo *git.Repository, tag, path string) ([]byte, error) { - oid, err := git.NewOid(tag) - if err != nil { - return nil, err - } - - commit, err := repo.Lookup(oid) +func GetFileContents(repo *git.Repository, hash plumbing.Hash, path string) ([]byte, error) { + commit, err := repo.CommitObject(hash) if err != nil { return nil, err } - treeObj, err := commit.Peel(git.ObjectTree) + tree, err := commit.Tree() if err != nil { return nil, err } - tree, err := treeObj.AsTree() - if err != nil { - return nil, err - } - - entry, err := tree.EntryByPath(path) + entry, err := tree.FindEntry(path) if err != nil { return nil, err } @@ -157,84 +149,47 @@ func GetFileContents(repo *git.Repository, tag, path string) ([]byte, error) { // The repository path will be taken as the directory name of the pkgfile that // is given to this function. func NewPackageHistory(pkgfile string) (*PackageHistory, error) { - // Repodir - path := filepath.Dir(pkgfile) + // Get the root of the package repo + packageDir := filepath.Dir(pkgfile) - repo, err := git.OpenRepository(path) + repo, err := git.PlainOpenWithOptions(packageDir, &git.PlainOpenOptions{ + DetectDotGit: true, + }) if err != nil { return nil, err } - // Get all the tags - var tags []string - tags, err = repo.Tags.List() - if err != nil { - return nil, err - } + var hashes []string updates := make(map[string]*PackageUpdate) - // Iterate all of the tags - err = repo.Tags.Foreach(func(name string, id *git.Oid) error { - if name == "" || id == nil { - return nil - } - - var commit *git.Commit - - obj, rErr := repo.Lookup(id) - if rErr != nil { - return rErr - } - - switch obj.Type() { - // Unannotated tag - case git.ObjectCommit: - commit, rErr = obj.AsCommit() - if rErr != nil { - return rErr - } - - tags = append(tags, name) - // Annotated tag with commit target - case git.ObjectTag: - tag, tErr := obj.AsTag() - if tErr != nil { - return tErr - } - - commit, tErr = repo.LookupCommit(tag.TargetId()) - if tErr != nil { - return tErr - } - - tags = append(tags, name) - default: - return fmt.Errorf("Internal git error, found %s", obj.Type().String()) - } - - if commit == nil { - return nil - } - - commitObj := NewPackageUpdate(name, commit, id.String()) - updates[name] = commitObj + cIter, err := repo.Log(&git.LogOptions{ + FileName: &packageDir, + }) + if err != nil { + return nil, err + } + err = cIter.ForEach(func(commit *object.Commit) error { + hash := commit.ID().String() + hashes = append(hashes, hash) + updates[hash] = NewPackageUpdate(commit, hash) return nil }) - // Foreach went bork + if err != nil { return nil, err } + // Sort the tags by -refname - sort.Sort(sort.Reverse(sort.StringSlice(tags))) + sort.Sort(sort.Reverse(sort.StringSlice(hashes))) ret := &PackageHistory{pkgfile: pkgfile} - ret.scanUpdates(repo, updates, tags) + ret.scanUpdates(repo, updates, hashes) updates = nil if len(ret.Updates) < 1 { - return nil, errors.New("No usable git history found") + return nil, errors.New("no usable git history found") } // All done! @@ -258,20 +213,20 @@ func (a SortUpdatesByRelease) Less(i, j int) bool { // scanUpdates will go back through the collected, "ok" tags, and analyze // them to be more useful. -func (p *PackageHistory) scanUpdates(repo *git.Repository, updates map[string]*PackageUpdate, tags []string) { +func (p *PackageHistory) scanUpdates(repo *git.Repository, updates map[string]*PackageUpdate, hashes []string) { // basename of file fname := filepath.Base(p.pkgfile) - updateSet := make([]*PackageUpdate, 0, len(tags)) + updateSet := make([]*PackageUpdate, 0, len(hashes)) // Iterate the commit set in order - for _, tagID := range tags { + for _, tagID := range hashes { update := updates[tagID] if update == nil { continue } - b, err := GetFileContents(repo, update.ObjectID, fname) + b, err := GetFileContents(repo, update.Commit, fname) if err != nil { continue } diff --git a/builder/manager.go b/builder/manager.go index 01b1be8..4fc9663 100644 --- a/builder/manager.go +++ b/builder/manager.go @@ -183,14 +183,15 @@ func (m *Manager) SetPackage(pkg *Package) error { // Obtain package history for git builds if pkg.Type == PackageTypeYpkg { - repoDir := filepath.Dir(pkg.Path) - if PathExists(filepath.Join(repoDir, ".git")) { + if PathExists(filepath.Join("../../..", ".git")) { + log.Goodln("yay, found the root dir!") + if history, err := NewPackageHistory(pkg.Path); err == nil { log.Debugln("Obtained package history") m.history = history } else { - log.Warnf("Failed to obtain package git history %s\n", err) + log.Warnf("Failed to obtain package git history: %s\n", err) } } } diff --git a/builder/source/git.go b/builder/source/git.go index 53f464e..6583bd0 100644 --- a/builder/source/git.go +++ b/builder/source/git.go @@ -17,7 +17,6 @@ package source import ( - "errors" "fmt" "net/url" "os" @@ -25,8 +24,8 @@ import ( "strings" log "github.com/DataDrake/waterlog" - "github.com/getsolus/libosdev/commands" - git "github.com/libgit2/git2go/v34" + git "github.com/go-git/go-git/v5" + "github.com/go-git/go-git/v5/plumbing" ) const ( @@ -34,9 +33,6 @@ const ( GitSourceDir = "/var/lib/solbuild/sources/git" ) -// ErrGitNoContinue is returned when git processing cannot continue. -var ErrGitNoContinue = errors.New("Fatal errors in git fetch") - // A GitSource as referenced by `ypkg` build spec. A git source must have // a valid ref to check out to. type GitSource struct { @@ -72,121 +68,6 @@ func NewGit(uri, ref string) (*GitSource, error) { return g, nil } -// message will be called to emit standard git text to the terminal. -func (g *GitSource) message(str string) error { - os.Stdout.Write([]byte(str)) - return nil -} - -// CreateCallbacks will create the default git callbacks. -func (g *GitSource) CreateCallbacks() git.RemoteCallbacks { - return git.RemoteCallbacks{ - SidebandProgressCallback: g.message, - } -} - -// Clone will set do a bare mirror clone of the remote repo to the local -// cache. -func (g *GitSource) Clone() error { - // Attempt cloning - log.Debugf("Cloning git source %s\n", g.URI) - - fetchOpts := &git.FetchOptions{ - RemoteCallbacks: g.CreateCallbacks(), - } - - _, err := git.Clone(g.URI, g.ClonePath, &git.CloneOptions{ - Bare: false, - FetchOptions: *fetchOpts, - }) - - return err -} - -// HasTag will attempt to find the tag, if possible. -func (g *GitSource) HasTag(repo *git.Repository, tagName string) bool { - haveTag := false - - repo.Tags.Foreach(func(name string, id *git.Oid) error { - if name == "refs/tags/"+tagName { - haveTag = true - } - - return nil - }) - - return haveTag -} - -// fetch will attempt. -func (g *GitSource) fetch(repo *git.Repository) error { - log.Infof("Git fetching existing clone %s\n", g.URI) - - remote, err := repo.Remotes.Lookup("origin") - if err != nil { - log.Errorf("Failed to find git remote %s %s\n", g.URI, err) - return err - } - - fetchOpts := &git.FetchOptions{ - RemoteCallbacks: g.CreateCallbacks(), - } - - return remote.Fetch([]string{}, fetchOpts, "") -} - -// GetCommitID will attempt to find the oid of the selected ref type. -func (g *GitSource) GetCommitID(repo *git.Repository) string { - oid := "" - // Attempt to find the branch - branch, err := repo.LookupBranch(g.Ref, git.BranchAll) - if err == nil { - oid = branch.Target().String() - log.Debugf("Found git commit of branch %s %s\n", g.Ref, oid) - - return oid - } - - tagName := g.Ref - if !strings.HasPrefix(tagName, "refs/tags") { - tagName = "refs/tags/" + tagName - } - - repo.Tags.Foreach(func(name string, id *git.Oid) error { - if name == tagName { - oid = id.String() - // Force break the foreach - return errors.New("") - } - - return nil - }) - - // Tag set the oid - if oid != "" { - log.Debugf("Found git commit of tag %s %s\n", tagName, oid) - return oid - } - - // Check the oid is valid - oid = g.Ref - - obj, err := git.NewOid(oid) - if err != nil { - return "" - } - - // Check if its a commit - _, err = repo.Lookup(obj) - if err != nil { - return "" - } - - log.Debugf("Found git commit %s %s\n", tagName, oid) - - return obj.String() -} - // GetHead will attempt to gain the OID for head. func (g *GitSource) GetHead(repo *git.Repository) (string, error) { head, err := repo.Head() @@ -197,98 +78,97 @@ func (g *GitSource) GetHead(repo *git.Repository) (string, error) { return head.Target().String(), nil } -// resetOnto will attempt to reset the repo (hard) onto the given commit. -func (g *GitSource) resetOnto(repo *git.Repository, ref string) error { - // this stuff _really_ shouldn't happen but oh well. - oid, err := git.NewOid(ref) - if err != nil { - return err - } - - commitFind, err := repo.Lookup(oid) +// submodules will handle setup of the git submodules after a +// reset has taken place. +func (g *GitSource) submodules(tree *git.Worktree) error { + submodules, err := tree.Submodules() if err != nil { return err } - commitObj, err := commitFind.Peel(git.ObjectCommit) - if err != nil { - return err + if len(submodules) == 0 { + return nil } - commit, err := commitObj.AsCommit() - if err != nil { - return err + opts := git.SubmoduleUpdateOptions{ + Init: true, + RecurseSubmodules: git.DefaultSubmoduleRecursionDepth, } - log.Debugf("Resetting git repository to commit %s\n", ref) - - checkOpts := &git.CheckoutOptions{ - Strategy: git.CheckoutForce | git.CheckoutRemoveUntracked | git.CheckoutRemoveIgnored, - } + return submodules.Update(&opts) +} - if err := repo.ResetToCommit(commit, git.ResetHard, checkOpts); err != nil { - log.Errorf("Failed to reset git repository %s %s\n", ref, err) - return err +func clone(uri, path, ref string) (*git.Repository, error) { + refName := plumbing.NewRemoteReferenceName("origin", ref) + cloneOpts := git.CloneOptions{ + URL: uri, + ReferenceName: refName, + SingleBranch: true, + Depth: 1, + RecurseSubmodules: git.DefaultSubmoduleRecursionDepth, + Progress: os.Stdout, } - return nil -} - -// submodules will handle setup of the git submodules after a -// reset has taken place. -func (g *GitSource) submodules() error { - // IDK What else to tell ya, git2go submodules is broken - cmd := []string{"submodule", "update", "--init", "--recursive"} - return commands.ExecStdoutArgsDir(g.ClonePath, "git", cmd) + return git.PlainClone(path, true, &cloneOpts) } // Fetch will attempt to download the git tree locally. If it already exists // then we'll make an attempt to update it. func (g *GitSource) Fetch() error { - hadRepo := true - - // First things first, clone if necessary + // First things first, make sure we have a destination if !PathExists(g.ClonePath) { - if err := g.Clone(); err != nil { - log.Errorf("Failed to clone remote repository %s %s\n", g.URI, err) + log.Debugf("making shallow clone of repo at '%s'\n", g.ClonePath) + + _, err := clone(g.URI, g.ClonePath, g.Ref) + if err != nil { return err } - hadRepo = false + return nil } - // Now open the repo and validate it - repo, err := git.OpenRepository(g.ClonePath) + // Repo already on disk, just open it + log.Debugf("source repo clone found on disk at '%s'\n", g.ClonePath) + + repo, err := git.PlainOpen(g.ClonePath) if err != nil { return err } - wantedCommit := g.GetCommitID(repo) - if wantedCommit == "" { - // Logic here being we just cloned it. Where is it? - if !hadRepo { - return fmt.Errorf("Cannot continue with git processing") - } - // So try to fetch it - if err := g.fetch(repo); err != nil { - return err + // Get the ref we want + var hash plumbing.Hash + + if len(g.Ref) != 40 { + log.Debugf("reference '%s' does not look like a hash; attempting to resolve\n", g.Ref) + + h, resolveErr := repo.ResolveRevision(plumbing.Revision(g.Ref)) + if resolveErr != nil { + return resolveErr } - // Re-establish the wanted commit - wantedCommit = g.GetCommitID(repo) + + hash = *h + } else { + hash = plumbing.NewHash(g.Ref) + } + + log.Debugf("resolved reference: %s\n", hash.String()) + + work, err := repo.Worktree() + if err != nil { + return err } - // Can't proceed now. Just doesn't exist - if wantedCommit == "" { - return ErrGitNoContinue + checkoutOpts := git.CheckoutOptions{ + Hash: hash, + Force: true, } - // Attempt reset - if err := g.resetOnto(repo, wantedCommit); err != nil { + if err = work.Checkout(&checkoutOpts); err != nil { return err } // Check out submodules - return g.submodules() + return g.submodules(work) } // IsFetched will check if we have the ref available, if not it will return diff --git a/cli/build.go b/cli/build.go index 003bdbe..2b6ed4f 100644 --- a/cli/build.go +++ b/cli/build.go @@ -162,7 +162,7 @@ func BuildRun(r *cmd.Root, s *cmd.Sub) { defer fd.Close() if err := manager.Build(); err != nil { - log.Panic("Failed to build packages") + log.Panicf("Failed to build packages: %s\n", err) } log.Infoln("Building succeeded") diff --git a/go.mod b/go.mod index 4d601c9..37a1d20 100644 --- a/go.mod +++ b/go.mod @@ -10,24 +10,42 @@ require ( github.com/cheggaaa/pb/v3 v3.1.4 github.com/coreos/go-systemd/v22 v22.5.0 github.com/getsolus/libosdev v0.0.0-20181023041421-9ab0f4b463fd - github.com/libgit2/git2go/v34 v34.0.0 + github.com/go-git/go-git/v5 v5.9.0 gopkg.in/ini.v1 v1.67.0 gopkg.in/yaml.v3 v3.0.1 ) require ( + dario.cat/mergo v1.0.0 // indirect github.com/DataDrake/flair v0.5.1 // indirect + github.com/Microsoft/go-winio v0.6.1 // indirect + github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 // indirect github.com/VividCortex/ewma v1.2.0 // indirect + github.com/acomagu/bufpipe v1.0.4 // indirect + github.com/cloudflare/circl v1.3.3 // indirect + github.com/cyphar/filepath-securejoin v0.2.4 // indirect + github.com/emirpasic/gods v1.18.1 // indirect github.com/fatih/color v1.15.0 // indirect + github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect + github.com/go-git/go-billy/v5 v5.5.0 // indirect github.com/godbus/dbus/v5 v5.1.0 // indirect - github.com/kr/pretty v0.1.0 // indirect + github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect + github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect + github.com/kevinburke/ssh_config v1.2.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.19 // indirect github.com/mattn/go-runewidth v0.0.15 // indirect + github.com/pjbgf/sha1cd v0.3.0 // indirect github.com/rivo/uniseg v0.4.4 // indirect + github.com/sergi/go-diff v1.1.0 // indirect + github.com/skeema/knownhosts v1.2.0 // indirect github.com/solus-project/libosdev v0.0.0-20171113084438-39032fc50772 // indirect github.com/stretchr/testify v1.8.4 // indirect - golang.org/x/crypto v0.12.0 // indirect - golang.org/x/sys v0.11.0 // indirect - gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect + github.com/xanzy/ssh-agent v0.3.3 // indirect + golang.org/x/crypto v0.13.0 // indirect + golang.org/x/mod v0.12.0 // indirect + golang.org/x/net v0.15.0 // indirect + golang.org/x/sys v0.12.0 // indirect + golang.org/x/tools v0.13.0 // indirect + gopkg.in/warnings.v0 v0.1.2 // indirect ) diff --git a/go.sum b/go.sum index 5d5196f..082ad98 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,5 @@ +dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= +dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/DataDrake/cli-ng/v2 v2.0.2 h1:7+25l25VmlERCE95glW6QKBUF13vxqAM2jasFiN02xQ= @@ -6,32 +8,71 @@ github.com/DataDrake/flair v0.5.1 h1:JHWOoBRiQGWg+k2bV2Mje2YmDtRjhMj51yDxQkzidWI github.com/DataDrake/flair v0.5.1/go.mod h1:3KgdmkL8eJDbg/HdMwlHkeYH/mpSy/hsQvxYQFp9A/Y= github.com/DataDrake/waterlog v1.2.0 h1:T3Hs0D6YOQfz6GtViw+fYSIGpGimU41FubcxQQzaeHM= github.com/DataDrake/waterlog v1.2.0/go.mod h1:xSKEWChL8698jwSJSyjKPIpFpj/K5n+Eif2ztYXDjJI= +github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= +github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= +github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= +github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 h1:kkhsdkhsCvIsutKu5zLMgWtgh9YxGCNAw8Ad8hjwfYg= +github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow= github.com/VividCortex/ewma v1.2.0/go.mod h1:nz4BbCtbLyFDeC9SUHbtcT5644juEuWfUAUnGx7j5l4= +github.com/acomagu/bufpipe v1.0.4 h1:e3H4WUzM3npvo5uv95QuJM3cQspFNtFBzvJ2oNjKIDQ= +github.com/acomagu/bufpipe v1.0.4/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4= +github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= +github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= +github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= github.com/cavaliergopher/grab/v3 v3.0.1 h1:4z7TkBfmPjmLAAmkkAZNX/6QJ1nNFdv3SdIHXju0Fr4= github.com/cavaliergopher/grab/v3 v3.0.1/go.mod h1:1U/KNnD+Ft6JJiYoYBAimKH2XrYptb8Kl3DFGmsjpq4= github.com/cheggaaa/pb/v3 v3.1.4 h1:DN8j4TVVdKu3WxVwcRKu0sG00IIU6FewoABZzXbRQeo= github.com/cheggaaa/pb/v3 v3.1.4/go.mod h1:6wVjILNBaXMs8c21qRiaUM8BR82erfgau1DQ4iUXmSA= +github.com/cloudflare/circl v1.3.3 h1:fE/Qz0QdIGqeWfnwq0RE0R7MI51s0M2E4Ga9kq5AEMs= +github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg= +github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a h1:mATvB/9r/3gvcejNsXKSkQ6lcIaNec2nyfOdlTBR2lU= +github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM= +github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= +github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= github.com/getsolus/libosdev v0.0.0-20181023041421-9ab0f4b463fd h1:QZoSqUIKIFeqhImxNk1cdY7M4n8JVZxTzuhP+Y0DaK8= github.com/getsolus/libosdev v0.0.0-20181023041421-9ab0f4b463fd/go.mod h1:8P4U+IYO8T6nRPLlC6qv1wMFcc0vK0vMVDCuyiFTTLg= +github.com/gliderlabs/ssh v0.3.5 h1:OcaySEmAQJgyYcArR+gGGTHCyE7nvhEMTlYY+Dp8CpY= +github.com/gliderlabs/ssh v0.3.5/go.mod h1:8XB4KraRrX39qHhT6yxPsHedjA08I/uBVwj4xC+/+z4= +github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= +github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= +github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU= +github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow= +github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20230305113008-0c11038e723f h1:Pz0DHeFij3XFhoBRGUDPzSJ+w2UcK5/0JvF8DRI58r8= +github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20230305113008-0c11038e723f/go.mod h1:8LHG1a3SRW71ettAD/jW13h8c6AqjVSeL11RAdgaqpo= +github.com/go-git/go-git/v5 v5.9.0 h1:cD9SFA7sHVRdJ7AYck1ZaAa/yeuBvGPxwXDL8cxrObY= +github.com/go-git/go-git/v5 v5.9.0/go.mod h1:RKIqga24sWdMGZF+1Ekv9kylsDz6LzdTSI2s/OsZWE0= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= -github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= -github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= +github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= +github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/libgit2/git2go/v34 v34.0.0 h1:UKoUaKLmiCRbOCD3PtUi2hD6hESSXzME/9OUZrGcgu8= -github.com/libgit2/git2go/v34 v34.0.0/go.mod h1:blVco2jDAw6YTXkErMMqzHLcAjKkwF0aWIRHBqiJkZ0= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/matryer/is v1.2.0 h1:92UTHpy8CDwaJ08GqLDzhhuixiBUUD1p3AU6PHddz4A= +github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA= 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= @@ -39,35 +80,107 @@ github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APP github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= +github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= +github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4= +github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= +github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= +github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= +github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= +github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/skeema/knownhosts v1.2.0 h1:h9r9cf0+u7wSE+M183ZtMGgOJKiL96brpaz5ekfJCpM= +github.com/skeema/knownhosts v1.2.0/go.mod h1:g4fPeYpque7P0xefxtGzV81ihjC8sX2IqpAoNkjxbMo= github.com/solus-project/libosdev v0.0.0-20171113084438-39032fc50772 h1:bZ38/PcKakYIXvy0sXj1i4STyoNVNbRmH/lwcqKRPys= github.com/solus-project/libosdev v0.0.0-20171113084438-39032fc50772/go.mod h1:DExgz4r2r2WHNHjoDZ35x83ARKNi87Uu3UQurqyPqg0= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= +github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk= -golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= +golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= +golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck= +golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +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-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +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= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8= +golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= +golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= -golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= -golang.org/x/term v0.11.0 h1:F9tnn/DA/Im8nCwm+fX+1/eBwi4qFjRT++MhtVC4ZX0= -golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= +golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +golang.org/x/term v0.12.0 h1:/ZfYdc3zq+q02Rv9vGqTeSItdzZTSNDmfTi0mBAuidU= +golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ= +golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= +gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=