mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-06-11 09:02:53 +00:00
139 lines
3.6 KiB
Go
139 lines
3.6 KiB
Go
// Copyright 2022 The Kubernetes Authors.
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package repo
|
|
|
|
import (
|
|
"fmt"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"sigs.k8s.io/kustomize/cmd/gorepomod/internal/git"
|
|
"sigs.k8s.io/kustomize/cmd/gorepomod/internal/misc"
|
|
"sigs.k8s.io/kustomize/cmd/gorepomod/internal/utils"
|
|
)
|
|
|
|
const (
|
|
dotGitFileName = ".git"
|
|
srcHint = "/src/"
|
|
goModFile = "go.mod"
|
|
)
|
|
|
|
// DotGitData holds basic information about a local .git file
|
|
type DotGitData struct {
|
|
// srcPath is the absolute path to the local Go src directory.
|
|
// This used to be $GOPATH/src.
|
|
// It's the directory containing git repository clones.
|
|
srcPath string
|
|
// The path below srcPath to a particular repository
|
|
// directory, a directory containing a .git directory.
|
|
// Typically {repoOrg}/{repoUserName}, e.g. sigs.k8s.io/cli-utils
|
|
repoPath string
|
|
}
|
|
|
|
func (dg *DotGitData) SrcPath() string {
|
|
return dg.srcPath
|
|
}
|
|
|
|
func (dg *DotGitData) RepoPath() string {
|
|
return dg.repoPath
|
|
}
|
|
|
|
func (dg *DotGitData) AbsPath() string {
|
|
return filepath.Join(dg.srcPath, dg.repoPath)
|
|
}
|
|
|
|
// NewDotGitDataFromPath wants the incoming path to hold dotGit
|
|
// E.g.
|
|
//
|
|
// ~/gopath/src/sigs.k8s.io/kustomize
|
|
// ~/gopath/src/github.com/monopole/gorepomod
|
|
func NewDotGitDataFromPath(path string) (*DotGitData, error) {
|
|
if !utils.DirExists(filepath.Join(path, dotGitFileName)) {
|
|
return nil, fmt.Errorf(
|
|
"%q doesn't have a %q file", path, dotGitFileName)
|
|
}
|
|
// This is an attempt to figure out where the user has cloned
|
|
// their repos. In the old days, it was an import path under
|
|
// $GOPATH/src. If we cannot guess it, we may need to ask for it,
|
|
// or maybe proceed without knowing it.
|
|
index := strings.Index(path, srcHint)
|
|
if index < 0 {
|
|
return nil, fmt.Errorf(
|
|
"path %q doesn't contain %q", path, srcHint)
|
|
}
|
|
return &DotGitData{
|
|
srcPath: path[:index+len(srcHint)-1],
|
|
repoPath: path[index+len(srcHint):],
|
|
}, nil
|
|
}
|
|
|
|
// It's a factory factory.
|
|
func (dg *DotGitData) NewRepoFactory(
|
|
exclusions []string) (*ManagerFactory, error) {
|
|
modules, err := loadProtoModules(dg.AbsPath(), exclusions)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
err = dg.checkModules(modules)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
runner := git.NewQuiet(dg.AbsPath(), true)
|
|
remoteName, err := runner.DetermineRemoteToUse()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Some tags might exist for modules that
|
|
// have been renamed or deleted; ignore those.
|
|
// There might be newer tags locally than remote,
|
|
// so report both.
|
|
localTags, err := runner.LoadLocalTags()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
remoteTags, err := runner.LoadRemoteTags(remoteName)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &ManagerFactory{
|
|
dg: dg,
|
|
modules: modules,
|
|
remoteName: remoteName,
|
|
versionMapLocal: localTags,
|
|
versionMapRemote: remoteTags,
|
|
}, nil
|
|
}
|
|
|
|
func (dg *DotGitData) checkModules(modules []*protoModule) error {
|
|
for _, pm := range modules {
|
|
|
|
file := filepath.Join(pm.PathToGoMod(), goModFile)
|
|
|
|
// Do the paths make sense?
|
|
if !strings.HasPrefix(pm.FullPath(), dg.RepoPath()) {
|
|
return fmt.Errorf(
|
|
"module %q doesn't start with the repository name %q",
|
|
pm.FullPath(), dg.RepoPath())
|
|
}
|
|
|
|
shortName := pm.ShortName(dg.RepoPath())
|
|
if shortName == misc.ModuleAtTop {
|
|
if pm.PathToGoMod() != dg.AbsPath() {
|
|
return fmt.Errorf("in %q, problem with top module", file)
|
|
}
|
|
} else {
|
|
// Do the relative path and short name make sense?
|
|
if !strings.HasSuffix(pm.PathToGoMod(), string(shortName)) {
|
|
return fmt.Errorf(
|
|
"in %q, the module name %q doesn't match the file's pathToGoMod %q",
|
|
file, shortName, pm.PathToGoMod())
|
|
}
|
|
}
|
|
}
|
|
return nil
|
|
}
|