diff --git a/lib/create/create.go b/lib/create/create.go index aeb1b38a8..6332b0710 100644 --- a/lib/create/create.go +++ b/lib/create/create.go @@ -305,6 +305,10 @@ func setupTmpdir(url, ver string) (tmpdir, subdir string, err error) { func runCreator(R *gencmd.Runtime, extra, inputs []string) (err error) { + if R.Flags.Verbosity > 0 { + fmt.Println("running creator with:", extra, inputs) + } + if len(R.Generators) == 0 { return fmt.Errorf("no generators found, please make sure there is a creator at the root of the repository") } diff --git a/lib/mod/get.go b/lib/mod/get.go index 16ebc67fb..069de5035 100644 --- a/lib/mod/get.go +++ b/lib/mod/get.go @@ -94,10 +94,11 @@ func updateOne(cm *CueMod, path, ver string, rflags flags.RootPflagpole, gflags } // check for already required at a version equal or greater (no downgrades with get) + // HMMM, let's remove this restriction, GO supports downgrading, let's inform the user currVer, ok := cm.Require[path] if ok { - if semver.Compare(currVer, ver) >= 0 { - return fmt.Errorf("%s@%s is already required", path, currVer) + if semver.Compare(currVer, ver) > 0 { + fmt.Printf("Downgrading: %s from %s to %s\n", path, currVer, ver) } } diff --git a/lib/mod/testdata/get__update_all_deps.txt b/lib/mod/testdata/get__update_all_deps.txt index 222af2bdc..e9884733c 100644 --- a/lib/mod/testdata/get__update_all_deps.txt +++ b/lib/mod/testdata/get__update_all_deps.txt @@ -27,6 +27,6 @@ require: { indirect: { "github.com/hofstadter-io/cuelm": "v0.2.0" "github.com/hofstadter-io/ghacue": "v0.2.0" - "github.com/hofstadter-io/hofmod-cli": "v0.8.6" + "github.com/hofstadter-io/hofmod-cli": "v0.8.8" "github.com/hofstadter-io/supacode": "v0.0.7" } diff --git a/lib/mod/tidy.go b/lib/mod/tidy.go index af13cf455..3a16ef1a6 100644 --- a/lib/mod/tidy.go +++ b/lib/mod/tidy.go @@ -48,7 +48,10 @@ func Tidy(rflags flags.RootPflagpole) (error) { func (cm *CueMod) UpgradePseudoVersions() (err error) { for path, dep := range cm.Replace { - ver, _ := cache.UpgradePseudoVersion(dep.Path, dep.Version) + ver, err := cache.UpgradePseudoVersion(dep.Path, dep.Version) + if err != nil { + return err + } dep.Version = ver cm.Replace[path] = dep } @@ -57,7 +60,10 @@ func (cm *CueMod) UpgradePseudoVersions() (err error) { if _, ok := cm.Replace[path]; ok { continue } - ver, _ = cache.UpgradePseudoVersion(path, ver) + ver, err = cache.UpgradePseudoVersion(path, ver) + if err != nil { + return err + } cm.Require[path] = ver } diff --git a/lib/repos/cache/info.go b/lib/repos/cache/info.go index ee1ec6ca1..33da5cfd9 100644 --- a/lib/repos/cache/info.go +++ b/lib/repos/cache/info.go @@ -153,6 +153,7 @@ func GetBranchLatestHash(path, branch string) (string, error) { if err != nil { return branch, err } + // open repo R, err := OpenRepoSource(path) if err != nil { @@ -170,15 +171,25 @@ func GetBranchLatestHash(path, branch string) (string, error) { Branch: plumbing.NewRemoteReferenceName("origin", branch), Force: true, }) - if err == nil { - h, err := R.Head() - if err != nil { - return branch, err + if err != nil { + // if error checking out branch name, try to check out a hash + herr := wt.Checkout(&gogit.CheckoutOptions{ + Hash: plumbing.NewHash(branch), + Force: true, + }) + // if no error, we can return "branch" which is a commit + if herr == nil { + return branch, nil } - return h.Hash().String(), nil + // else, we can return the "ref not found" error from the first checkout + return branch, err } - return branch, nil + h, err := R.Head() + if err != nil { + return branch, err + } + return h.Hash().String(), nil } func UpgradePseudoVersion(path, ver string) (s string, err error) { @@ -198,10 +209,10 @@ func UpgradePseudoVersion(path, ver string) (s string, err error) { } } - // branch? need to find commit + // branch? need to find commit, what if branch does not exist nver, err := GetHashForNamedRef(path, ver) if err != nil { - return ver, err + return ver, fmt.Errorf("while upgrading pseudo version for %s@%s: %w", path, ver, err) } if nver != "" { ver = nver diff --git a/lib/repos/cache/load.go b/lib/repos/cache/load.go index cdf88d260..3fd7c1bea 100644 --- a/lib/repos/cache/load.go +++ b/lib/repos/cache/load.go @@ -5,7 +5,7 @@ import ( "os" "path/filepath" "sync" - "strings" + // "strings" "github.com/go-git/go-billy/v5" "github.com/go-git/go-billy/v5/osfs" @@ -45,10 +45,11 @@ func init() { if err != nil { return } + // workaround for running in TestScript tool - if strings.HasPrefix(d, "/no-home") { - d = strings.TrimPrefix(d, "/") - } + //if strings.HasPrefix(d, "/no-home") { + // d = strings.TrimPrefix(d, "/") + //} // save to hof dir for cache across projects cacheBaseDir = filepath.Join(d, "hof") @@ -187,7 +188,6 @@ func CacheModule(url, ver string) (billy.Filesystem, error) { cacheLock.Lock() defer cacheLock.Unlock() - // fmt.Println("FETCH:", url, ver) // we are smarter here and check to see if the tag already exists // this will both clone new & sync existing repos as needed // when ver != "", it will only fetch if the tag is not found diff --git a/lib/repos/cache/write.go b/lib/repos/cache/write.go index 7ade0253c..ae5533107 100644 --- a/lib/repos/cache/write.go +++ b/lib/repos/cache/write.go @@ -10,6 +10,7 @@ import ( "github.com/go-git/go-billy/v5/osfs" gogit "github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5/plumbing" + "golang.org/x/mod/semver" "github.com/hofstadter-io/hof/lib/repos/utils" "github.com/hofstadter-io/hof/lib/yagu" @@ -70,6 +71,9 @@ func CopyRepoTag(path, ver string) (string, error) { if debug { fmt.Println("cache.CopyRepoTag:", path, ver) } + + // HMMM, upgrade pseudoversion here? + remote, owner, repo := utils.ParseModURL(path) dir := SourceOutdir(remote, owner, repo) @@ -85,47 +89,58 @@ func CopyRepoTag(path, ver string) (string, error) { return ver, fmt.Errorf("(crt) worktree error: %w for %s@%s", err, path, ver) } + // we aren't really using this, but want to think through the logic and make it available + verType := "branch" + if semver.IsValid(ver) { + verType = "tag" + } + lver := ver + // trim the prefix from module versions that are actually commits + // then using the commit hash for checkout parts := strings.Split(lver, "-") if strings.HasPrefix(lver, "v0.0.0-") { lver = strings.Join(parts[2:], "-") + verType = "commit" } - // fmt.Println("PVL", path, ver, lver) + if debug { + fmt.Println("PVL", path, ver, lver, verType) + } - // checkout tag - err = wt.Checkout(&gogit.CheckoutOptions{ - Branch: plumbing.NewTagReferenceName(lver), - Force: true, - }) - if err != nil { - // fmt.Printf("(crt) -- checkout error: %v for %s@%s\n", err, path, ver) + // what we are doing here is trying to checkout the right thing + // before doing the copy + // choices are: [tag, branch, commit] + // maybe any commit inputs should already have been upgraded? + // going with this for now, we should catch an error in tests + // and ensure there is a test, then remove these last few comment lines + + // checkout ref + switch verType { + case "tag": + err = wt.Checkout(&gogit.CheckoutOptions{ + Branch: plumbing.NewTagReferenceName(lver), + Force: true, + }) + + case "commit": + err = wt.Checkout(&gogit.CheckoutOptions{ + Hash: plumbing.NewHash(lver), + Force: true, + }) - // err = fmt.Errorf("(crt) checkout error: %w for %s@%s", err, path, ver) - // try branch + case "branch": err = wt.Checkout(&gogit.CheckoutOptions{ Branch: plumbing.NewRemoteReferenceName("origin", lver), Force: true, }) - if err != nil { - err = wt.Checkout(&gogit.CheckoutOptions{ - Hash: plumbing.NewHash(lver), - Force: true, - }) - if err != nil { - return ver, fmt.Errorf("(crt) checkout error: unable to find version %q for module %q: %w", ver, path, err) - } - - } else { - h, err := R.Head() - lver = strings.Join(append(parts[:2], h.Hash().String()), "-") - fmt.Println("Checking out branch:", path, ver, lver, err) - ver = lver - } + } + if err != nil { + return "", err } - // copy + // Now we can copy from src to mods FS := osfs.New(dir) err = Write(remote, owner, repo, ver, FS) if err != nil { diff --git a/lib/repos/git/fetch.go b/lib/repos/git/fetch.go index e57c5f836..c12bf9754 100644 --- a/lib/repos/git/fetch.go +++ b/lib/repos/git/fetch.go @@ -45,10 +45,10 @@ func IsNetworkReachable(ctx context.Context, mod string) (bool, error) { return err == nil, nil } -func SyncSource(dir, remote, owner, repo, ver string) error { +func SyncSource(dir, remote, owner, repo string) error { url := path.Join(remote, owner, repo) if debug { - fmt.Println("git.SyncSource:", dir, remote, owner, repo, ver, url) + fmt.Println("git.SyncSource:", dir, remote, owner, repo, url) } _, err := os.Lstat(dir) // does not exist diff --git a/lib/repos/remote/remote.go b/lib/repos/remote/remote.go index a5badeeff..0df7b3fd9 100644 --- a/lib/repos/remote/remote.go +++ b/lib/repos/remote/remote.go @@ -55,9 +55,11 @@ func NewRemote(mod string, mir *Mirrors) *Remote { func (r *Remote) Pull(ctx context.Context, dir, ver string) error { switch r.kind { case KindGit: - if err := git.SyncSource(dir, r.Host, r.Owner, r.Name, ver); err != nil { + // ensure we have up-to-date code in .cache/hof/src/ + if err := git.SyncSource(dir, r.Host, r.Owner, r.Name); err != nil { return fmt.Errorf("git sync source: %w", err) } + case KindOCI: // extract hash from version if strings.HasPrefix(ver, "v0.0.0-") { diff --git a/test/create/test_01/Makefile b/test/create/test_01/Makefile index 51cf7b9db..eb682e177 100644 --- a/test/create/test_01/Makefile +++ b/test/create/test_01/Makefile @@ -1,4 +1,4 @@ test: - hof create github.com/hofstadter-io/hofmod-cli@v0.8.3 -I @input.cue -O out + hof create github.com/hofstadter-io/hofmod-cli@v0.8.8 -I @input.cue -O out cd out && make first rm -rf out diff --git a/test/create/test_01/input.cue b/test/create/test_01/input.cue index e23e84492..47ed93c24 100644 --- a/test/create/test_01/input.cue +++ b/test/create/test_01/input.cue @@ -1,4 +1,4 @@ -name: "foo" -repo: "github.com/hof/test" -about: "testing example" +name: "foo" +repo: "github.com/hof/test" +about: "testing example" releases: false