From a2fc5215d0c81eee886b5c654d0a7398e4f21846 Mon Sep 17 00:00:00 2001 From: zongz Date: Thu, 5 Sep 2024 19:51:18 +0800 Subject: [PATCH 1/3] feat: mvs algorithm for 'version' in kcl.mod is supported in the add command Signed-off-by: zongz --- pkg/client/client.go | 8 +- pkg/client/client_test.go | 14 +-- pkg/client/resolver.go | 16 +-- pkg/client/resolver_test.go | 6 +- .../test_mod_file_package/test_pkg/expect.mod | 5 +- .../test_pkg/expect.mod.lock | 18 ++- .../test_mod_file_package/test_pkg/kcl.mod | 7 ++ .../test_pkg/kcl.mod.lock | 8 ++ .../test_pkg_win/expect.mod | 5 +- .../test_pkg_win/expect.mod.lock | 18 ++- .../test_pkg_win/kcl.mod | 4 + .../update_0/dep_0/kcl.mod | 7 ++ .../update_0/dep_0/kcl.mod.lock | 6 + .../update_0/dep_0/main.k | 1 + .../update_0/dep_1/kcl.mod | 7 ++ .../update_0/dep_1/kcl.mod.lock | 6 + .../update_0/dep_1/main.k | 1 + .../update_0/dep_2/kcl.mod | 7 ++ .../update_0/dep_2/kcl.mod.lock | 5 + .../update_0/dep_2/main.k | 1 + .../test_update_with_mvs/update_0/pkg/kcl.mod | 9 ++ .../update_0/pkg/kcl.mod.expect | 9 ++ .../update_0/pkg/kcl.mod.lock | 17 +++ .../update_0/pkg/kcl.mod.lock.expect | 17 +++ .../test_update_with_mvs/update_0/pkg/main.k | 1 + .../update_1/dep_0/kcl.mod | 7 ++ .../update_1/dep_0/kcl.mod.lock | 6 + .../update_1/dep_0/main.k | 1 + .../update_1/dep_1/kcl.mod | 7 ++ .../update_1/dep_1/kcl.mod.lock | 6 + .../update_1/dep_1/main.k | 1 + .../update_1/dep_2/kcl.mod | 7 ++ .../update_1/dep_2/kcl.mod.lock | 5 + .../update_1/dep_2/main.k | 1 + .../test_update_with_mvs/update_1/pkg/kcl.mod | 10 ++ .../update_1/pkg/kcl.mod.bk | 10 ++ .../update_1/pkg/kcl.mod.expect | 10 ++ .../update_1/pkg/kcl.mod.lock | 17 +++ .../update_1/pkg/kcl.mod.lock.bk | 17 +++ .../update_1/pkg/kcl.mod.lock.expect | 17 +++ .../test_update_with_mvs/update_1/pkg/main.k | 1 + pkg/client/update.go | 108 ++++++++++++++++++ pkg/client/update_test.go | 80 +++++++++++++ pkg/client/visitor.go | 9 +- pkg/downloader/downloader.go | 12 +- pkg/package/modfile.go | 28 ++++- .../test_data/test_add_with_name_1/kcl.mod | 7 ++ .../test_add_with_name_1/kcl.mod.lock | 9 ++ .../test_data/test_add_with_name_1/main.k | 1 + .../test_kpm_add_git_commit_0/kcl.mod | 4 + .../test_kpm_add_git_commit_0/main.k | 1 + .../test_kpm_add_git_commit_1/kcl.mod | 4 + .../test_kpm_add_git_commit_1/main.k | 1 + 53 files changed, 536 insertions(+), 54 deletions(-) create mode 100644 pkg/client/test_data/test_update_with_mvs/update_0/dep_0/kcl.mod create mode 100644 pkg/client/test_data/test_update_with_mvs/update_0/dep_0/kcl.mod.lock create mode 100644 pkg/client/test_data/test_update_with_mvs/update_0/dep_0/main.k create mode 100644 pkg/client/test_data/test_update_with_mvs/update_0/dep_1/kcl.mod create mode 100644 pkg/client/test_data/test_update_with_mvs/update_0/dep_1/kcl.mod.lock create mode 100644 pkg/client/test_data/test_update_with_mvs/update_0/dep_1/main.k create mode 100644 pkg/client/test_data/test_update_with_mvs/update_0/dep_2/kcl.mod create mode 100644 pkg/client/test_data/test_update_with_mvs/update_0/dep_2/kcl.mod.lock create mode 100644 pkg/client/test_data/test_update_with_mvs/update_0/dep_2/main.k create mode 100644 pkg/client/test_data/test_update_with_mvs/update_0/pkg/kcl.mod create mode 100644 pkg/client/test_data/test_update_with_mvs/update_0/pkg/kcl.mod.expect create mode 100644 pkg/client/test_data/test_update_with_mvs/update_0/pkg/kcl.mod.lock create mode 100644 pkg/client/test_data/test_update_with_mvs/update_0/pkg/kcl.mod.lock.expect create mode 100644 pkg/client/test_data/test_update_with_mvs/update_0/pkg/main.k create mode 100644 pkg/client/test_data/test_update_with_mvs/update_1/dep_0/kcl.mod create mode 100644 pkg/client/test_data/test_update_with_mvs/update_1/dep_0/kcl.mod.lock create mode 100644 pkg/client/test_data/test_update_with_mvs/update_1/dep_0/main.k create mode 100644 pkg/client/test_data/test_update_with_mvs/update_1/dep_1/kcl.mod create mode 100644 pkg/client/test_data/test_update_with_mvs/update_1/dep_1/kcl.mod.lock create mode 100644 pkg/client/test_data/test_update_with_mvs/update_1/dep_1/main.k create mode 100644 pkg/client/test_data/test_update_with_mvs/update_1/dep_2/kcl.mod create mode 100644 pkg/client/test_data/test_update_with_mvs/update_1/dep_2/kcl.mod.lock create mode 100644 pkg/client/test_data/test_update_with_mvs/update_1/dep_2/main.k create mode 100644 pkg/client/test_data/test_update_with_mvs/update_1/pkg/kcl.mod create mode 100644 pkg/client/test_data/test_update_with_mvs/update_1/pkg/kcl.mod.bk create mode 100644 pkg/client/test_data/test_update_with_mvs/update_1/pkg/kcl.mod.expect create mode 100644 pkg/client/test_data/test_update_with_mvs/update_1/pkg/kcl.mod.lock create mode 100644 pkg/client/test_data/test_update_with_mvs/update_1/pkg/kcl.mod.lock.bk create mode 100644 pkg/client/test_data/test_update_with_mvs/update_1/pkg/kcl.mod.lock.expect create mode 100644 pkg/client/test_data/test_update_with_mvs/update_1/pkg/main.k create mode 100644 pkg/client/update.go create mode 100644 pkg/client/update_test.go create mode 100644 test/e2e/test_suites/test_data/test_add_with_name_1/kcl.mod create mode 100644 test/e2e/test_suites/test_data/test_add_with_name_1/kcl.mod.lock create mode 100644 test/e2e/test_suites/test_data/test_add_with_name_1/main.k diff --git a/pkg/client/client.go b/pkg/client/client.go index e4f65a01..2857f4de 100644 --- a/pkg/client/client.go +++ b/pkg/client/client.go @@ -813,7 +813,12 @@ func (c *KpmClient) AddDepWithOpts(kclPkg *pkg.KclPkg, opt *opt.AddOptions) (*pk kclPkg.Dependencies.Deps.Delete(d.Name) } - err = kclPkg.UpdateModAndLockFile() + // After adding the new dependency, + // Iterate through all the dependencies and select the version by mvs + _, err = c.Update( + WithUpdatedKclPkg(kclPkg), + ) + if err != nil { return nil, err } @@ -1191,6 +1196,7 @@ func (c *KpmClient) Download(dep *pkg.Dependency, homePath, localPath string) (* if dep.Source.Registry != nil { dep.Source.Registry.Tag = latestTag + dep.Source.Registry.Version = latestTag } // Complete some information that the local three dependencies depend on. diff --git a/pkg/client/client_test.go b/pkg/client/client_test.go index 2beed21a..a60b5639 100644 --- a/pkg/client/client_test.go +++ b/pkg/client/client_test.go @@ -196,9 +196,9 @@ func TestModandLockFilesWithGitPackageDownload(t *testing.T) { LocalPath: testPkgPath, RegistryOpts: opt.RegistryOptions{ Git: &opt.GitOptions{ - Url: "https://github.com/kcl-lang/modules.git", - Commit: "ee03122b5f45b09eb48694422fc99a0772f6bba8", - Package: "agent", + Url: "https://github.com/kcl-lang/flask-demo-kcl-manifests.git", + Commit: "8308200", + Package: "cc", }, }, } @@ -256,14 +256,6 @@ func TestModandLockFilesWithGitPackageDownload(t *testing.T) { fmt.Println(modLockContentStr) assert.Equal(t, modLockExpectContentStr, modLockContentStr) - - defer func() { - err = os.Truncate(testPkgPathMod, 0) - assert.Equal(t, err, nil) - - err = os.Truncate(testPkgPathModLock, 0) - assert.Equal(t, err, nil) - }() } func TestDependencyGraph(t *testing.T) { diff --git a/pkg/client/resolver.go b/pkg/client/resolver.go index 667d8fce..87d1fb19 100644 --- a/pkg/client/resolver.go +++ b/pkg/client/resolver.go @@ -12,7 +12,7 @@ type ResolveOption func(*ResolveOptions) error // resolveFunc is the function for resolving each dependency when traversing the dependency graph. // currentPkg is the current package to be resolved and parentPkg is the parent package of the current package. -type resolveFunc func(currentPkg, parentPkg *pkg.KclPkg) error +type resolveFunc func(dep *pkg.Dependency, parentPkg *pkg.KclPkg) error type ResolveOptions struct { // Source is the source of the package to be pulled. @@ -40,16 +40,16 @@ func WithCachePath(cachePath string) ResolveOption { } } -// WithPkgSource sets the source of the package to be resolved. -func WithPkgSource(source *downloader.Source) ResolveOption { +// WithResolveSource sets the source of the package to be resolved. +func WithResolveSource(source *downloader.Source) ResolveOption { return func(opts *ResolveOptions) error { opts.Source = source return nil } } -// WithPkgSourceUrl sets the source of the package to be resolved by the source url. -func WithPkgSourceUrl(sourceUrl string) ResolveOption { +// WithResolveSourceUrl sets the source of the package to be resolved by the source url. +func WithResolveSourceUrl(sourceUrl string) ResolveOption { return func(opts *ResolveOptions) error { source, err := downloader.NewSourceFromStr(sourceUrl) if err != nil { @@ -106,7 +106,7 @@ func (dr *DepsResolver) Resolve(options ...ResolveOption) error { } return PkgVisitor, nil } else { - return NewVisitor(*opts.Source, dr.kpmClient), nil + return NewVisitor(*source, dr.kpmClient), nil } } @@ -143,7 +143,7 @@ func (dr *DepsResolver) Resolve(options ...ResolveOption) error { err = visitor.Visit(&depSource, func(childPkg *pkg.KclPkg) error { for _, resolveFunc := range dr.resolveFuncs { - err := resolveFunc(childPkg, kclPkg) + err := resolveFunc(&dep, kclPkg) if err != nil { return err } @@ -158,7 +158,7 @@ func (dr *DepsResolver) Resolve(options ...ResolveOption) error { // Recursively resolve the dependencies of the dependency. err = dr.Resolve( - WithPkgSource(&depSource), + WithResolveSource(&depSource), WithEnableCache(opts.EnableCache), WithCachePath(opts.CachePath), ) diff --git a/pkg/client/resolver_test.go b/pkg/client/resolver_test.go index 37559b3e..fa7773e5 100644 --- a/pkg/client/resolver_test.go +++ b/pkg/client/resolver_test.go @@ -31,14 +31,14 @@ func TestResolver(t *testing.T) { kpmcli.SetLogWriter(&buf) resolver := NewDepsResolver(kpmcli) - resolver.AddResolveFunc(func(currentPkg, parentPkg *pkg.KclPkg) error { - res = append(res, fmt.Sprintf("%s -> %s", parentPkg.GetPkgName(), currentPkg.GetPkgName())) + resolver.AddResolveFunc(func(dep *pkg.Dependency, parentPkg *pkg.KclPkg) error { + res = append(res, fmt.Sprintf("%s -> %s", parentPkg.GetPkgName(), dep.Name)) return nil }) err = resolver.Resolve( WithEnableCache(true), - WithPkgSource(pkgSource), + WithResolveSource(pkgSource), ) if err != nil { diff --git a/pkg/client/test_data/test_mod_file_package/test_pkg/expect.mod b/pkg/client/test_data/test_mod_file_package/test_pkg/expect.mod index 18fcce1e..b9c6d8ef 100644 --- a/pkg/client/test_data/test_mod_file_package/test_pkg/expect.mod +++ b/pkg/client/test_data/test_mod_file_package/test_pkg/expect.mod @@ -1,4 +1,7 @@ [package] +name = "test_pkg" +edition = "v0.10.0" +version = "0.0.1" [dependencies] -agent = { git = "https://github.com/kcl-lang/modules.git", commit = "ee03122b5f45b09eb48694422fc99a0772f6bba8", package = "agent" } \ No newline at end of file +cc = { git = "https://github.com/kcl-lang/flask-demo-kcl-manifests.git", commit = "8308200", package = "cc" } \ No newline at end of file diff --git a/pkg/client/test_data/test_mod_file_package/test_pkg/expect.mod.lock b/pkg/client/test_data/test_mod_file_package/test_pkg/expect.mod.lock index 924f002d..32355765 100644 --- a/pkg/client/test_data/test_mod_file_package/test_pkg/expect.mod.lock +++ b/pkg/client/test_data/test_mod_file_package/test_pkg/expect.mod.lock @@ -1,12 +1,8 @@ [dependencies] - [dependencies.agent] - name = "agent" - full_name = "modules_ee03122b5f45b09eb48694422fc99a0772f6bba8" - version = "0.1.0" - url = "https://github.com/kcl-lang/modules.git" - commit = "ee03122b5f45b09eb48694422fc99a0772f6bba8" - package = "agent" - [dependencies.k8s] - name = "k8s" - full_name = "k8s_1.28" - version = "1.28" + [dependencies.cc] + name = "cc" + full_name = "flask-demo-kcl-manifests_8308200" + version = "0.0.1" + url = "https://github.com/kcl-lang/flask-demo-kcl-manifests.git" + commit = "8308200" + package = "cc" diff --git a/pkg/client/test_data/test_mod_file_package/test_pkg/kcl.mod b/pkg/client/test_data/test_mod_file_package/test_pkg/kcl.mod index e69de29b..aab695ab 100644 --- a/pkg/client/test_data/test_mod_file_package/test_pkg/kcl.mod +++ b/pkg/client/test_data/test_mod_file_package/test_pkg/kcl.mod @@ -0,0 +1,7 @@ +[package] +name = "test_pkg" +edition = "v0.10.0" +version = "0.0.1" + +[dependencies] +cc = { git = "https://github.com/kcl-lang/flask-demo-kcl-manifests.git", commit = "8308200", package = "cc" } diff --git a/pkg/client/test_data/test_mod_file_package/test_pkg/kcl.mod.lock b/pkg/client/test_data/test_mod_file_package/test_pkg/kcl.mod.lock index e69de29b..32355765 100644 --- a/pkg/client/test_data/test_mod_file_package/test_pkg/kcl.mod.lock +++ b/pkg/client/test_data/test_mod_file_package/test_pkg/kcl.mod.lock @@ -0,0 +1,8 @@ +[dependencies] + [dependencies.cc] + name = "cc" + full_name = "flask-demo-kcl-manifests_8308200" + version = "0.0.1" + url = "https://github.com/kcl-lang/flask-demo-kcl-manifests.git" + commit = "8308200" + package = "cc" diff --git a/pkg/client/test_data/test_mod_file_package/test_pkg_win/expect.mod b/pkg/client/test_data/test_mod_file_package/test_pkg_win/expect.mod index 18fcce1e..b9c6d8ef 100644 --- a/pkg/client/test_data/test_mod_file_package/test_pkg_win/expect.mod +++ b/pkg/client/test_data/test_mod_file_package/test_pkg_win/expect.mod @@ -1,4 +1,7 @@ [package] +name = "test_pkg" +edition = "v0.10.0" +version = "0.0.1" [dependencies] -agent = { git = "https://github.com/kcl-lang/modules.git", commit = "ee03122b5f45b09eb48694422fc99a0772f6bba8", package = "agent" } \ No newline at end of file +cc = { git = "https://github.com/kcl-lang/flask-demo-kcl-manifests.git", commit = "8308200", package = "cc" } \ No newline at end of file diff --git a/pkg/client/test_data/test_mod_file_package/test_pkg_win/expect.mod.lock b/pkg/client/test_data/test_mod_file_package/test_pkg_win/expect.mod.lock index 924f002d..32355765 100644 --- a/pkg/client/test_data/test_mod_file_package/test_pkg_win/expect.mod.lock +++ b/pkg/client/test_data/test_mod_file_package/test_pkg_win/expect.mod.lock @@ -1,12 +1,8 @@ [dependencies] - [dependencies.agent] - name = "agent" - full_name = "modules_ee03122b5f45b09eb48694422fc99a0772f6bba8" - version = "0.1.0" - url = "https://github.com/kcl-lang/modules.git" - commit = "ee03122b5f45b09eb48694422fc99a0772f6bba8" - package = "agent" - [dependencies.k8s] - name = "k8s" - full_name = "k8s_1.28" - version = "1.28" + [dependencies.cc] + name = "cc" + full_name = "flask-demo-kcl-manifests_8308200" + version = "0.0.1" + url = "https://github.com/kcl-lang/flask-demo-kcl-manifests.git" + commit = "8308200" + package = "cc" diff --git a/pkg/client/test_data/test_mod_file_package/test_pkg_win/kcl.mod b/pkg/client/test_data/test_mod_file_package/test_pkg_win/kcl.mod index e69de29b..a1ad3285 100644 --- a/pkg/client/test_data/test_mod_file_package/test_pkg_win/kcl.mod +++ b/pkg/client/test_data/test_mod_file_package/test_pkg_win/kcl.mod @@ -0,0 +1,4 @@ +[package] +name = "test_pkg" +edition = "v0.10.0" +version = "0.0.1" diff --git a/pkg/client/test_data/test_update_with_mvs/update_0/dep_0/kcl.mod b/pkg/client/test_data/test_update_with_mvs/update_0/dep_0/kcl.mod new file mode 100644 index 00000000..14335b99 --- /dev/null +++ b/pkg/client/test_data/test_update_with_mvs/update_0/dep_0/kcl.mod @@ -0,0 +1,7 @@ +[package] +name = "dep_0" +edition = "v0.10.0" +version = "0.0.1" + +[dependencies] +helloworld = "0.1.0" diff --git a/pkg/client/test_data/test_update_with_mvs/update_0/dep_0/kcl.mod.lock b/pkg/client/test_data/test_update_with_mvs/update_0/dep_0/kcl.mod.lock new file mode 100644 index 00000000..1bc5d15c --- /dev/null +++ b/pkg/client/test_data/test_update_with_mvs/update_0/dep_0/kcl.mod.lock @@ -0,0 +1,6 @@ +[dependencies] + [dependencies.helloworld] + name = "helloworld" + full_name = "helloworld_0.1.0" + version = "0.1.0" + sum = "aqrvSsd8zGHzRERbOzxYxARmK6QjvpQMYC1OqemdZvc=" diff --git a/pkg/client/test_data/test_update_with_mvs/update_0/dep_0/main.k b/pkg/client/test_data/test_update_with_mvs/update_0/dep_0/main.k new file mode 100644 index 00000000..fa7048e6 --- /dev/null +++ b/pkg/client/test_data/test_update_with_mvs/update_0/dep_0/main.k @@ -0,0 +1 @@ +The_first_kcl_program = 'Hello World!' \ No newline at end of file diff --git a/pkg/client/test_data/test_update_with_mvs/update_0/dep_1/kcl.mod b/pkg/client/test_data/test_update_with_mvs/update_0/dep_1/kcl.mod new file mode 100644 index 00000000..e4d487a9 --- /dev/null +++ b/pkg/client/test_data/test_update_with_mvs/update_0/dep_1/kcl.mod @@ -0,0 +1,7 @@ +[package] +name = "dep_1" +edition = "v0.10.0" +version = "0.0.1" + +[dependencies] +helloworld = "0.1.1" diff --git a/pkg/client/test_data/test_update_with_mvs/update_0/dep_1/kcl.mod.lock b/pkg/client/test_data/test_update_with_mvs/update_0/dep_1/kcl.mod.lock new file mode 100644 index 00000000..667cdff0 --- /dev/null +++ b/pkg/client/test_data/test_update_with_mvs/update_0/dep_1/kcl.mod.lock @@ -0,0 +1,6 @@ +[dependencies] + [dependencies.helloworld] + name = "helloworld" + full_name = "helloworld_0.1.1" + version = "0.1.1" + sum = "7OO4YK2QuRWPq9C7KTzcWcti5yUnueCjptT3OXiPVeQ=" diff --git a/pkg/client/test_data/test_update_with_mvs/update_0/dep_1/main.k b/pkg/client/test_data/test_update_with_mvs/update_0/dep_1/main.k new file mode 100644 index 00000000..fa7048e6 --- /dev/null +++ b/pkg/client/test_data/test_update_with_mvs/update_0/dep_1/main.k @@ -0,0 +1 @@ +The_first_kcl_program = 'Hello World!' \ No newline at end of file diff --git a/pkg/client/test_data/test_update_with_mvs/update_0/dep_2/kcl.mod b/pkg/client/test_data/test_update_with_mvs/update_0/dep_2/kcl.mod new file mode 100644 index 00000000..b098f6c7 --- /dev/null +++ b/pkg/client/test_data/test_update_with_mvs/update_0/dep_2/kcl.mod @@ -0,0 +1,7 @@ +[package] +name = "dep_2" +edition = "v0.10.0" +version = "0.0.1" + +[dependencies] +helloworld = "0.1.0" diff --git a/pkg/client/test_data/test_update_with_mvs/update_0/dep_2/kcl.mod.lock b/pkg/client/test_data/test_update_with_mvs/update_0/dep_2/kcl.mod.lock new file mode 100644 index 00000000..7b80eba3 --- /dev/null +++ b/pkg/client/test_data/test_update_with_mvs/update_0/dep_2/kcl.mod.lock @@ -0,0 +1,5 @@ +[dependencies] + [dependencies.helloworld] + name = "helloworld" + full_name = "helloworld_0.1.0" + version = "0.1.0" diff --git a/pkg/client/test_data/test_update_with_mvs/update_0/dep_2/main.k b/pkg/client/test_data/test_update_with_mvs/update_0/dep_2/main.k new file mode 100644 index 00000000..fa7048e6 --- /dev/null +++ b/pkg/client/test_data/test_update_with_mvs/update_0/dep_2/main.k @@ -0,0 +1 @@ +The_first_kcl_program = 'Hello World!' \ No newline at end of file diff --git a/pkg/client/test_data/test_update_with_mvs/update_0/pkg/kcl.mod b/pkg/client/test_data/test_update_with_mvs/update_0/pkg/kcl.mod new file mode 100644 index 00000000..c98ccd1b --- /dev/null +++ b/pkg/client/test_data/test_update_with_mvs/update_0/pkg/kcl.mod @@ -0,0 +1,9 @@ +[package] +name = "pkg" +edition = "v0.10.0" +version = "0.0.1" + +[dependencies] +dep_0 = { path = "../dep_0" } +dep_1 = { path = "../dep_1" } +dep_2 = { path = "../dep_2" } diff --git a/pkg/client/test_data/test_update_with_mvs/update_0/pkg/kcl.mod.expect b/pkg/client/test_data/test_update_with_mvs/update_0/pkg/kcl.mod.expect new file mode 100644 index 00000000..c98ccd1b --- /dev/null +++ b/pkg/client/test_data/test_update_with_mvs/update_0/pkg/kcl.mod.expect @@ -0,0 +1,9 @@ +[package] +name = "pkg" +edition = "v0.10.0" +version = "0.0.1" + +[dependencies] +dep_0 = { path = "../dep_0" } +dep_1 = { path = "../dep_1" } +dep_2 = { path = "../dep_2" } diff --git a/pkg/client/test_data/test_update_with_mvs/update_0/pkg/kcl.mod.lock b/pkg/client/test_data/test_update_with_mvs/update_0/pkg/kcl.mod.lock new file mode 100644 index 00000000..e60448ad --- /dev/null +++ b/pkg/client/test_data/test_update_with_mvs/update_0/pkg/kcl.mod.lock @@ -0,0 +1,17 @@ +[dependencies] + [dependencies.dep_0] + name = "dep_0" + full_name = "dep_0_0.0.1" + version = "0.0.1" + [dependencies.dep_1] + name = "dep_1" + full_name = "dep_1_0.0.1" + version = "0.0.1" + [dependencies.dep_2] + name = "dep_2" + full_name = "dep_2_0.0.1" + version = "0.0.1" + [dependencies.helloworld] + name = "helloworld" + full_name = "helloworld_0.1.1" + version = "0.1.1" diff --git a/pkg/client/test_data/test_update_with_mvs/update_0/pkg/kcl.mod.lock.expect b/pkg/client/test_data/test_update_with_mvs/update_0/pkg/kcl.mod.lock.expect new file mode 100644 index 00000000..e60448ad --- /dev/null +++ b/pkg/client/test_data/test_update_with_mvs/update_0/pkg/kcl.mod.lock.expect @@ -0,0 +1,17 @@ +[dependencies] + [dependencies.dep_0] + name = "dep_0" + full_name = "dep_0_0.0.1" + version = "0.0.1" + [dependencies.dep_1] + name = "dep_1" + full_name = "dep_1_0.0.1" + version = "0.0.1" + [dependencies.dep_2] + name = "dep_2" + full_name = "dep_2_0.0.1" + version = "0.0.1" + [dependencies.helloworld] + name = "helloworld" + full_name = "helloworld_0.1.1" + version = "0.1.1" diff --git a/pkg/client/test_data/test_update_with_mvs/update_0/pkg/main.k b/pkg/client/test_data/test_update_with_mvs/update_0/pkg/main.k new file mode 100644 index 00000000..fa7048e6 --- /dev/null +++ b/pkg/client/test_data/test_update_with_mvs/update_0/pkg/main.k @@ -0,0 +1 @@ +The_first_kcl_program = 'Hello World!' \ No newline at end of file diff --git a/pkg/client/test_data/test_update_with_mvs/update_1/dep_0/kcl.mod b/pkg/client/test_data/test_update_with_mvs/update_1/dep_0/kcl.mod new file mode 100644 index 00000000..14335b99 --- /dev/null +++ b/pkg/client/test_data/test_update_with_mvs/update_1/dep_0/kcl.mod @@ -0,0 +1,7 @@ +[package] +name = "dep_0" +edition = "v0.10.0" +version = "0.0.1" + +[dependencies] +helloworld = "0.1.0" diff --git a/pkg/client/test_data/test_update_with_mvs/update_1/dep_0/kcl.mod.lock b/pkg/client/test_data/test_update_with_mvs/update_1/dep_0/kcl.mod.lock new file mode 100644 index 00000000..1bc5d15c --- /dev/null +++ b/pkg/client/test_data/test_update_with_mvs/update_1/dep_0/kcl.mod.lock @@ -0,0 +1,6 @@ +[dependencies] + [dependencies.helloworld] + name = "helloworld" + full_name = "helloworld_0.1.0" + version = "0.1.0" + sum = "aqrvSsd8zGHzRERbOzxYxARmK6QjvpQMYC1OqemdZvc=" diff --git a/pkg/client/test_data/test_update_with_mvs/update_1/dep_0/main.k b/pkg/client/test_data/test_update_with_mvs/update_1/dep_0/main.k new file mode 100644 index 00000000..fa7048e6 --- /dev/null +++ b/pkg/client/test_data/test_update_with_mvs/update_1/dep_0/main.k @@ -0,0 +1 @@ +The_first_kcl_program = 'Hello World!' \ No newline at end of file diff --git a/pkg/client/test_data/test_update_with_mvs/update_1/dep_1/kcl.mod b/pkg/client/test_data/test_update_with_mvs/update_1/dep_1/kcl.mod new file mode 100644 index 00000000..e4d487a9 --- /dev/null +++ b/pkg/client/test_data/test_update_with_mvs/update_1/dep_1/kcl.mod @@ -0,0 +1,7 @@ +[package] +name = "dep_1" +edition = "v0.10.0" +version = "0.0.1" + +[dependencies] +helloworld = "0.1.1" diff --git a/pkg/client/test_data/test_update_with_mvs/update_1/dep_1/kcl.mod.lock b/pkg/client/test_data/test_update_with_mvs/update_1/dep_1/kcl.mod.lock new file mode 100644 index 00000000..667cdff0 --- /dev/null +++ b/pkg/client/test_data/test_update_with_mvs/update_1/dep_1/kcl.mod.lock @@ -0,0 +1,6 @@ +[dependencies] + [dependencies.helloworld] + name = "helloworld" + full_name = "helloworld_0.1.1" + version = "0.1.1" + sum = "7OO4YK2QuRWPq9C7KTzcWcti5yUnueCjptT3OXiPVeQ=" diff --git a/pkg/client/test_data/test_update_with_mvs/update_1/dep_1/main.k b/pkg/client/test_data/test_update_with_mvs/update_1/dep_1/main.k new file mode 100644 index 00000000..fa7048e6 --- /dev/null +++ b/pkg/client/test_data/test_update_with_mvs/update_1/dep_1/main.k @@ -0,0 +1 @@ +The_first_kcl_program = 'Hello World!' \ No newline at end of file diff --git a/pkg/client/test_data/test_update_with_mvs/update_1/dep_2/kcl.mod b/pkg/client/test_data/test_update_with_mvs/update_1/dep_2/kcl.mod new file mode 100644 index 00000000..b098f6c7 --- /dev/null +++ b/pkg/client/test_data/test_update_with_mvs/update_1/dep_2/kcl.mod @@ -0,0 +1,7 @@ +[package] +name = "dep_2" +edition = "v0.10.0" +version = "0.0.1" + +[dependencies] +helloworld = "0.1.0" diff --git a/pkg/client/test_data/test_update_with_mvs/update_1/dep_2/kcl.mod.lock b/pkg/client/test_data/test_update_with_mvs/update_1/dep_2/kcl.mod.lock new file mode 100644 index 00000000..7b80eba3 --- /dev/null +++ b/pkg/client/test_data/test_update_with_mvs/update_1/dep_2/kcl.mod.lock @@ -0,0 +1,5 @@ +[dependencies] + [dependencies.helloworld] + name = "helloworld" + full_name = "helloworld_0.1.0" + version = "0.1.0" diff --git a/pkg/client/test_data/test_update_with_mvs/update_1/dep_2/main.k b/pkg/client/test_data/test_update_with_mvs/update_1/dep_2/main.k new file mode 100644 index 00000000..fa7048e6 --- /dev/null +++ b/pkg/client/test_data/test_update_with_mvs/update_1/dep_2/main.k @@ -0,0 +1 @@ +The_first_kcl_program = 'Hello World!' \ No newline at end of file diff --git a/pkg/client/test_data/test_update_with_mvs/update_1/pkg/kcl.mod b/pkg/client/test_data/test_update_with_mvs/update_1/pkg/kcl.mod new file mode 100644 index 00000000..e3d83935 --- /dev/null +++ b/pkg/client/test_data/test_update_with_mvs/update_1/pkg/kcl.mod @@ -0,0 +1,10 @@ +[package] +name = "pkg" +edition = "v0.10.0" +version = "0.0.1" + +[dependencies] +dep_0 = { path = "../dep_0" } +dep_1 = { path = "../dep_1" } +dep_2 = { path = "../dep_2" } +helloworld = "0.1.1" diff --git a/pkg/client/test_data/test_update_with_mvs/update_1/pkg/kcl.mod.bk b/pkg/client/test_data/test_update_with_mvs/update_1/pkg/kcl.mod.bk new file mode 100644 index 00000000..5e8f8790 --- /dev/null +++ b/pkg/client/test_data/test_update_with_mvs/update_1/pkg/kcl.mod.bk @@ -0,0 +1,10 @@ +[package] +name = "pkg" +edition = "v0.10.0" +version = "0.0.1" + +[dependencies] +dep_0 = { path = "../dep_0" } +dep_1 = { path = "../dep_1" } +dep_2 = { path = "../dep_2" } +helloworld = "0.1.0" diff --git a/pkg/client/test_data/test_update_with_mvs/update_1/pkg/kcl.mod.expect b/pkg/client/test_data/test_update_with_mvs/update_1/pkg/kcl.mod.expect new file mode 100644 index 00000000..9d725b79 --- /dev/null +++ b/pkg/client/test_data/test_update_with_mvs/update_1/pkg/kcl.mod.expect @@ -0,0 +1,10 @@ +[package] +name = "pkg" +edition = "v0.10.0" +version = "0.0.1" + +[dependencies] +dep_0 = { path = "../dep_0" } +dep_1 = { path = "../dep_1" } +dep_2 = { path = "../dep_2" } +helloworld = "0.1.1" \ No newline at end of file diff --git a/pkg/client/test_data/test_update_with_mvs/update_1/pkg/kcl.mod.lock b/pkg/client/test_data/test_update_with_mvs/update_1/pkg/kcl.mod.lock new file mode 100644 index 00000000..e60448ad --- /dev/null +++ b/pkg/client/test_data/test_update_with_mvs/update_1/pkg/kcl.mod.lock @@ -0,0 +1,17 @@ +[dependencies] + [dependencies.dep_0] + name = "dep_0" + full_name = "dep_0_0.0.1" + version = "0.0.1" + [dependencies.dep_1] + name = "dep_1" + full_name = "dep_1_0.0.1" + version = "0.0.1" + [dependencies.dep_2] + name = "dep_2" + full_name = "dep_2_0.0.1" + version = "0.0.1" + [dependencies.helloworld] + name = "helloworld" + full_name = "helloworld_0.1.1" + version = "0.1.1" diff --git a/pkg/client/test_data/test_update_with_mvs/update_1/pkg/kcl.mod.lock.bk b/pkg/client/test_data/test_update_with_mvs/update_1/pkg/kcl.mod.lock.bk new file mode 100644 index 00000000..04d67c17 --- /dev/null +++ b/pkg/client/test_data/test_update_with_mvs/update_1/pkg/kcl.mod.lock.bk @@ -0,0 +1,17 @@ +[dependencies] + [dependencies.dep_0] + name = "dep_0" + full_name = "dep_0_0.0.1" + version = "0.0.1" + [dependencies.dep_1] + name = "dep_1" + full_name = "dep_1_0.0.1" + version = "0.0.1" + [dependencies.dep_2] + name = "dep_2" + full_name = "dep_2_0.0.1" + version = "0.0.1" + [dependencies.helloworld] + name = "helloworld" + full_name = "helloworld_0.1.0" + version = "0.1.0" diff --git a/pkg/client/test_data/test_update_with_mvs/update_1/pkg/kcl.mod.lock.expect b/pkg/client/test_data/test_update_with_mvs/update_1/pkg/kcl.mod.lock.expect new file mode 100644 index 00000000..e60448ad --- /dev/null +++ b/pkg/client/test_data/test_update_with_mvs/update_1/pkg/kcl.mod.lock.expect @@ -0,0 +1,17 @@ +[dependencies] + [dependencies.dep_0] + name = "dep_0" + full_name = "dep_0_0.0.1" + version = "0.0.1" + [dependencies.dep_1] + name = "dep_1" + full_name = "dep_1_0.0.1" + version = "0.0.1" + [dependencies.dep_2] + name = "dep_2" + full_name = "dep_2_0.0.1" + version = "0.0.1" + [dependencies.helloworld] + name = "helloworld" + full_name = "helloworld_0.1.1" + version = "0.1.1" diff --git a/pkg/client/test_data/test_update_with_mvs/update_1/pkg/main.k b/pkg/client/test_data/test_update_with_mvs/update_1/pkg/main.k new file mode 100644 index 00000000..fa7048e6 --- /dev/null +++ b/pkg/client/test_data/test_update_with_mvs/update_1/pkg/main.k @@ -0,0 +1 @@ +The_first_kcl_program = 'Hello World!' \ No newline at end of file diff --git a/pkg/client/update.go b/pkg/client/update.go new file mode 100644 index 00000000..7eac201c --- /dev/null +++ b/pkg/client/update.go @@ -0,0 +1,108 @@ +package client + +import ( + "fmt" + "path/filepath" + + "kcl-lang.io/kpm/pkg/downloader" + pkg "kcl-lang.io/kpm/pkg/package" +) + +// UpdateOptions is the option for updating a package. +// Updating a package means iterating all the dependencies of the package +// and updating the dependencies and selecting the version of the dependencies by MVS. +type UpdateOptions struct { + kpkg *pkg.KclPkg +} + +type UpdateOption func(*UpdateOptions) error + +// WithUpdatedKclPkg sets the kcl package to be updated. +func WithUpdatedKclPkg(kpkg *pkg.KclPkg) UpdateOption { + return func(opts *UpdateOptions) error { + opts.kpkg = kpkg + return nil + } +} + +func (c *KpmClient) Update(options ...UpdateOption) (*pkg.KclPkg, error) { + opts := &UpdateOptions{} + for _, option := range options { + if err := option(opts); err != nil { + return nil, err + } + } + + kpkg := opts.kpkg + + modDeps := kpkg.ModFile.Dependencies.Deps + lockDeps := kpkg.Dependencies.Deps + + // Create a new dependency resolver + resolver := NewDepsResolver(c) + // ResolveFunc is the function for resolving each dependency when traversing the dependency graph. + resolverFunc := func(dep *pkg.Dependency, parentPkg *pkg.KclPkg) error { + // Check if the dependency exists in the mod file. + if existDep, exist := modDeps.Get(dep.Name); exist { + // if the dependency exists in the mod file, + // check the version and select the greater one. + if less, err := existDep.VersionLessThan(dep); less && err == nil { + kpkg.ModFile.Dependencies.Deps.Set(dep.Name, *dep) + } + // if the dependency does not exist in the mod file, + // the dependency is a indirect dependency. + // it will be added to the kcl.mod.lock file not the kcl.mod file. + } + // Check if the dependency exists in the lock file. + if existDep, exist := lockDeps.Get(dep.Name); exist { + // If the dependency exists in the lock file, + // check the version and select the greater one. + if less, err := existDep.VersionLessThan(dep); less && err == nil { + kpkg.Dependencies.Deps.Set(dep.Name, *dep) + } + } else { + // if the dependency does not exist in the lock file, + // the dependency is a new dependency and will be added to the lock file. + kpkg.Dependencies.Deps.Set(dep.Name, *dep) + } + + return nil + } + resolver.AddResolveFunc(resolverFunc) + + // Iterate all the dependencies of the package in kcl.mod and resolve each dependency. + for _, depName := range modDeps.Keys() { + dep, ok := modDeps.Get(depName) + if !ok { + return nil, fmt.Errorf("failed to get dependency %s", depName) + } + + // Check if the dependency is a local path and it is not an absolute path. + // If it is not an absolute path, transform the path to an absolute path. + var depSource *downloader.Source + if dep.Source.IsLocalPath() && !filepath.IsAbs(dep.Source.Local.Path) { + depSource = &downloader.Source{ + Local: &downloader.Local{ + Path: filepath.Join(kpkg.HomePath, dep.Source.Local.Path), + }, + } + } else { + depSource = &dep.Source + } + + err := resolver.Resolve( + WithEnableCache(true), + WithResolveSource(depSource), + ) + if err != nil { + return nil, err + } + } + + err := kpkg.UpdateModAndLockFile() + if err != nil { + return nil, err + } + + return kpkg, nil +} diff --git a/pkg/client/update_test.go b/pkg/client/update_test.go new file mode 100644 index 00000000..1202428f --- /dev/null +++ b/pkg/client/update_test.go @@ -0,0 +1,80 @@ +package client + +import ( + "os" + "path/filepath" + "testing" + + "github.com/otiai10/copy" + "gotest.tools/v3/assert" + "kcl-lang.io/kpm/pkg/utils" +) + +func TestUpdate(t *testing.T) { + testDir := getTestDir("test_update_with_mvs") + kpmcli, err := NewKpmClient() + if err != nil { + t.Fatal(err) + } + + updates := []struct { + name string + before func() error + }{ + { + name: "update_0", + before: func() error { return nil }, + }, + { + name: "update_1", + before: func() error { + if err := copy.Copy(filepath.Join(testDir, "update_1", "pkg", "kcl.mod.bk"), filepath.Join(testDir, "update_1", "pkg", "kcl.mod")); err != nil { + return err + } + if err := copy.Copy(filepath.Join(testDir, "update_1", "pkg", "kcl.mod.lock.bk"), filepath.Join(testDir, "update_1", "pkg", "kcl.mod.lock")); err != nil { + return err + } + return nil + }, + }, + } + + for _, update := range updates { + if err := update.before(); err != nil { + t.Fatal(err) + } + + kpkg, err := kpmcli.LoadPkgFromPath(filepath.Join(testDir, update.name, "pkg")) + if err != nil { + t.Fatal(err) + } + + _, err = kpmcli.Update(WithUpdatedKclPkg(kpkg)) + if err != nil { + t.Fatal(err) + } + + expectedMod, err := os.ReadFile(filepath.Join(testDir, update.name, "pkg", "kcl.mod.expect")) + if err != nil { + t.Fatal(err) + } + + expectedModLock, err := os.ReadFile(filepath.Join(testDir, update.name, "pkg", "kcl.mod.lock.expect")) + if err != nil { + t.Fatal(err) + } + + gotMod, err := os.ReadFile(filepath.Join(testDir, update.name, "pkg", "kcl.mod")) + if err != nil { + t.Fatal(err) + } + + gotModLock, err := os.ReadFile(filepath.Join(testDir, update.name, "pkg", "kcl.mod.lock")) + if err != nil { + t.Fatal(err) + } + + assert.Equal(t, utils.RmNewline(string(expectedMod)), utils.RmNewline(string(gotMod))) + assert.Equal(t, utils.RmNewline(string(expectedModLock)), utils.RmNewline(string(gotModLock))) + } +} diff --git a/pkg/client/visitor.go b/pkg/client/visitor.go index fe3159dc..0d151ded 100644 --- a/pkg/client/visitor.go +++ b/pkg/client/visitor.go @@ -138,8 +138,15 @@ func (rv *RemoteVisitor) Visit(s *downloader.Source, v visitFunc) error { if err != nil { return err } + pkgPath := tmpDir + if s.Git != nil && len(s.Git.Package) > 0 { + pkgPath, err = utils.FindPackage(tmpDir, s.Git.Package) + if err != nil { + return err + } + } - kclPkg, err := rv.kpmcli.LoadPkgFromPath(tmpDir) + kclPkg, err := rv.kpmcli.LoadPkgFromPath(pkgPath) if err != nil { return err } diff --git a/pkg/downloader/downloader.go b/pkg/downloader/downloader.go index 668061e1..14580681 100644 --- a/pkg/downloader/downloader.go +++ b/pkg/downloader/downloader.go @@ -6,6 +6,7 @@ import ( "io" "os" "path/filepath" + "strings" v1 "github.com/opencontainers/image-spec/specs-go/v1" "github.com/otiai10/copy" @@ -131,6 +132,7 @@ func (d *DepDownloader) Download(opts DownloadOptions) error { if opts.EnableCache { // TODO: After the new local storage structure is complete, // this section should be replaced with the new storage structure instead of the cache path according to the /. + // https://github.com/kcl-lang/kpm/issues/384 var pkgFullName string if opts.Source.Registry != nil && len(opts.Source.Registry.Version) != 0 { pkgFullName = fmt.Sprintf("%s_%s", filepath.Base(opts.Source.Registry.Oci.Repo), opts.Source.Registry.Version) @@ -138,14 +140,18 @@ func (d *DepDownloader) Download(opts DownloadOptions) error { if opts.Source.Oci != nil && len(opts.Source.Oci.Tag) != 0 { pkgFullName = fmt.Sprintf("%s_%s", filepath.Base(opts.Source.Oci.Repo), opts.Source.Oci.Tag) } + if opts.Source.Git != nil && len(opts.Source.Git.Tag) != 0 { - pkgFullName = fmt.Sprintf("%s_%s", filepath.Base(opts.Source.Git.Url), opts.Source.Git.Tag) + gitUrl := strings.TrimSuffix(opts.Source.Git.Url, filepath.Ext(opts.Source.Git.Url)) + pkgFullName = fmt.Sprintf("%s_%s", filepath.Base(gitUrl), opts.Source.Git.Tag) } if opts.Source.Git != nil && len(opts.Source.Git.Branch) != 0 { - pkgFullName = fmt.Sprintf("%s_%s", filepath.Base(opts.Source.Git.Url), opts.Source.Git.Branch) + gitUrl := strings.TrimSuffix(opts.Source.Git.Url, filepath.Ext(opts.Source.Git.Url)) + pkgFullName = fmt.Sprintf("%s_%s", filepath.Base(gitUrl), opts.Source.Git.Branch) } if opts.Source.Git != nil && len(opts.Source.Git.Commit) != 0 { - pkgFullName = fmt.Sprintf("%s_%s", filepath.Base(opts.Source.Git.Url), opts.Source.Git.Commit) + gitUrl := strings.TrimSuffix(opts.Source.Git.Url, filepath.Ext(opts.Source.Git.Url)) + pkgFullName = fmt.Sprintf("%s_%s", filepath.Base(gitUrl), opts.Source.Git.Commit) } cacheFullPath := filepath.Join(opts.CachePath, pkgFullName) diff --git a/pkg/package/modfile.go b/pkg/package/modfile.go index b4477ed8..87deaa47 100644 --- a/pkg/package/modfile.go +++ b/pkg/package/modfile.go @@ -9,6 +9,7 @@ import ( "github.com/BurntSushi/toml" orderedmap "github.com/elliotchance/orderedmap/v2" + "github.com/hashicorp/go-version" "kcl-lang.io/kcl-go/pkg/kcl" @@ -200,6 +201,22 @@ type Dependency struct { downloader.Source `json:"-"` } +// VersionGreaterThan will compare the version of a dependency with another dependency. +func (d *Dependency) VersionLessThan(other *Dependency) (bool, error) { + + ver, err := version.NewVersion(d.Version) + if err != nil { + return false, fmt.Errorf("failed to parse version %s", d.Version) + } + + otherVer, err := version.NewVersion(other.Version) + if err != nil { + return false, fmt.Errorf("failed to parse version %s", other.Version) + } + + return ver.LessThan(otherVer), nil +} + func (d *Dependency) FromKclPkg(pkg *KclPkg) { d.FullName = pkg.GetPkgFullName() d.Version = pkg.GetPkgVersion() @@ -252,9 +269,12 @@ func (d *Dependency) GenPathSuffix() string { var storePkgName string if d.Source.Oci != nil { - storePkgName = fmt.Sprintf(PKG_NAME_PATTERN, d.Name, d.Source.Oci.Tag) + name := filepath.Base(d.Source.Oci.Repo) + storePkgName = fmt.Sprintf(PKG_NAME_PATTERN, name, d.Source.Oci.Tag) } else if d.Source.Git != nil { - name := d.Name + // TODO: new local dependency structure will replace this + // issue: https://github.com/kcl-lang/kpm/issues/384 + name := strings.TrimSuffix(filepath.Base(d.Source.Git.Url), filepath.Ext(d.Source.Git.Url)) if d.Source.Git.GetPackage() != "" { name = strings.Split(d.FullName, "_")[0] } @@ -266,7 +286,8 @@ func (d *Dependency) GenPathSuffix() string { storePkgName = fmt.Sprintf(PKG_NAME_PATTERN, name, d.Source.Git.Branch) } } else if d.Source.Registry != nil { - storePkgName = fmt.Sprintf(PKG_NAME_PATTERN, d.Name, d.Source.Registry.Version) + name := filepath.Base(d.Source.Registry.Oci.Repo) + storePkgName = fmt.Sprintf(PKG_NAME_PATTERN, name, d.Source.Registry.Version) } else { storePkgName = fmt.Sprintf(PKG_NAME_PATTERN, d.Name, d.Version) } @@ -579,6 +600,7 @@ func ParseOpt(opt *opt.RegistryOptions) (*Dependency, error) { Registry: &downloader.Registry{ Oci: &ociSource, Version: opt.Registry.Tag, + Name: opt.Registry.Ref, }, }, Version: opt.Registry.Tag, diff --git a/test/e2e/test_suites/test_data/test_add_with_name_1/kcl.mod b/test/e2e/test_suites/test_data/test_add_with_name_1/kcl.mod new file mode 100644 index 00000000..d8222e81 --- /dev/null +++ b/test/e2e/test_suites/test_data/test_add_with_name_1/kcl.mod @@ -0,0 +1,7 @@ +[package] +name = "test_add_with_name_1" +edition = "v0.10.0" +version = "0.0.1" + +[dependencies] +k8s = { oci = "oci://localhost:5001/test/k8s", tag = "1.27" } diff --git a/test/e2e/test_suites/test_data/test_add_with_name_1/kcl.mod.lock b/test/e2e/test_suites/test_data/test_add_with_name_1/kcl.mod.lock new file mode 100644 index 00000000..7ca1df46 --- /dev/null +++ b/test/e2e/test_suites/test_data/test_add_with_name_1/kcl.mod.lock @@ -0,0 +1,9 @@ +[dependencies] + [dependencies.k8s] + name = "k8s" + full_name = "k8s_1.27" + version = "1.27" + sum = "xnYM1FWHAy3m+KcQMQb2rjZouTxumqYt6FGZpu2T4yM=" + reg = "localhost:5001" + repo = "test/k8s" + oci_tag = "1.27" diff --git a/test/e2e/test_suites/test_data/test_add_with_name_1/main.k b/test/e2e/test_suites/test_data/test_add_with_name_1/main.k new file mode 100644 index 00000000..fa7048e6 --- /dev/null +++ b/test/e2e/test_suites/test_data/test_add_with_name_1/main.k @@ -0,0 +1 @@ +The_first_kcl_program = 'Hello World!' \ No newline at end of file diff --git a/test/e2e/test_suites/test_data/test_kpm_add_git_commit_0/kcl.mod b/test/e2e/test_suites/test_data/test_kpm_add_git_commit_0/kcl.mod index e69de29b..3875517f 100644 --- a/test/e2e/test_suites/test_data/test_kpm_add_git_commit_0/kcl.mod +++ b/test/e2e/test_suites/test_data/test_kpm_add_git_commit_0/kcl.mod @@ -0,0 +1,4 @@ +[package] +name = "test_kpm_add_git_commit_0" +edition = "v0.10.0" +version = "0.0.1" diff --git a/test/e2e/test_suites/test_data/test_kpm_add_git_commit_0/main.k b/test/e2e/test_suites/test_data/test_kpm_add_git_commit_0/main.k index e69de29b..fa7048e6 100644 --- a/test/e2e/test_suites/test_data/test_kpm_add_git_commit_0/main.k +++ b/test/e2e/test_suites/test_data/test_kpm_add_git_commit_0/main.k @@ -0,0 +1 @@ +The_first_kcl_program = 'Hello World!' \ No newline at end of file diff --git a/test/e2e/test_suites/test_data/test_kpm_add_git_commit_1/kcl.mod b/test/e2e/test_suites/test_data/test_kpm_add_git_commit_1/kcl.mod index e69de29b..cc6644d5 100644 --- a/test/e2e/test_suites/test_data/test_kpm_add_git_commit_1/kcl.mod +++ b/test/e2e/test_suites/test_data/test_kpm_add_git_commit_1/kcl.mod @@ -0,0 +1,4 @@ +[package] +name = "test_kpm_add_git_commit_1" +edition = "v0.10.0" +version = "0.0.1" diff --git a/test/e2e/test_suites/test_data/test_kpm_add_git_commit_1/main.k b/test/e2e/test_suites/test_data/test_kpm_add_git_commit_1/main.k index e69de29b..fa7048e6 100644 --- a/test/e2e/test_suites/test_data/test_kpm_add_git_commit_1/main.k +++ b/test/e2e/test_suites/test_data/test_kpm_add_git_commit_1/main.k @@ -0,0 +1 @@ +The_first_kcl_program = 'Hello World!' \ No newline at end of file From d873e47dfb7a5a93207e21f3f6a3530a67dc734c Mon Sep 17 00:00:00 2001 From: zongz Date: Fri, 6 Sep 2024 15:22:06 +0800 Subject: [PATCH 2/3] fix: add protected code for nil pointer Signed-off-by: zongz --- pkg/client/update.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/pkg/client/update.go b/pkg/client/update.go index 7eac201c..9414e992 100644 --- a/pkg/client/update.go +++ b/pkg/client/update.go @@ -34,9 +34,18 @@ func (c *KpmClient) Update(options ...UpdateOption) (*pkg.KclPkg, error) { } kpkg := opts.kpkg + if kpkg == nil { + return nil, fmt.Errorf("kcl package is nil") + } modDeps := kpkg.ModFile.Dependencies.Deps + if modDeps == nil { + return nil, fmt.Errorf("kcl.mod dependencies is nil") + } lockDeps := kpkg.Dependencies.Deps + if lockDeps == nil { + return nil, fmt.Errorf("kcl.mod.lock dependencies is nil") + } // Create a new dependency resolver resolver := NewDepsResolver(c) From add6bc2cf4f3370f2bb5ad8c8ff4883ff49b2dd1 Mon Sep 17 00:00:00 2001 From: zongz Date: Fri, 6 Sep 2024 15:46:04 +0800 Subject: [PATCH 3/3] feat: supports mvs for update command Signed-off-by: zongz --- pkg/client/client.go | 17 ++++----------- pkg/cmd/cmd_update.go | 48 ------------------------------------------- 2 files changed, 4 insertions(+), 61 deletions(-) diff --git a/pkg/client/client.go b/pkg/client/client.go index 2857f4de..23779ad1 100644 --- a/pkg/client/client.go +++ b/pkg/client/client.go @@ -473,20 +473,11 @@ func (c *KpmClient) UpdateDeps(kclPkg *pkg.KclPkg) error { return err } - // update kcl.mod - err = kclPkg.ModFile.StoreModFile() - if err != nil { - return err - } + _, err = c.Update( + WithUpdatedKclPkg(kclPkg), + ) - // Generate file kcl.mod.lock. - if !kclPkg.NoSumCheck { - err := kclPkg.LockDepsVersion() - if err != nil { - return err - } - } - return nil + return err } // ResolveDepsMetadataInJsonStr will calculate the local storage path of the external package, diff --git a/pkg/cmd/cmd_update.go b/pkg/cmd/cmd_update.go index b745b73a..703ad7a5 100644 --- a/pkg/cmd/cmd_update.go +++ b/pkg/cmd/cmd_update.go @@ -10,8 +10,6 @@ import ( "slices" "strings" - "github.com/dominikbraun/graph" - "github.com/elliotchance/orderedmap/v2" "github.com/urfave/cli/v2" "golang.org/x/mod/module" "kcl-lang.io/kpm/pkg/client" @@ -58,8 +56,6 @@ func KpmUpdate(c *cli.Context, kpmcli *client.KpmClient) error { } }() - pkgInfos := c.Args().Slice() - pwd, err := os.Getwd() if err != nil { return reporter.NewErrorEvent(reporter.Bug, err, "internal bugs, please contact us to fix it.") @@ -80,50 +76,6 @@ func KpmUpdate(c *cli.Context, kpmcli *client.KpmClient) error { return err } - var ( - modulesToUpgrade []module.Version - modulesToDowngrade []module.Version - ) - - for _, pkgInfo := range pkgInfos { - err = GetModulesToUpdate(kclPkg, modulesToUpgrade, modulesToDowngrade, pkgInfo) - if err != nil { - reporter.Report(err) - } - } - - _, depGraph, err := kpmcli.InitGraphAndDownloadDeps(kclPkg) - if err != nil { - return err - } - - reqs := mvs.ReqsGraph{ - Graph: depGraph, - KpmClient: kpmcli, - KpmPkg: kclPkg, - } - - target := module.Version{Path: kclPkg.GetPkgName(), Version: kclPkg.GetPkgVersion()} - buildList, err := mvs.UpdateBuildList(target, modulesToUpgrade, modulesToDowngrade, &reqs) - if err != nil { - return reporter.NewErrorEvent(reporter.FailedUpdatingBuildList, err, "failed to update build list") - } - - // get all the vertices in the graph - modules, err := graph.TopologicalSort(depGraph) - if err != nil { - return reporter.NewErrorEvent(reporter.FailedTopologicalSort, err, "failed to sort the dependencies") - } - - kclPkg.ModFile.Dependencies.Deps = orderedmap.NewOrderedMap[string, pkg.Dependency]() - - for _, module := range modules { - err = InsertModuleToDeps(kclPkg, module, target, buildList, reqs) - if err != nil { - return err - } - } - err = kpmcli.UpdateDeps(kclPkg) if err != nil { return err