github.com/octohelm/cuekit@v0.0.0-20240424021256-e7df8d743066/internal/gomod/revinfo.go (about)

     1  package gomod
     2  
     3  import (
     4  	"context"
     5  	"path"
     6  	"strings"
     7  	_ "unsafe"
     8  
     9  	"github.com/pkg/errors"
    10  	"golang.org/x/mod/modfile"
    11  	"golang.org/x/mod/module"
    12  
    13  	"github.com/octohelm/cuekit/pkg/version"
    14  
    15  	"github.com/octohelm/cuekit/internal/gomod/internal/cmd/go/internals/modfetch"
    16  	"github.com/octohelm/cuekit/internal/gomod/internal/cmd/go/internals/modfetch/codehost"
    17  	"github.com/octohelm/cuekit/internal/gomod/internal/cmd/go/internals/vcs"
    18  )
    19  
    20  //go:linkname newCodeRepo github.com/octohelm/cuekit/internal/gomod/internal/cmd/go/internals/modfetch.newCodeRepo
    21  func newCodeRepo(code codehost.Repo, codeRoot, path string) (modfetch.Repo, error)
    22  
    23  //go:linkname lookupCodeRepo github.com/octohelm/cuekit/internal/gomod/internal/cmd/go/internals/modfetch.lookupCodeRepo
    24  func lookupCodeRepo(ctx context.Context, rr *vcs.RepoRoot) (codehost.Repo, error)
    25  
    26  func finalLookupCodeRepo(ctx context.Context, rr *vcs.RepoRoot, localOk bool) (codehost.Repo, error) {
    27  	if strings.ToLower(rr.VCS.Name) == "git" && localOk {
    28  		return codehost.LocalGitRepo(ctx, path.Join(rr.Root, ".git"))
    29  	}
    30  	return lookupCodeRepo(ctx, rr)
    31  }
    32  
    33  type RevInfo = modfetch.RevInfo
    34  
    35  func RevInfoFromDir(ctx context.Context, dir string) (*RevInfo, error) {
    36  	rootDir, c, err := vcs.FromDir(dir, "", true)
    37  	if err != nil {
    38  		return nil, err
    39  	}
    40  
    41  	repo, err := c.RemoteRepo(c, rootDir)
    42  	if err != nil {
    43  		return nil, errors.Wrap(err, "resolve remote repo failed")
    44  	}
    45  
    46  	head, err := c.Status(c, rootDir)
    47  	if err != nil {
    48  		return nil, errors.Wrapf(err, "stat faield")
    49  	}
    50  
    51  	rr := &vcs.RepoRoot{}
    52  	rr.VCS = c
    53  	rr.Root = rootDir
    54  	rr.Repo = repo
    55  
    56  	code, err := finalLookupCodeRepo(ctx, rr, true)
    57  	if err != nil {
    58  		return nil, err
    59  	}
    60  
    61  	importPath := rr.Root
    62  
    63  	data, err := code.ReadFile(ctx, head.Revision, "go.mod", -1)
    64  	if err == nil {
    65  		f, err := modfile.ParseLax("go.mod", data, nil)
    66  		if err != nil {
    67  			return nil, err
    68  		}
    69  
    70  		// <import_path>/v2
    71  		_, pathMajor, ok := module.SplitPathVersion(f.Module.Mod.Path)
    72  		if ok && pathMajor != "" {
    73  			importPath += pathMajor
    74  		}
    75  	}
    76  
    77  	r, err := newCodeRepo(code, rr.Root, importPath)
    78  	if err != nil {
    79  		return nil, err
    80  	}
    81  
    82  	info, err := r.Stat(ctx, head.Revision)
    83  	if err != nil {
    84  		return nil, errors.Wrapf(err, "stat faield")
    85  	}
    86  
    87  	info.Version = version.Convert(info.Version, info.Time, info.Short, head.Uncommitted)
    88  
    89  	return info, nil
    90  }