Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: fix missing mod and deps not found #523

Merged
merged 5 commits into from
Nov 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
153 changes: 72 additions & 81 deletions pkg/client/add.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,54 +13,46 @@ import (
type AddOptions struct {
// Source is the source of the package to be pulled.
// Including git, oci, local.
Sources []*downloader.Source
KclPkg *pkg.KclPkg
Source *downloader.Source
KclPkg *pkg.KclPkg
}

type AddOption func(*AddOptions) error

func WithAddSource(source *downloader.Source) AddOption {
func WithAddModSpec(modSpec *downloader.ModSpec) AddOption {
return func(opts *AddOptions) error {
if opts.Sources == nil {
opts.Sources = make([]*downloader.Source, 0)
if modSpec == nil {
return fmt.Errorf("modSpec cannot be nil")
}
opts.Sources = append(opts.Sources, source)
if opts.Source == nil {
opts.Source = &downloader.Source{
ModSpec: modSpec,
}
} else {
opts.Source.ModSpec = modSpec
}

return nil
}
}

func WithAddSources(sources []*downloader.Source) AddOption {
return func(ro *AddOptions) error {
ro.Sources = sources
func WithAddSource(source *downloader.Source) AddOption {
return func(opts *AddOptions) error {
if source == nil {
return fmt.Errorf("source cannot be nil")
}
opts.Source = source
return nil
}
}

func WithAddSourceUrl(sourceUrl string) AddOption {
return func(opts *AddOptions) error {
if opts.Sources == nil {
opts.Sources = make([]*downloader.Source, 0)
}
source, err := downloader.NewSourceFromStr(sourceUrl)
if err != nil {
return err
}
opts.Sources = append(opts.Sources, source)
return nil
}
}

func WithAddSourceUrls(sourceUrls []string) AddOption {
return func(opts *AddOptions) error {
var sources []*downloader.Source
for _, sourceUrl := range sourceUrls {
source, err := downloader.NewSourceFromStr(sourceUrl)
if err != nil {
return err
}
sources = append(sources, source)
}
opts.Sources = sources
opts.Source = source
return nil
}
}
Expand Down Expand Up @@ -88,6 +80,7 @@ func (c *KpmClient) Add(options ...AddOption) error {
}
}
addedPkg := opts.KclPkg
depSource := opts.Source

visitorSelector := func(source *downloader.Source) (visitor.Visitor, error) {
pkgVisitor := &visitor.PkgVisitor{
Expand All @@ -113,73 +106,71 @@ func (c *KpmClient) Add(options ...AddOption) error {
}
}

for _, depSource := range opts.Sources {
// Set the default OCI registry and repo if the source is nil and the package spec is not nil.
if depSource.IsNilSource() && !depSource.ModSpec.IsNil() {
depSource.Oci = &downloader.Oci{
Reg: c.GetSettings().Conf.DefaultOciRegistry,
Repo: utils.JoinPath(c.GetSettings().Conf.DefaultOciRepo, depSource.ModSpec.Name),
Tag: depSource.ModSpec.Version,
}
// Set the default OCI registry and repo if the source is nil and the package spec is not nil.
if depSource.IsNilSource() && !depSource.ModSpec.IsNil() {
depSource.Oci = &downloader.Oci{
Reg: c.GetSettings().Conf.DefaultOciRegistry,
Repo: utils.JoinPath(c.GetSettings().Conf.DefaultOciRepo, depSource.ModSpec.Name),
Tag: depSource.ModSpec.Version,
}
}

var fullSouce *downloader.Source
// Transform the relative path to the full path.
if depSource.IsLocalPath() && !filepath.IsAbs(depSource.Path) {
fullSouce = &downloader.Source{
ModSpec: depSource.ModSpec,
Local: &downloader.Local{
Path: filepath.Join(addedPkg.HomePath, depSource.Path),
},
}
} else {
fullSouce = depSource
var fullSouce *downloader.Source
// Transform the relative path to the full path.
if depSource.IsLocalPath() && !filepath.IsAbs(depSource.Path) {
fullSouce = &downloader.Source{
ModSpec: depSource.ModSpec,
Local: &downloader.Local{
Path: filepath.Join(addedPkg.HomePath, depSource.Path),
},
}
} else {
fullSouce = depSource
}

visitor, err := visitorSelector(fullSouce)
if err != nil {
return err
}
visitor, err := visitorSelector(fullSouce)
if err != nil {
return err
}

// Visit the dependency source
// If the dependency is remote, the visitor will download it to the local.
// If the dependency is already in local cache, the visitor will not download it again.
err = visitor.Visit(fullSouce, func(depPkg *pkg.KclPkg) error {
var modSpec *downloader.ModSpec
if depSource.ModSpec.IsNil() {
modSpec = &downloader.ModSpec{
Name: depPkg.ModFile.Pkg.Name,
Version: depPkg.ModFile.Pkg.Version,
}
depSource.ModSpec = modSpec
// Visit the dependency source
// If the dependency is remote, the visitor will download it to the local.
// If the dependency is already in local cache, the visitor will not download it again.
err = visitor.Visit(fullSouce, func(depPkg *pkg.KclPkg) error {
var modSpec *downloader.ModSpec
if depSource.ModSpec.IsNil() {
modSpec = &downloader.ModSpec{
Name: depPkg.ModFile.Pkg.Name,
Version: depPkg.ModFile.Pkg.Version,
}
depSource.ModSpec = modSpec
}

dep := pkg.Dependency{
Name: depPkg.ModFile.Pkg.Name,
FullName: depPkg.GetPkgFullName(),
Version: depPkg.ModFile.Pkg.Version,
LocalFullPath: depPkg.HomePath,
Source: *depSource,
}
dep := pkg.Dependency{
Name: depPkg.ModFile.Pkg.Name,
FullName: depPkg.GetPkgFullName(),
Version: depPkg.ModFile.Pkg.Version,
LocalFullPath: depPkg.HomePath,
Source: *depSource,
}

// Add the dependency to the kcl.mod file.
if modExistDep, ok := addedPkg.ModFile.Dependencies.Deps.Get(dep.Name); ok {
if less, err := modExistDep.VersionLessThan(&dep); less && err == nil {
addedPkg.ModFile.Dependencies.Deps.Set(dep.Name, dep)
}
} else {
// Add the dependency to the kcl.mod file.
if modExistDep, ok := addedPkg.ModFile.Dependencies.Deps.Get(dep.Name); ok {
if less, err := modExistDep.VersionLessThan(&dep); less && err == nil {
addedPkg.ModFile.Dependencies.Deps.Set(dep.Name, dep)
}

return nil
})
if err != nil {
return err
} else {
addedPkg.ModFile.Dependencies.Deps.Set(dep.Name, dep)
}

return nil
})
if err != nil {
return err
}

// Iterate the dependencies and update the kcl.mod and kcl.mod.lock respectively.
_, err := c.Update(
_, err = c.Update(
WithUpdatedKclPkg(addedPkg),
)

Expand Down
18 changes: 18 additions & 0 deletions pkg/client/pull.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,23 @@ type PullOptions struct {

type PullOption func(*PullOptions) error

func WithPullModSpec(modSpec *downloader.ModSpec) PullOption {
return func(opts *PullOptions) error {
if modSpec == nil {
return errors.New("modSpec cannot be nil")
}
if opts.Source == nil {
opts.Source = &downloader.Source{
ModSpec: modSpec,
}
} else {
opts.Source.ModSpec = modSpec
}

return nil
}
}

func WithPullSourceUrl(sourceUrl string) PullOption {
return func(opts *PullOptions) error {
source, err := downloader.NewSourceFromStr(sourceUrl)
Expand Down Expand Up @@ -76,6 +93,7 @@ func (c *KpmClient) Pull(options ...PullOption) (*pkg.KclPkg, error) {
if err != nil {
return nil, err
}

reporter.ReportMsgTo(
fmt.Sprintf("start to pull %s", sourceStr),
c.GetLogWriter(),
Expand Down
38 changes: 38 additions & 0 deletions pkg/client/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,29 @@ type RunOptions struct {

type RunOption func(*RunOptions) error

func WithRunModSpec(modSpec *downloader.ModSpec) RunOption {
return func(ro *RunOptions) error {
if modSpec == nil {
return errors.New("modSpec cannot be nil")
}
if ro.Sources == nil {
ro.Sources = make([]*downloader.Source, 0)
}
if len(ro.Sources) > 1 {
return errors.New("only allows one package to be compiled at a time")
}
if len(ro.Sources) == 0 {
ro.Sources = append(ro.Sources, &downloader.Source{
ModSpec: modSpec,
})
} else {
ro.Sources[0].ModSpec = modSpec
}

return nil
}
}

// Use the another RunOptions to override the current RunOptions.
func WithRunOptions(runOpts *RunOptions) RunOption {
return func(ro *RunOptions) error {
Expand Down Expand Up @@ -401,6 +424,16 @@ func (o *RunOptions) applyCompileOptions(source downloader.Source, kclPkg *pkg.K
sourcePath = filepath.Join(workDir, sourcePath)
}

// When determining whether the path in 'Source' is the same as homepath of 'KclPkg',
// use the subdirectories specified by 'ModSpec'
var err error
if pkgSource.ModSpec != nil && pkgSource.ModSpec.Name != "" {
sourcePath, err = utils.FindPackage(sourcePath, pkgSource.ModSpec.Name)
if err != nil {
return false
}
}

pkgHome := kclPkg.HomePath

if !filepath.IsAbs(pkgHome) && !utils.IsModRelativePath(sourcePath) {
Expand Down Expand Up @@ -479,6 +512,7 @@ func (o *RunOptions) getPkgSource() (*downloader.Source, error) {
workDir := o.WorkDir

var pkgSource *downloader.Source
var modSpec *downloader.ModSpec
if len(o.Sources) == 0 {
workDir, err := filepath.Abs(workDir)
if err != nil {
Expand All @@ -497,6 +531,9 @@ func (o *RunOptions) getPkgSource() (*downloader.Source, error) {
for _, source := range o.Sources {
if pkgSource == nil {
pkgSource = source
// If the root source is found,
// update the modSpec and rootPath.
modSpec = source.ModSpec
rootPath, err = source.FindRootPath()
if err != nil {
return nil, err
Expand Down Expand Up @@ -548,6 +585,7 @@ func (o *RunOptions) getPkgSource() (*downloader.Source, error) {
if err != nil {
return nil, err
}
pkgSource.ModSpec = modSpec
}
}

Expand Down
8 changes: 6 additions & 2 deletions pkg/downloader/source.go
Original file line number Diff line number Diff line change
Expand Up @@ -443,7 +443,10 @@ func (source *Source) FromString(sourceStr string) error {
} else if sourceUrl.Scheme == constants.DefaultOciScheme {
source.ModSpec = &ModSpec{}
source.ModSpec.FromString(sourceUrl.String())
} else {
// There is a case where there is only 'ModSpec'
// On winodws, the path url will be parsed as 'Opaque'
// On linux, the path url will be parsed as 'Path'
} else if sourceUrl.Path != "" || sourceUrl.Opaque != "" {
source.Local = &Local{}
source.Local.FromString(sourceUrl.String())
}
Expand Down Expand Up @@ -556,7 +559,8 @@ func (git *Git) GetValidGitReference() (string, error) {
nonEmptyRef = git.Branch
}

if nonEmptyFields != 1 {
// The latest commit id for git repo is supported.
if nonEmptyFields > 1 {
return "", errors.New("only one of branch, tag or commit is allowed")
}

Expand Down
22 changes: 21 additions & 1 deletion pkg/visitor/visitor.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func (pv *PkgVisitor) Visit(s *downloader.Source, v visitFunc) error {
return err
}

if !s.ModSpec.IsNil() {
if s.ModSpec != nil && s.ModSpec.Name != "" {
modPath, err = utils.FindPackage(modPath, s.ModSpec.Name)
if err != nil {
return err
Expand Down Expand Up @@ -120,6 +120,15 @@ func (rv *RemoteVisitor) Visit(s *downloader.Source, v visitFunc) error {
return fmt.Errorf("source is not remote")
}

// For some sources with only the spec, the default registry and repo will be used.
if s.SpecOnly() {
s.Oci = &downloader.Oci{
Reg: rv.Settings.DefaultOciRegistry(),
Repo: utils.JoinPath(rv.Settings.DefaultOciRepo(), s.ModSpec.Name),
Tag: s.ModSpec.Version,
}
}

var cacheFullPath string
var modFullPath string

Expand All @@ -134,6 +143,17 @@ func (rv *RemoteVisitor) Visit(s *downloader.Source, v visitFunc) error {
}
}

// If the cache is not enabled,
// create a temporary directory to get the latest commit of git repo
if !rv.EnableCache {
cacheFullPath, err = os.MkdirTemp("", "")
if err != nil {
return err
}

defer os.RemoveAll(cacheFullPath)
}

// 1. Load the credential file.
credCli, err := downloader.LoadCredentialFile(rv.Settings.CredentialsFile)
if err != nil {
Expand Down