diff --git a/commands/alpha/live/plan/command.go b/commands/alpha/live/plan/command.go index 886face464..e1b6b51687 100644 --- a/commands/alpha/live/plan/command.go +++ b/commands/alpha/live/plan/command.go @@ -21,7 +21,7 @@ import ( "os" "strings" - "github.com/kptdev/kpt/internal/util/argutil" + argsutil "github.com/kptdev/kpt/pkg/lib/util/args" "github.com/kptdev/kpt/pkg/live" kptplanner "github.com/kptdev/kpt/pkg/live/planner" "github.com/spf13/cobra" @@ -112,7 +112,7 @@ func (r *Runner) RunE(c *cobra.Command, args []string) error { path := args[0] var err error if args[0] != "-" { - path, err = argutil.ResolveSymlink(r.ctx, path) + path, err = argsutil.ResolveSymlink(r.ctx, path) if err != nil { return err } diff --git a/commands/fn/render/cmdrender.go b/commands/fn/render/cmdrender.go index 43426ebef9..f1bdb03f52 100644 --- a/commands/fn/render/cmdrender.go +++ b/commands/fn/render/cmdrender.go @@ -23,11 +23,11 @@ import ( "os" docs "github.com/kptdev/kpt/internal/docs/generated/fndocs" - "github.com/kptdev/kpt/internal/util/argutil" - "github.com/kptdev/kpt/internal/util/pathutil" - "github.com/kptdev/kpt/internal/util/render" + "github.com/kptdev/kpt/pkg/lib/kptops" "github.com/kptdev/kpt/pkg/lib/runneroptions" + argsutil "github.com/kptdev/kpt/pkg/lib/util/args" "github.com/kptdev/kpt/pkg/lib/util/cmdutil" + "github.com/kptdev/kpt/pkg/lib/util/path" "github.com/kptdev/kpt/pkg/printer" "github.com/spf13/cobra" "sigs.k8s.io/kustomize/kyaml/filesys" @@ -100,7 +100,7 @@ func (r *Runner) preRunE(_ *cobra.Command, args []string) error { r.pkgPath = args[0] } var err error - r.pkgPath, err = argutil.ResolveSymlink(r.ctx, r.pkgPath) + r.pkgPath, err = argsutil.ResolveSymlink(r.ctx, r.pkgPath) if err != nil { return err } @@ -126,11 +126,11 @@ func (r *Runner) runE(_ *cobra.Command, _ []string) error { // capture the content to be written output = &outContent } - absPkgPath, _, err := pathutil.ResolveAbsAndRelPaths(r.pkgPath) + absPkgPath, _, err := path.ResolveAbsAndRelPaths(r.pkgPath) if err != nil { return err } - executor := render.Renderer{ + executor := kptops.Renderer{ PkgPath: absPkgPath, ResultsDirPath: r.resultsDirPath, Output: output, diff --git a/commands/live/apply/cmdapply.go b/commands/live/apply/cmdapply.go index 2c5ea3e0c1..1dd81fd15a 100644 --- a/commands/live/apply/cmdapply.go +++ b/commands/live/apply/cmdapply.go @@ -20,12 +20,12 @@ import ( "os" "time" - alphaprinterstable "github.com/kptdev/kpt/internal/alpha/printers/table" "github.com/kptdev/kpt/internal/docs/generated/livedocs" - "github.com/kptdev/kpt/internal/util/argutil" - "github.com/kptdev/kpt/internal/util/strings" + argsutil "github.com/kptdev/kpt/pkg/lib/util/args" "github.com/kptdev/kpt/pkg/lib/util/cmdutil" + "github.com/kptdev/kpt/pkg/lib/util/strings" "github.com/kptdev/kpt/pkg/live" + alphaprinterstable "github.com/kptdev/kpt/pkg/printer/table" "github.com/kptdev/kpt/pkg/status" "github.com/spf13/cobra" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -174,7 +174,7 @@ func (r *Runner) runE(c *cobra.Command, args []string) error { path := args[0] var err error if args[0] != "-" { - path, err = argutil.ResolveSymlink(r.ctx, path) + path, err = argsutil.ResolveSymlink(r.ctx, path) if err != nil { return err } diff --git a/commands/live/destroy/cmddestroy.go b/commands/live/destroy/cmddestroy.go index bc274f2578..1381e217dc 100644 --- a/commands/live/destroy/cmddestroy.go +++ b/commands/live/destroy/cmddestroy.go @@ -20,8 +20,8 @@ import ( "os" "github.com/kptdev/kpt/internal/docs/generated/livedocs" - "github.com/kptdev/kpt/internal/util/argutil" - "github.com/kptdev/kpt/internal/util/strings" + argsutil "github.com/kptdev/kpt/pkg/lib/util/args" + "github.com/kptdev/kpt/pkg/lib/util/strings" "github.com/kptdev/kpt/pkg/live" "github.com/kptdev/kpt/pkg/status" "github.com/spf13/cobra" @@ -133,7 +133,7 @@ func (r *Runner) runE(c *cobra.Command, args []string) error { path := args[0] var err error if args[0] != "-" { - path, err = argutil.ResolveSymlink(r.ctx, path) + path, err = argsutil.ResolveSymlink(r.ctx, path) if err != nil { return err } diff --git a/commands/live/init/cmdliveinit.go b/commands/live/init/cmdliveinit.go index 8d3ff2c943..8ad6737d6b 100644 --- a/commands/live/init/cmdliveinit.go +++ b/commands/live/init/cmdliveinit.go @@ -26,14 +26,14 @@ import ( "time" "github.com/kptdev/kpt/internal/docs/generated/livedocs" - "github.com/kptdev/kpt/internal/pkg" - "github.com/kptdev/kpt/internal/types" - "github.com/kptdev/kpt/internal/util/attribution" - "github.com/kptdev/kpt/internal/util/pathutil" kptfilev1 "github.com/kptdev/kpt/pkg/api/kptfile/v1" rgfilev1alpha1 "github.com/kptdev/kpt/pkg/api/resourcegroup/v1alpha1" "github.com/kptdev/kpt/pkg/kptfile/kptfileutil" "github.com/kptdev/kpt/pkg/lib/errors" + "github.com/kptdev/kpt/pkg/lib/pkg" + "github.com/kptdev/kpt/pkg/lib/types" + "github.com/kptdev/kpt/pkg/lib/util/attribution" + "github.com/kptdev/kpt/pkg/lib/util/path" "github.com/kptdev/kpt/pkg/printer" "github.com/spf13/cobra" "k8s.io/cli-runtime/pkg/genericclioptions" @@ -140,7 +140,7 @@ func (r *Runner) runE(_ *cobra.Command, args []string) error { return errors.E(op, err) } - absPath, _, err := pathutil.ResolveAbsAndRelPaths(dir) + absPath, _, err := path.ResolveAbsAndRelPaths(dir) if err != nil { return err } diff --git a/commands/live/init/cmdliveinit_test.go b/commands/live/init/cmdliveinit_test.go index 49963969f4..7d79a68af7 100644 --- a/commands/live/init/cmdliveinit_test.go +++ b/commands/live/init/cmdliveinit_test.go @@ -21,11 +21,11 @@ import ( "testing" "time" - "github.com/kptdev/kpt/internal/pkg" "github.com/kptdev/kpt/internal/testutil" kptfilev1 "github.com/kptdev/kpt/pkg/api/kptfile/v1" rgfilev1alpha1 "github.com/kptdev/kpt/pkg/api/resourcegroup/v1alpha1" "github.com/kptdev/kpt/pkg/kptfile/kptfileutil" + "github.com/kptdev/kpt/pkg/lib/pkg" "github.com/kptdev/kpt/pkg/printer/fake" "github.com/stretchr/testify/assert" "k8s.io/cli-runtime/pkg/genericclioptions" diff --git a/commands/live/migrate/migratecmd.go b/commands/live/migrate/migratecmd.go index 616e228898..7e2af23bb7 100644 --- a/commands/live/migrate/migratecmd.go +++ b/commands/live/migrate/migratecmd.go @@ -25,13 +25,13 @@ import ( initialization "github.com/kptdev/kpt/commands/live/init" "github.com/kptdev/kpt/internal/docs/generated/livedocs" - "github.com/kptdev/kpt/internal/pkg" - "github.com/kptdev/kpt/internal/types" - "github.com/kptdev/kpt/internal/util/argutil" - "github.com/kptdev/kpt/internal/util/pathutil" rgfilev1alpha1 "github.com/kptdev/kpt/pkg/api/resourcegroup/v1alpha1" "github.com/kptdev/kpt/pkg/kptfile/kptfileutil" "github.com/kptdev/kpt/pkg/lib/errors" + "github.com/kptdev/kpt/pkg/lib/pkg" + "github.com/kptdev/kpt/pkg/lib/types" + argsutil "github.com/kptdev/kpt/pkg/lib/util/args" + "github.com/kptdev/kpt/pkg/lib/util/path" "github.com/kptdev/kpt/pkg/live" "github.com/spf13/cobra" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" @@ -251,7 +251,7 @@ func (mr *Runner) migrateObjs(rgInvClient inventory.Client, path := args[0] var err error if args[0] != "-" { - path, err = argutil.ResolveSymlink(mr.ctx, path) + path, err = argsutil.ResolveSymlink(mr.ctx, path) if err != nil { return err } @@ -363,7 +363,7 @@ func (mr *Runner) migrateKptfileToRG(args []string) error { klog.V(4).Infoln("attempting to migrate from Kptfile inventory") fmt.Fprint(mr.ioStreams.Out, " reading existing Kptfile...") if !mr.dryRun { - dir, _, err := pathutil.ResolveAbsAndRelPaths(args[0]) + dir, _, err := path.ResolveAbsAndRelPaths(args[0]) if err != nil { return err } @@ -459,7 +459,7 @@ func (mr *Runner) migrateCMToRG(stdinBytes []byte, args []string) error { func (mr *Runner) createRGfile(ctx context.Context, args []string, prevID string) error { fmt.Fprint(mr.ioStreams.Out, " creating ResourceGroup object file...") if !mr.dryRun { - dir, _, err := pathutil.ResolveAbsAndRelPaths(args[0]) + dir, _, err := path.ResolveAbsAndRelPaths(args[0]) if err != nil { return err } diff --git a/commands/live/migrate/migratecmd_test.go b/commands/live/migrate/migratecmd_test.go index b6dbadda80..1448beaeed 100644 --- a/commands/live/migrate/migratecmd_test.go +++ b/commands/live/migrate/migratecmd_test.go @@ -20,9 +20,9 @@ import ( "strings" "testing" - "github.com/kptdev/kpt/internal/pkg" rgfilev1alpha1 "github.com/kptdev/kpt/pkg/api/resourcegroup/v1alpha1" "github.com/kptdev/kpt/pkg/kptfile/kptfileutil" + "github.com/kptdev/kpt/pkg/lib/pkg" "github.com/kptdev/kpt/pkg/printer/fake" "github.com/stretchr/testify/assert" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" diff --git a/commands/live/status/cmdstatus.go b/commands/live/status/cmdstatus.go index c3e73c1b3e..ecb61bc4a6 100644 --- a/commands/live/status/cmdstatus.go +++ b/commands/live/status/cmdstatus.go @@ -19,7 +19,7 @@ import ( "os" "github.com/kptdev/kpt/internal/docs/generated/livedocs" - "github.com/kptdev/kpt/internal/util/argutil" + argsutil "github.com/kptdev/kpt/pkg/lib/util/args" "github.com/kptdev/kpt/pkg/live" kptstatus "github.com/kptdev/kpt/pkg/status" "github.com/spf13/cobra" @@ -74,7 +74,7 @@ func (rir *RGInventoryLoader) GetInvInfo(cmd *cobra.Command, args []string) (inv path := args[0] var err error if args[0] != "-" { - path, err = argutil.ResolveSymlink(rir.ctx, path) + path, err = argsutil.ResolveSymlink(rir.ctx, path) if err != nil { return nil, err } diff --git a/commands/live/status/fake-loader.go b/commands/live/status/fake-loader.go index 74c3b8c82d..90db0edca8 100644 --- a/commands/live/status/fake-loader.go +++ b/commands/live/status/fake-loader.go @@ -18,7 +18,7 @@ import ( "context" "os" - "github.com/kptdev/kpt/internal/util/argutil" + argsutil "github.com/kptdev/kpt/pkg/lib/util/args" "github.com/kptdev/kpt/pkg/live" "github.com/spf13/cobra" "k8s.io/kubectl/pkg/cmd/util" @@ -56,7 +56,7 @@ func (r *FakeLoader) GetInvInfo(cmd *cobra.Command, args []string) (inventory.In path := args[0] var err error if args[0] != "-" { - path, err = argutil.ResolveSymlink(r.ctx, path) + path, err = argsutil.ResolveSymlink(r.ctx, path) if err != nil { return nil, err } diff --git a/commands/pkg/diff/cmddiff.go b/commands/pkg/diff/cmddiff.go index f05fafd003..1d38397c49 100644 --- a/commands/pkg/diff/cmddiff.go +++ b/commands/pkg/diff/cmddiff.go @@ -19,11 +19,11 @@ import ( "os" "github.com/kptdev/kpt/internal/docs/generated/pkgdocs" - "github.com/kptdev/kpt/internal/pkg" - "github.com/kptdev/kpt/internal/util/argutil" - "github.com/kptdev/kpt/internal/util/diff" - "github.com/kptdev/kpt/internal/util/pathutil" + "github.com/kptdev/kpt/pkg/lib/pkg" + "github.com/kptdev/kpt/pkg/lib/pkg/diff" + argsutil "github.com/kptdev/kpt/pkg/lib/util/args" "github.com/kptdev/kpt/pkg/lib/util/cmdutil" + "github.com/kptdev/kpt/pkg/lib/util/path" "github.com/kptdev/kpt/pkg/printer" "github.com/spf13/cobra" "sigs.k8s.io/kustomize/kyaml/filesys" @@ -80,7 +80,7 @@ func (r *Runner) preRunE(_ *cobra.Command, args []string) error { args = append(args, pkg.CurDir) } dirVer := args[0] - dir, version, err := argutil.ParseDirVersion(dirVer) + dir, version, err := argsutil.ParseDirVersion(dirVer) if err != nil { return err } @@ -96,12 +96,12 @@ func (r *Runner) preRunE(_ *cobra.Command, args []string) error { r.DiffType = diff.Type(r.diffType) } - resolvedPath, err := argutil.ResolveSymlink(r.ctx, dir) + resolvedPath, err := argsutil.ResolveSymlink(r.ctx, dir) if err != nil { return err } - absResolvedPath, _, err := pathutil.ResolveAbsAndRelPaths(resolvedPath) + absResolvedPath, _, err := path.ResolveAbsAndRelPaths(resolvedPath) if err != nil { return err } diff --git a/commands/pkg/get/cmdget.go b/commands/pkg/get/cmdget.go index 03821c663e..0f9baea157 100644 --- a/commands/pkg/get/cmdget.go +++ b/commands/pkg/get/cmdget.go @@ -21,15 +21,15 @@ import ( "strings" docs "github.com/kptdev/kpt/internal/docs/generated/pkgdocs" - "github.com/kptdev/kpt/internal/pkg" - "github.com/kptdev/kpt/internal/types" - "github.com/kptdev/kpt/internal/util/argutil" - "github.com/kptdev/kpt/internal/util/get" - "github.com/kptdev/kpt/internal/util/pathutil" kptfilev1 "github.com/kptdev/kpt/pkg/api/kptfile/v1" "github.com/kptdev/kpt/pkg/lib/errors" + "github.com/kptdev/kpt/pkg/lib/pkg" + "github.com/kptdev/kpt/pkg/lib/types" + argsutil "github.com/kptdev/kpt/pkg/lib/util/args" "github.com/kptdev/kpt/pkg/lib/util/cmdutil" + "github.com/kptdev/kpt/pkg/lib/util/get" "github.com/kptdev/kpt/pkg/lib/util/parse" + "github.com/kptdev/kpt/pkg/lib/util/path" "github.com/spf13/cobra" "sigs.k8s.io/kustomize/kyaml/filesys" ) @@ -84,7 +84,7 @@ func (r *Runner) preRunE(_ *cobra.Command, args []string) error { } else if filepath.Clean(args[1]) != "." { _, err := os.Lstat(args[1]) if err == nil || os.IsExist(err) { - resolvedPath, err := argutil.ResolveSymlink(r.ctx, args[1]) + resolvedPath, err := argsutil.ResolveSymlink(r.ctx, args[1]) if err != nil { return errors.E(op, err) } @@ -97,7 +97,7 @@ func (r *Runner) preRunE(_ *cobra.Command, args []string) error { } r.Get.Git = &t.Git - absDestPath, _, err := pathutil.ResolveAbsAndRelPaths(t.Destination) + absDestPath, _, err := path.ResolveAbsAndRelPaths(t.Destination) if err != nil { return err } diff --git a/commands/pkg/init/cmdinit.go b/commands/pkg/init/cmdinit.go index 90b9afc38f..232b6b4da3 100644 --- a/commands/pkg/init/cmdinit.go +++ b/commands/pkg/init/cmdinit.go @@ -18,10 +18,10 @@ import ( "context" docs "github.com/kptdev/kpt/internal/docs/generated/pkgdocs" - "github.com/kptdev/kpt/internal/pkg" - "github.com/kptdev/kpt/internal/util/pathutil" "github.com/kptdev/kpt/pkg/kptpkg" + "github.com/kptdev/kpt/pkg/lib/pkg" "github.com/kptdev/kpt/pkg/lib/util/cmdutil" + "github.com/kptdev/kpt/pkg/lib/util/path" "github.com/spf13/cobra" "sigs.k8s.io/kustomize/kyaml/filesys" ) @@ -67,7 +67,7 @@ func (r *Runner) runE(_ *cobra.Command, args []string) error { args = append(args, pkg.CurDir) } - absPath, _, err := pathutil.ResolveAbsAndRelPaths(args[0]) + absPath, _, err := path.ResolveAbsAndRelPaths(args[0]) if err != nil { return err } diff --git a/commands/pkg/init/cmdinit_test.go b/commands/pkg/init/cmdinit_test.go index 9b6ee69611..8c1641c73f 100644 --- a/commands/pkg/init/cmdinit_test.go +++ b/commands/pkg/init/cmdinit_test.go @@ -21,10 +21,10 @@ import ( "testing" initialization "github.com/kptdev/kpt/commands/pkg/init" - "github.com/kptdev/kpt/internal/builtins" "github.com/kptdev/kpt/internal/testutil" - "github.com/kptdev/kpt/internal/util/man" - builtintypes "github.com/kptdev/kpt/pkg/lib/builtins/builtintypes" + "github.com/kptdev/kpt/pkg/lib/builtins" + "github.com/kptdev/kpt/pkg/lib/builtins/builtintypes" + "github.com/kptdev/kpt/pkg/lib/util/man" "github.com/kptdev/kpt/pkg/printer/fake" "github.com/stretchr/testify/assert" ) diff --git a/commands/pkg/update/cmdupdate.go b/commands/pkg/update/cmdupdate.go index daa39b2f50..133101fc25 100644 --- a/commands/pkg/update/cmdupdate.go +++ b/commands/pkg/update/cmdupdate.go @@ -22,14 +22,14 @@ import ( "strings" docs "github.com/kptdev/kpt/internal/docs/generated/pkgdocs" - "github.com/kptdev/kpt/internal/pkg" - "github.com/kptdev/kpt/internal/types" - "github.com/kptdev/kpt/internal/util/argutil" - "github.com/kptdev/kpt/internal/util/pathutil" - "github.com/kptdev/kpt/internal/util/update" kptfilev1 "github.com/kptdev/kpt/pkg/api/kptfile/v1" "github.com/kptdev/kpt/pkg/lib/errors" + "github.com/kptdev/kpt/pkg/lib/pkg" + "github.com/kptdev/kpt/pkg/lib/types" + "github.com/kptdev/kpt/pkg/lib/update" + argsutil "github.com/kptdev/kpt/pkg/lib/util/args" "github.com/kptdev/kpt/pkg/lib/util/cmdutil" + "github.com/kptdev/kpt/pkg/lib/util/path" "github.com/spf13/cobra" "sigs.k8s.io/kustomize/kyaml/filesys" ) @@ -91,11 +91,11 @@ func (r *Runner) preRunE(_ *cobra.Command, args []string) error { return errors.E(op, errors.InvalidParam, fmt.Errorf("at most 1 version permitted")) } - resolvedPath, err := argutil.ResolveSymlink(r.ctx, parts[0]) + resolvedPath, err := argsutil.ResolveSymlink(r.ctx, parts[0]) if err != nil { return err } - absResolvedPath, _, err := pathutil.ResolveAbsAndRelPaths(resolvedPath) + absResolvedPath, _, err := path.ResolveAbsAndRelPaths(resolvedPath) if err != nil { return err } diff --git a/internal/pkg/testing/helpers.go b/internal/pkg/testing/helpers.go deleted file mode 100644 index d91358f3e7..0000000000 --- a/internal/pkg/testing/helpers.go +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2021 The kpt Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package testing - -import ( - "testing" - - "github.com/kptdev/kpt/internal/pkg" - "github.com/kptdev/kpt/internal/util/pathutil" - "github.com/stretchr/testify/assert" - "sigs.k8s.io/kustomize/kyaml/filesys" -) - -// CreatePkgOrFail creates a new package from the provided path. Unlike the -// pkg.New function, it fails the test instead of returning an error. -func CreatePkgOrFail(t *testing.T, path string) *pkg.Pkg { - absPath, _, err := pathutil.ResolveAbsAndRelPaths(path) - if !assert.NoError(t, err) { - t.FailNow() - } - p, err := pkg.New(filesys.FileSystemOrOnDisk{}, absPath) - if !assert.NoError(t, err) { - t.FailNow() - } - return p -} diff --git a/internal/testutil/setup_manager.go b/internal/testutil/setup_manager.go index 27a546852c..66031304b0 100644 --- a/internal/testutil/setup_manager.go +++ b/internal/testutil/setup_manager.go @@ -22,8 +22,8 @@ import ( "github.com/kptdev/kpt/internal/gitutil" "github.com/kptdev/kpt/internal/testutil/pkgbuilder" - "github.com/kptdev/kpt/internal/util/get" kptfilev1 "github.com/kptdev/kpt/pkg/api/kptfile/v1" + "github.com/kptdev/kpt/pkg/lib/util/get" "github.com/kptdev/kpt/pkg/printer/fake" "github.com/stretchr/testify/assert" "sigs.k8s.io/kustomize/kyaml/yaml" diff --git a/internal/testutil/testutil.go b/internal/testutil/testutil.go index 6d7040b7f4..c15c81ecf0 100644 --- a/internal/testutil/testutil.go +++ b/internal/testutil/testutil.go @@ -25,11 +25,13 @@ import ( "strings" "testing" - "github.com/kptdev/kpt/internal/gitutil" - "github.com/kptdev/kpt/internal/util/git" + git2 "github.com/kptdev/kpt/internal/gitutil" kptfilev1 "github.com/kptdev/kpt/pkg/api/kptfile/v1" "github.com/kptdev/kpt/pkg/kptfile/kptfileutil" + "github.com/kptdev/kpt/pkg/lib/pkg" "github.com/kptdev/kpt/pkg/lib/util/addmergecomment" + "github.com/kptdev/kpt/pkg/lib/util/git" + pathutil "github.com/kptdev/kpt/pkg/lib/util/path" "github.com/kptdev/kpt/pkg/printer/fake" "github.com/philopon/go-toposort" "github.com/stretchr/testify/assert" @@ -434,7 +436,7 @@ func SetupWorkspace(t *testing.T) (*TestWorkspace, func()) { err := w.SetupTestWorkspace() assert.NoError(t, err) - gr, err := gitutil.NewLocalGitRunner(w.WorkspaceDirectory) + gr, err := git2.NewLocalGitRunner(w.WorkspaceDirectory) if !assert.NoError(t, err) { t.FailNow() } @@ -461,7 +463,7 @@ func AddKptfileToWorkspace(t *testing.T, w *TestWorkspace, kf *kptfilev1.KptFile t.FailNow() } - gitRunner, err := gitutil.NewLocalGitRunner(w.WorkspaceDirectory) + gitRunner, err := git2.NewLocalGitRunner(w.WorkspaceDirectory) if !assert.NoError(t, err) { t.FailNow() } @@ -871,7 +873,7 @@ func ConfigureTestKptCache(m *testing.M) int { defer func() { _ = os.RemoveAll(cacheDir) }() - if err := os.Setenv(gitutil.RepoCacheDirEnv, cacheDir); err != nil { + if err := os.Setenv(git2.RepoCacheDirEnv, cacheDir); err != nil { panic(fmt.Errorf("error setting repo cache env variable: %w", err)) } return m.Run() @@ -908,3 +910,17 @@ func (ri *ReposInfo) ResolveCommitIndex(repoRef string, index int) (string, bool } return commits[index], true } + +// CreatePkgOrFail creates a new package from the provided path. Unlike the +// pkg.New function, it fails the test instead of returning an error. +func CreatePkgOrFail(t *testing.T, path string) *pkg.Pkg { + absPath, _, err := pathutil.ResolveAbsAndRelPaths(path) + if !assert.NoError(t, err) { + t.FailNow() + } + p, err := pkg.New(filesys.FileSystemOrOnDisk{}, absPath) + if !assert.NoError(t, err) { + t.FailNow() + } + return p +} diff --git a/internal/util/httputil/httputil.go b/internal/util/httputil/httputil.go deleted file mode 100644 index e59674d680..0000000000 --- a/internal/util/httputil/httputil.go +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2021 The kpt Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package httputil - -import ( - "io" - "net/http" -) - -// FetchContent fetches the content from the input url -func FetchContent(url string) (string, error) { - req, err := http.NewRequest("GET", url, nil) - if err != nil { - return "", err - } - res, err := http.DefaultClient.Do(req) - if err != nil { - return "", err - } - defer res.Body.Close() - body, err := io.ReadAll(res.Body) - if err != nil { - return "", err - } - return string(body), nil -} diff --git a/internal/util/merge/merge3.go b/internal/util/merge/merge3.go deleted file mode 100644 index 4d7c2d9237..0000000000 --- a/internal/util/merge/merge3.go +++ /dev/null @@ -1,369 +0,0 @@ -// Copyright 2020 The kpt Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package merge - -import ( - "path/filepath" - "strings" - - "github.com/kptdev/kpt/internal/util/attribution" - kptfilev1 "github.com/kptdev/kpt/pkg/api/kptfile/v1" - "sigs.k8s.io/kustomize/kyaml/kio" - "sigs.k8s.io/kustomize/kyaml/kio/filters" - "sigs.k8s.io/kustomize/kyaml/kio/kioutil" - "sigs.k8s.io/kustomize/kyaml/pathutil" - "sigs.k8s.io/kustomize/kyaml/resid" - "sigs.k8s.io/kustomize/kyaml/yaml" -) - -const ( - mergeSourceAnnotation = "config.kubernetes.io/merge-source" - mergeSourceOriginal = "original" - mergeSourceUpdated = "updated" - mergeSourceDest = "dest" - MergeCommentPrefix = "kpt-merge:" -) - -// Merge3 performs a 3-way merge on the original, upstream and -// destination packages. It provides support for doing this only for -// the parent package and ignore any subpackages. Whenever the boundaries -// of a package differs between original, upstream and destination, the -// boundaries in destination will be used. -type Merge3 struct { - OriginalPath string - UpdatedPath string - DestPath string - MatchFilesGlob []string - MergeOnPath bool - IncludeSubPackages bool -} - -func (m Merge3) Merge() error { - // If subpackages are not included when doing the merge, first - // look up the known subpackages in destination so we can make sure - // those are ignored when reading files from original and updated. - var relPaths []string - if !m.IncludeSubPackages { - var err error - relPaths, err = m.findExclusions() - if err != nil { - return err - } - } - - var inputs []kio.Reader - dest := &kio.LocalPackageReadWriter{ - PackagePath: m.DestPath, - MatchFilesGlob: m.MatchFilesGlob, - SetAnnotations: map[string]string{mergeSourceAnnotation: mergeSourceDest}, - IncludeSubpackages: m.IncludeSubPackages, - PackageFileName: kptfilev1.KptFileName, - PreserveSeqIndent: true, - WrapBareSeqNode: true, - } - inputs = append(inputs, dest) - - // Read the original package - inputs = append(inputs, PruningLocalPackageReader{ - LocalPackageReader: kio.LocalPackageReader{ - PackagePath: m.OriginalPath, - MatchFilesGlob: m.MatchFilesGlob, - SetAnnotations: map[string]string{mergeSourceAnnotation: mergeSourceOriginal}, - IncludeSubpackages: m.IncludeSubPackages, - PackageFileName: kptfilev1.KptFileName, - PreserveSeqIndent: true, - WrapBareSeqNode: true, - }, - Exclusions: relPaths, - }) - - // Read the updated package - inputs = append(inputs, PruningLocalPackageReader{ - LocalPackageReader: kio.LocalPackageReader{ - PackagePath: m.UpdatedPath, - MatchFilesGlob: m.MatchFilesGlob, - SetAnnotations: map[string]string{mergeSourceAnnotation: mergeSourceUpdated}, - IncludeSubpackages: m.IncludeSubPackages, - PackageFileName: kptfilev1.KptFileName, - PreserveSeqIndent: true, - WrapBareSeqNode: true, - }, - Exclusions: relPaths, - }) - - rmMatcher := ResourceMergeMatcher{MergeOnPath: m.MergeOnPath} - resourceHandler := resourceHandler{} - kyamlMerge := filters.Merge3{ - Matcher: &rmMatcher, - Handler: &resourceHandler, - } - - return kio.Pipeline{ - Inputs: inputs, - Filters: []kio.Filter{kyamlMerge}, - Outputs: []kio.Writer{dest}, - }.Execute() -} - -func (m Merge3) findExclusions() ([]string, error) { - var relPaths []string - paths, err := pathutil.DirsWithFile(m.DestPath, kptfilev1.KptFileName, true) - if err != nil { - return relPaths, err - } - - for _, p := range paths { - rel, err := filepath.Rel(m.DestPath, p) - if err != nil { - return relPaths, err - } - if rel == "." { - continue - } - relPaths = append(relPaths, rel) - } - return relPaths, nil -} - -// PruningLocalPackageReader implements the Reader interface. It is similar -// to the LocalPackageReader but allows for exclusion of subdirectories. -type PruningLocalPackageReader struct { - LocalPackageReader kio.LocalPackageReader - Exclusions []string -} - -func (p PruningLocalPackageReader) Read() ([]*yaml.RNode, error) { - // Delegate reading the resources to the LocalPackageReader. - nodes, err := p.LocalPackageReader.Read() - if err != nil { - return nil, err - } - - // Exclude any resources that exist underneath an excluded path. - var filteredNodes []*yaml.RNode - for _, node := range nodes { - if err := kioutil.CopyLegacyAnnotations(node); err != nil { - return nil, err - } - n, err := node.Pipe(yaml.GetAnnotation(kioutil.PathAnnotation)) - if err != nil { - return nil, err - } - path := n.YNode().Value - if p.isExcluded(path) { - continue - } - filteredNodes = append(filteredNodes, node) - } - return filteredNodes, nil -} - -func (p PruningLocalPackageReader) isExcluded(path string) bool { - for _, e := range p.Exclusions { - if strings.HasPrefix(path, e) { - return true - } - } - return false -} - -type ResourceMergeMatcher struct { - MergeOnPath bool -} - -// IsSameResource determines if 2 resources are same to be merged by matching GKNN+filepath -// Group, Kind are derived from resource metadata directly, Namespace and Name are derived -// from merge comment which is of format "kpt-merge: namespace/name", if the merge comment -// is not present, then it falls back to Namespace and Name on the resource meta -func (rm *ResourceMergeMatcher) IsSameResource(node1, node2 *yaml.RNode) bool { - if node1 == nil || node2 == nil { - return false - } - - if err := kioutil.CopyLegacyAnnotations(node1); err != nil { - return false - } - if err := kioutil.CopyLegacyAnnotations(node2); err != nil { - return false - } - - meta1, err := node1.GetMeta() - if err != nil { - return false - } - - meta2, err := node2.GetMeta() - if err != nil { - return false - } - - if resolveGroup(meta1) != resolveGroup(meta2) { - return false - } - - if meta1.Kind != meta2.Kind { - return false - } - - if resolveName(meta1, metadataComment(node1)) != resolveName(meta2, metadataComment(node2)) { - return false - } - - if resolveNamespace(meta1, metadataComment(node1)) != resolveNamespace(meta2, metadataComment(node2)) { - return false - } - - if rm.MergeOnPath { - // directories may contain multiple copies of a resource with the same - // name, namespace, apiVersion and kind -- e.g. kustomize patches, or - // multiple environments - // mergeOnPath configures the merge logic to use the path as part of the - // resource key - if meta1.Annotations[kioutil.PathAnnotation] != meta2.Annotations[kioutil.PathAnnotation] { - return false - } - } - return true -} - -// resolveGroup resolves the group of a resource from ResourceMeta -func resolveGroup(meta yaml.ResourceMeta) string { - group, _ := resid.ParseGroupVersion(meta.APIVersion) - return group -} - -// resolveNamespace resolves the namespace which should be used for merging resources -// uses namespace from comment on metadata field if present, falls back to resource namespace -func resolveNamespace(meta yaml.ResourceMeta, metadataComment string) string { - nsName := NsAndNameForMerge(metadataComment) - if nsName == nil { - return meta.Namespace - } - return nsName[0] -} - -// resolveName resolves the name which should be used for merging resources -// uses name from comment on metadata field if present, falls back to resource name -func resolveName(meta yaml.ResourceMeta, metadataComment string) string { - nsName := NsAndNameForMerge(metadataComment) - if nsName == nil { - return meta.Name - } - return nsName[1] -} - -// NsAndNameForMerge returns the namespace and name for merge -// from the line comment on the metadata field -// e.g. metadata: # kpt-merge: default/foo returns [default, foo] -func NsAndNameForMerge(metadataComment string) []string { - comment := strings.TrimPrefix(metadataComment, "#") - comment = strings.TrimSpace(comment) - if !strings.HasPrefix(comment, MergeCommentPrefix) { - return nil - } - comment = strings.TrimPrefix(comment, MergeCommentPrefix) - nsAndName := strings.SplitN(strings.TrimSpace(comment), "/", 2) - if len(nsAndName) != 2 { - return nil - } - return nsAndName -} - -// metadataComment returns the line comment on the metadata field of input RNode -func metadataComment(node *yaml.RNode) string { - mf := node.Field(yaml.MetadataField) - if mf.IsNilOrEmpty() { - return "" - } - return mf.Key.YNode().LineComment -} - -// resourceHandler is an implementation of the ResourceHandler interface from -// kyaml. It is used to decide how a resource should be handled during the -// 3-way merge. This differs from the default implementation in that if a -// resource is deleted from upstream, it will only be deleted from local if -// there is no diff between origin and local. -type resourceHandler struct { - keptResources []*yaml.RNode -} - -func (r *resourceHandler) Handle(origin, upstream, local *yaml.RNode) (filters.ResourceMergeStrategy, error) { - var strategy filters.ResourceMergeStrategy - switch { - // Keep the resource if added locally. - case origin == nil && upstream == nil && local != nil: - strategy = filters.KeepDest - // Add the resource if added in upstream. - case origin == nil && upstream != nil && local == nil: - strategy = filters.KeepUpdated - // Do not re-add the resource if deleted from both upstream and local - case upstream == nil && local == nil: - strategy = filters.Skip - // If deleted from upstream, only delete if local fork does not have changes. - case origin != nil && upstream == nil: - equal, err := r.equals(origin, local) - if err != nil { - return strategy, err - } - if equal { - strategy = filters.Skip - } else { - r.keptResources = append(r.keptResources, local) - strategy = filters.KeepDest - } - // Do not re-add if deleted from local. - case origin != nil && local == nil: - strategy = filters.Skip - default: - strategy = filters.Merge - } - return strategy, nil -} - -func (*resourceHandler) equals(r1, r2 *yaml.RNode) (bool, error) { - // We need to create new copies of the resources since we need to - // mutate them before comparing them. - r1Clone, err := yaml.Parse(r1.MustString()) - if err != nil { - return false, err - } - r2Clone, err := yaml.Parse(r2.MustString()) - if err != nil { - return false, err - } - - // The resources include annotations with information used during the merge - // process. We need to remove those before comparing the resources. - if err := stripKyamlAnnos(r1Clone); err != nil { - return false, err - } - if err := stripKyamlAnnos(r2Clone); err != nil { - return false, err - } - - return r1Clone.MustString() == r2Clone.MustString(), nil -} - -func stripKyamlAnnos(n *yaml.RNode) error { - for _, a := range []string{mergeSourceAnnotation, kioutil.PathAnnotation, kioutil.IndexAnnotation, - kioutil.LegacyPathAnnotation, kioutil.LegacyIndexAnnotation, // nolint:staticcheck - kioutil.InternalAnnotationsMigrationResourceIDAnnotation, attribution.CNRMMetricsAnnotation} { - err := n.PipeE(yaml.ClearAnnotation(a)) - if err != nil { - return err - } - } - return nil -} diff --git a/internal/util/merge/merge3_test.go b/internal/util/merge/merge3_test.go deleted file mode 100644 index 8bf2c4a056..0000000000 --- a/internal/util/merge/merge3_test.go +++ /dev/null @@ -1,635 +0,0 @@ -// Copyright 2020 The kpt Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package merge_test - -import ( - "os" - "path/filepath" - "strings" - "testing" - - "github.com/kptdev/kpt/internal/testutil" - "github.com/kptdev/kpt/internal/testutil/pkgbuilder" - "github.com/kptdev/kpt/internal/util/merge" - "github.com/stretchr/testify/assert" - "sigs.k8s.io/kustomize/kyaml/copyutil" - "sigs.k8s.io/kustomize/kyaml/yaml" -) - -func TestMerge3_Nested_packages(t *testing.T) { - annotationSetter := yaml.SetAnnotation("foo", "bar") - labelSetter := yaml.SetLabel("bar", "foo") - - testCases := []struct { - name string - includeSubPackages bool - original *pkgbuilder.RootPkg - upstream *pkgbuilder.RootPkg - local *pkgbuilder.RootPkg - expected *pkgbuilder.RootPkg - }{ - { - name: "subpackages are merged if included", - includeSubPackages: true, - original: createPkg(), - upstream: createPkg(annotationSetter), - local: createPkg(labelSetter), - expected: createPkg(labelSetter, annotationSetter), - }, - { - name: "subpackages are not merged if not included", - includeSubPackages: false, - original: createPkg(), - upstream: createPkg(annotationSetter), - local: createPkg(labelSetter), - expected: createPkgMultipleMutators( - []yaml.Filter{ - labelSetter, - annotationSetter, - }, - []yaml.Filter{ - labelSetter, - }, - ), - }, - { - name: "local copy defines the package boundaries if different from upstream", - includeSubPackages: false, - original: pkgbuilder.NewRootPkg(). - WithKptfile(). - WithResource(pkgbuilder.DeploymentResource). - WithSubPackages( - pkgbuilder.NewSubPkg("a"). - WithKptfile(). - WithResource(pkgbuilder.DeploymentResource), - ), - upstream: pkgbuilder.NewRootPkg(). - WithKptfile(). - WithResource(pkgbuilder.DeploymentResource, annotationSetter). - WithSubPackages( - pkgbuilder.NewSubPkg("a"). - WithResource(pkgbuilder.DeploymentResource, annotationSetter), - ), - local: pkgbuilder.NewRootPkg(). - WithKptfile(). - WithResource(pkgbuilder.DeploymentResource, labelSetter). - WithSubPackages( - pkgbuilder.NewSubPkg("a"). - WithKptfile(). - WithResource(pkgbuilder.DeploymentResource, labelSetter), - ), - expected: pkgbuilder.NewRootPkg(). - WithKptfile(). - WithResource(pkgbuilder.DeploymentResource, labelSetter, annotationSetter). - WithSubPackages( - pkgbuilder.NewSubPkg("a"). - WithKptfile(). - WithResource(pkgbuilder.DeploymentResource, labelSetter), - ), - }, - { - name: "upstream changes not included if in a different package", - includeSubPackages: false, - original: pkgbuilder.NewRootPkg(). - WithKptfile(). - WithResource(pkgbuilder.DeploymentResource). - WithSubPackages( - pkgbuilder.NewSubPkg("a"). - WithKptfile(). - WithResource(pkgbuilder.DeploymentResource), - ), - upstream: pkgbuilder.NewRootPkg(). - WithKptfile(). - WithResource(pkgbuilder.DeploymentResource, annotationSetter). - WithSubPackages( - pkgbuilder.NewSubPkg("a"). - WithKptfile(). - WithResource(pkgbuilder.DeploymentResource, annotationSetter), - ), - local: pkgbuilder.NewRootPkg(). - WithKptfile(). - WithResource(pkgbuilder.DeploymentResource, labelSetter). - WithSubPackages( - pkgbuilder.NewSubPkg("a"). // No Kptfile - WithResource(pkgbuilder.DeploymentResource, labelSetter), - ), - expected: pkgbuilder.NewRootPkg(). - WithKptfile(). - WithResource(pkgbuilder.DeploymentResource, labelSetter, annotationSetter). - WithSubPackages( - pkgbuilder.NewSubPkg("a"). - WithResource(pkgbuilder.DeploymentResource, labelSetter), - ), - }, - } - - for i := range testCases { - test := testCases[i] - t.Run(test.name, func(t *testing.T) { - original := test.original.ExpandPkg(t, testutil.EmptyReposInfo) - updated := test.upstream.ExpandPkg(t, testutil.EmptyReposInfo) - local := test.local.ExpandPkg(t, testutil.EmptyReposInfo) - expected := test.expected.ExpandPkg(t, testutil.EmptyReposInfo) - err := merge.Merge3{ - OriginalPath: original, - UpdatedPath: updated, - DestPath: local, - MergeOnPath: true, - IncludeSubPackages: test.includeSubPackages, - }.Merge() - if !assert.NoError(t, err) { - t.FailNow() - } - - diffs, err := copyutil.Diff(local, expected) - if !assert.NoError(t, err) { - t.FailNow() - } - - if !assert.Empty(t, diffs.List()) { - t.FailNow() - } - }) - } -} - -func createPkg(mutators ...yaml.Filter) *pkgbuilder.RootPkg { - return createPkgMultipleMutators(mutators, mutators) -} - -func createPkgMultipleMutators(packageMutators, subPackageMutators []yaml.Filter) *pkgbuilder.RootPkg { - return pkgbuilder.NewRootPkg(). - WithKptfile(). - WithResource(pkgbuilder.DeploymentResource, packageMutators...). - WithSubPackages( - pkgbuilder.NewSubPkg("a"). - WithKptfile(). - WithResource(pkgbuilder.DeploymentResource, subPackageMutators...), - pkgbuilder.NewSubPkg("b"). - WithResource(pkgbuilder.DeploymentResource, packageMutators...). - WithSubPackages( - pkgbuilder.NewSubPkg("c"). - WithKptfile(). - WithResource(pkgbuilder.DeploymentResource, subPackageMutators...), - ), - ) -} - -func TestMerge3_Merge_path(t *testing.T) { - testCases := map[string]struct { - origin string - update string - local string - expected string - errMsg string - }{ - `Most common: add namespace and name-prefix on local, merge upstream changes`: { - origin: ` -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-deployment -spec: - replicas: 3`, - update: ` -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-deployment -spec: - replicas: 4`, - local: ` -apiVersion: apps/v1 -kind: Deployment -metadata: # kpt-merge: /nginx-deployment - name: dev-nginx-deployment - namespace: my-space -spec: - replicas: 3 -`, - expected: ` -apiVersion: apps/v1 -kind: Deployment -metadata: # kpt-merge: /nginx-deployment - name: dev-nginx-deployment - namespace: my-space -spec: - replicas: 4 -`}, - - `Add namespace and name-prefix on local manually without adding annotations, adds new resource`: { - origin: ` -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-deployment -spec: - replicas: 3`, - update: ` -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-deployment -spec: - replicas: 4`, - local: ` -apiVersion: apps/v1 -kind: Deployment -metadata: - name: dev-nginx-deployment - namespace: my-space -spec: - replicas: 3 -`, - expected: ` -apiVersion: apps/v1 -kind: Deployment -metadata: - name: dev-nginx-deployment - namespace: my-space -spec: - replicas: 3 -`}, - - `Conflict: User fetches package, copies a resource in same file, adds different name suffix`: { - origin: ` -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-deployment -spec: - replicas: 3`, - update: ` -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-deployment -spec: - replicas: 4`, - local: ` -apiVersion: apps/v1 -kind: Deployment -metadata: # kpt-merge: default/nginx-deployment - name: nginx-deployment-1 - namespace: my-space -spec: - replicas: 3 ---- -apiVersion: apps/v1 -kind: Deployment -metadata: # kpt-merge: default/nginx-deployment - name: nginx-deployment-2 - namespace: my-space -spec: - replicas: 3 -`, - errMsg: `found duplicate "local" resources in file "f1.yaml"`}, - - `Publisher changes name in upstream but want to maintain original identity, no local customizations, fetch upstream changes`: { - origin: ` -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-deployment -spec: - replicas: 3`, - update: ` -apiVersion: apps/v1 -kind: Deployment -metadata: # kpt-merge: /nginx-deployment - name: nginx-deployment-new -spec: - replicas: 4`, - local: ` -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-deployment -spec: - replicas: 3 -`, - expected: ` -apiVersion: apps/v1 -kind: Deployment -metadata: # kpt-merge: /nginx-deployment - name: nginx-deployment-new -spec: - replicas: 4 -`}, - - `Publisher changes name in upstream but want to maintain original identity, consumer adds name-prefix on local, fetch upstream changes`: { - origin: ` -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-deployment -spec: - replicas: 3`, - update: ` -apiVersion: apps/v1 -kind: Deployment -metadata: # kpt-merge: default/nginx-deployment - name: nginx-deployment-new -spec: - replicas: 4`, - local: ` -apiVersion: apps/v1 -kind: Deployment -metadata: # kpt-merge: default/nginx-deployment - name: dev-nginx-deployment - namespace: my-space -spec: - replicas: 3 -`, - expected: ` -apiVersion: apps/v1 -kind: Deployment -metadata: # kpt-merge: default/nginx-deployment - name: nginx-deployment-new - namespace: my-space -spec: - replicas: 4 -`}, - - `Publisher changes name in upstream but don't want to maintain original identity which is equivalent -to delete existing resource and add new one, consumer adds name-prefix on local`: { - origin: ` -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-deployment -spec: - replicas: 3`, - update: ` -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-deployment-new -spec: - replicas: 4`, - local: ` -apiVersion: apps/v1 -kind: Deployment -metadata: # kpt-merge: /nginx-deployment - name: dev-nginx-deployment - namespace: my-space -spec: - replicas: 3 -`, - expected: ` -apiVersion: apps/v1 -kind: Deployment -metadata: # kpt-merge: /nginx-deployment - name: dev-nginx-deployment - namespace: my-space -spec: - replicas: 3 ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-deployment-new -spec: - replicas: 4 -`}, - - `Publisher changes name multiple times in upstream but maintains original identity, no local customizations, -fetch upstream changes`: { - origin: ` -apiVersion: apps/v1 -kind: Deployment -metadata: # kpt-merge: default/nginx-deployment - name: nginx-deployment-new -spec: - replicas: 4`, - update: ` -apiVersion: apps/v1 -kind: Deployment -metadata: # kpt-merge: default/nginx-deployment - name: nginx-deployment-new-again -spec: - replicas: 5`, - local: ` -apiVersion: apps/v1 -kind: Deployment -metadata: # kpt-merge: default/nginx-deployment - name: nginx-deployment-new -spec: - replicas: 5 -`, - expected: ` -apiVersion: apps/v1 -kind: Deployment -metadata: # kpt-merge: default/nginx-deployment - name: nginx-deployment-new-again -spec: - replicas: 5 -`}, - - `Publisher changes name multiple times in upstream but maintains original identity, consumer adds name-prefix -on local, fetch upstream changes`: { - origin: ` -apiVersion: apps/v1 -kind: Deployment -metadata: # kpt-merge: default/nginx-deployment - name: nginx-deployment-new -spec: - replicas: 4`, - update: ` -apiVersion: apps/v1 -kind: Deployment -metadata: # kpt-merge: default/nginx-deployment - name: nginx-deployment-new-again -spec: - replicas: 5`, - local: ` -apiVersion: apps/v1 -kind: Deployment -metadata: # kpt-merge: default/nginx-deployment - name: dev-nginx-deployment - namespace: my-space -spec: - replicas: 5 -`, - expected: ` -apiVersion: apps/v1 -kind: Deployment -metadata: # kpt-merge: default/nginx-deployment - name: nginx-deployment-new-again - namespace: my-space -spec: - replicas: 5 -`}, - `Publisher adds metadata.annotations in upstream in a non-identity kustomization resource, consumer adds changes to resource body -on local, fetch upstream changes`: { - origin: ` -apiVersion: kustomize.config.k8s.io/v1beta1 -metadata: - labels: - color: blue -commonLabels: - app: dev`, - update: ` -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization -metadata: - labels: - color: blue - annotations: - id.example.org: abcd -commonLabels: - app: dev`, - local: ` -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization -metadata: - labels: - color: blue -commonLabels: - app: dev - tier: backend -`, - expected: ` -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization -metadata: - labels: - color: blue - annotations: - id.example.org: abcd -commonLabels: - app: dev - tier: backend -`}, - `Publisher adds commonLabels in upstream in a non-identity kustomization resource, consumer adds changes to resource body -on local, fetch upstream changes`: { - origin: ` -commonLabels: - app: dev`, - update: ` -commonLabels: - tier: backend - app: dev`, - local: ` -commonLabels: - app: dev - tier: backend - db: mysql -`, - expected: ` -commonLabels: - app: dev - tier: backend - db: mysql -`}, - - `Version changes are just like any other changes`: { - origin: ` -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-deployment -spec: - replicas: 3`, - update: ` -apiVersion: apps/v2 -kind: Deployment -metadata: - name: nginx-deployment -spec: - replicas: 4`, - local: ` -apiVersion: apps/v1 -kind: Deployment -metadata: - name: nginx-deployment -spec: - replicas: 3 -`, - expected: ` -apiVersion: apps/v2 -kind: Deployment -metadata: - name: nginx-deployment -spec: - replicas: 4 -`}, - } - - for tn, tc := range testCases { - t.Run(tn, func(t *testing.T) { - // setup the local directory - dir := t.TempDir() - - err := os.MkdirAll(filepath.Join(dir, "localDir"), 0700) - if !assert.NoError(t, err) { - t.FailNow() - } - - err = os.MkdirAll(filepath.Join(dir, "updatedDir"), 0700) - if !assert.NoError(t, err) { - t.FailNow() - } - - err = os.MkdirAll(filepath.Join(dir, "originalDir"), 0700) - if !assert.NoError(t, err) { - t.FailNow() - } - - err = os.WriteFile(filepath.Join(dir, "originalDir", "f1.yaml"), []byte(strings.TrimSpace(tc.origin)), 0700) - if !assert.NoError(t, err) { - t.FailNow() - } - - err = os.WriteFile(filepath.Join(dir, "updatedDir", "f1.yaml"), []byte(strings.TrimSpace(tc.update)), 0700) - if !assert.NoError(t, err) { - t.FailNow() - } - - err = os.WriteFile(filepath.Join(dir, "localDir", "f1.yaml"), []byte(strings.TrimSpace(tc.local)), 0700) - if !assert.NoError(t, err) { - t.FailNow() - } - - err = merge.Merge3{ - OriginalPath: filepath.Join(dir, "originalDir"), - UpdatedPath: filepath.Join(dir, "updatedDir"), - DestPath: filepath.Join(dir, "localDir"), - MergeOnPath: true, - }.Merge() - if tc.errMsg == "" { - if !assert.NoError(t, err) { - t.FailNow() - } - } else { - if !assert.Error(t, err) { - t.FailNow() - } - if !assert.Contains(t, err.Error(), tc.errMsg) { - t.FailNow() - } - return - } - - b, err := os.ReadFile(filepath.Join(dir, "localDir", "f1.yaml")) - if !assert.NoError(t, err) { - t.FailNow() - } - if !assert.Equal(t, strings.TrimSpace(tc.expected), strings.TrimSpace(string(b))) { - t.FailNow() - } - }) - } -} diff --git a/internal/util/update/update.go b/internal/util/update/update.go deleted file mode 100644 index 68badccc58..0000000000 --- a/internal/util/update/update.go +++ /dev/null @@ -1,493 +0,0 @@ -// Copyright 2019,2026 The kpt Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Package update contains libraries for updating packages. -package update - -import ( - "context" - "fmt" - "os" - "path" - "path/filepath" - "strings" - - "github.com/kptdev/kpt/internal/gitutil" - "github.com/kptdev/kpt/internal/pkg" - "github.com/kptdev/kpt/internal/types" - "github.com/kptdev/kpt/internal/util/fetch" - "github.com/kptdev/kpt/internal/util/git" - "github.com/kptdev/kpt/internal/util/pkgutil" - "github.com/kptdev/kpt/internal/util/stack" - kptfilev1 "github.com/kptdev/kpt/pkg/api/kptfile/v1" - "github.com/kptdev/kpt/pkg/kptfile/kptfileutil" - "github.com/kptdev/kpt/pkg/lib/errors" - updatetypes "github.com/kptdev/kpt/pkg/lib/update/updatetypes" - "github.com/kptdev/kpt/pkg/lib/util/addmergecomment" - "github.com/kptdev/kpt/pkg/printer" - "sigs.k8s.io/kustomize/kyaml/copyutil" - "sigs.k8s.io/kustomize/kyaml/filesys" -) - -// PkgNotGitRepoError is the error type returned if the package being updated is not inside -// a git repository. -type PkgNotGitRepoError struct { - Path types.UniquePath -} - -func (p *PkgNotGitRepoError) Error() string { - return fmt.Sprintf("package %q is not a git repository", p.Path.String()) -} - -// PkgRepoDirtyError is the error type returned if the package being updated contains -// uncommitted changes. -type PkgRepoDirtyError struct { - Path types.UniquePath -} - -func (p *PkgRepoDirtyError) Error() string { - return fmt.Sprintf("package %q contains uncommitted changes", p.Path.String()) -} - -type Options struct { - // RelPackagePath is the relative path of a subpackage to the root. If the - // package is root, the value here will be ".". - RelPackagePath string - - // LocalPath is the absolute path to the package on the local fork. - LocalPath string - - // OriginPath is the absolute path to the package in the on-disk clone - // of the origin ref of the repo. - OriginPath string - - // UpdatedPath is the absolute path to the package in the on-disk clone - // of the updated ref of the repo. - UpdatedPath string - - // IsRoot is true if the package is the root, i.e. the clones of - // updated and origin were fetched based on the information in the - // Kptfile from this package. - IsRoot bool -} - -// Updater updates a local package -var strategies = map[kptfilev1.UpdateStrategyType]func() updatetypes.Updater{ - kptfilev1.FastForward: func() updatetypes.Updater { return FastForwardUpdater{} }, - kptfilev1.ForceDeleteReplace: func() updatetypes.Updater { return ReplaceUpdater{} }, - kptfilev1.ResourceMerge: func() updatetypes.Updater { return ResourceMergeUpdater{} }, - kptfilev1.CopyMerge: func() updatetypes.Updater { return CopyMergeUpdater{} }, -} - -// Command updates the contents of a local package to a different version. -type Command struct { - // Pkg captures information about the package that should be updated. - Pkg *pkg.Pkg - - // Ref is the ref to update to - Ref string - - // Strategy is the update strategy to use - Strategy kptfilev1.UpdateStrategyType - - // cachedUpstreamRepos is an upstream repo already fetched for a given repoSpec CloneRef - cachedUpstreamRepos map[string]*gitutil.GitUpstreamRepo -} - -func GetUpdater(strategy string) updatetypes.Updater { - switch strategy { - case "fast-forward": - return FastForwardUpdater{} - case "force-delete-replace": - return ReplaceUpdater{} - case "copy-merge": - return CopyMergeUpdater{} - default: - return ResourceMergeUpdater{} - } -} - -// Run runs the Command. -func (u *Command) Run(ctx context.Context) error { - const op errors.Op = "update.Run" - pr := printer.FromContextOrDie(ctx) - - if u.Pkg == nil { - return errors.E(op, errors.MissingParam, "pkg must be provided") - } - - rootKf, err := u.Pkg.Kptfile() - if err != nil { - return errors.E(op, u.Pkg.UniquePath, err) - } - - if rootKf.Upstream == nil || rootKf.Upstream.Git == nil { - return errors.E(op, u.Pkg.UniquePath, - fmt.Errorf("package must have an upstream reference")) - } - originalRootKfRef := rootKf.Upstream.Git.Ref - if u.Ref != "" { - rootKf.Upstream.Git.Ref = u.Ref - } - if u.Strategy != "" { - rootKf.Upstream.UpdateStrategy = u.Strategy - } - err = kptfileutil.WriteFile(u.Pkg.UniquePath.String(), rootKf) - if err != nil { - return errors.E(op, u.Pkg.UniquePath, err) - } - if u.cachedUpstreamRepos == nil { - u.cachedUpstreamRepos = make(map[string]*gitutil.GitUpstreamRepo) - } - packageCount := 0 - - // Use stack to keep track of paths with a Kptfile that might contain - // information about remote subpackages. - s := stack.NewPkgStack() - s.Push(u.Pkg) - - for s.Len() > 0 { - p := s.Pop() - packageCount++ - - if err := u.updateRootPackage(ctx, p); err != nil { - return errors.E(op, p.UniquePath, err) - } - - subPkgs, err := p.DirectSubpackages() - if err != nil { - return errors.E(op, p.UniquePath, err) - } - for _, subPkg := range subPkgs { - subKf, err := subPkg.Kptfile() - if err != nil { - return errors.E(op, p.UniquePath, err) - } - - if subKf.Upstream != nil && subKf.Upstream.Git != nil { - // update subpackage kf ref/strategy if current pkg is a subpkg of root pkg or is root pkg - // and if original root pkg ref matches the subpkg ref - if shouldUpdateSubPkgRef(subKf, rootKf, originalRootKfRef) { - updateSubKf(subKf, u.Ref, u.Strategy) - err = kptfileutil.WriteFile(subPkg.UniquePath.String(), subKf) - if err != nil { - return errors.E(op, subPkg.UniquePath, err) - } - } - s.Push(subPkg) - } - } - } - pr.Printf("\nUpdated %d package(s).\n", packageCount) - - // finally, make sure that the merge comments are added to all resources in the updated package - if err := addmergecomment.Process(string(u.Pkg.UniquePath)); err != nil { - return errors.E(op, u.Pkg.UniquePath, err) - } - return nil -} - -// GetCachedUpstreamRepos returns repos cached during update -func (u Command) GetCachedUpstreamRepos() map[string]*gitutil.GitUpstreamRepo { - return u.cachedUpstreamRepos -} - -// updateSubKf updates subpackage with given ref and update strategy -func updateSubKf(subKf *kptfilev1.KptFile, ref string, strategy kptfilev1.UpdateStrategyType) { - // check if explicit ref provided - if ref != "" { - subKf.Upstream.Git.Ref = ref - } - if strategy != "" { - subKf.Upstream.UpdateStrategy = strategy - } -} - -// shouldUpdateSubPkgRef checks if subpkg ref should be updated. -// This is true if pkg has the same upstream repo, upstream directory is within or equal to root pkg directory and original root pkg ref matches the subpkg ref. -func shouldUpdateSubPkgRef(subKf, rootKf *kptfilev1.KptFile, originalRootKfRef string) bool { - return subKf.Upstream.Git.Repo == rootKf.Upstream.Git.Repo && - subKf.Upstream.Git.Ref == originalRootKfRef && - strings.HasPrefix(path.Clean(subKf.Upstream.Git.Directory), path.Clean(rootKf.Upstream.Git.Directory)) -} - -// repoClone is an interface that represents a clone of a repo on the local -// disk. -type repoClone interface { - AbsPath() string -} - -// newNilRepoClone creates a new nilRepoClone that implements the repoClone -// interface -func newNilRepoClone() (*nilRepoClone, error) { - const op errors.Op = "update.newNilRepoClone" - dir, err := os.MkdirTemp("", "kpt-empty-") - if err != nil { - return nil, errors.E(op, errors.IO, fmt.Errorf("errors creating a temporary directory: %w", err)) - } - return &nilRepoClone{ - dir: dir, - }, nil -} - -// nilRepoClone is an implementation of the repoClone interface, but that -// just represents an empty directory. This simplifies the logic for update -// since we don't have to special case situations where we don't have -// upstream and/or origin. -type nilRepoClone struct { - dir string -} - -// AbsPath returns the absolute path to the local directory for the repo. For -// the nilRepoClone, this will always be an empty directory. -func (nrc *nilRepoClone) AbsPath() string { - return nrc.dir -} - -// updateRootPackage updates a local package. It will use the information -// about upstream in the Kptfile to fetch upstream and origin, and then -// recursively traverse the hierarchy to add/update/delete packages. -func (u Command) updateRootPackage(ctx context.Context, p *pkg.Pkg) error { - const op errors.Op = "update.updateRootPackage" - kf, err := p.Kptfile() - if err != nil { - return errors.E(op, p.UniquePath, err) - } - - pr := printer.FromContextOrDie(ctx) - pr.PrintPackage(p, p != u.Pkg) - - g := kf.Upstream.Git - updated := &git.RepoSpec{OrgRepo: g.Repo, Path: g.Directory, Ref: g.Ref} - pr.Printf("Fetching upstream from %s@%s\n", kf.Upstream.Git.Repo, kf.Upstream.Git.Ref) - cloner := fetch.NewCloner(updated, fetch.WithCachedRepo(u.cachedUpstreamRepos)) - if err := cloner.ClonerUsingGitExec(ctx); err != nil { - return errors.E(op, p.UniquePath, err) - } - defer os.RemoveAll(updated.AbsPath()) - - var origin repoClone - if kf.UpstreamLock != nil { - gLock := kf.UpstreamLock.Git - originRepoSpec := &git.RepoSpec{OrgRepo: gLock.Repo, Path: gLock.Directory, Ref: gLock.Commit} - pr.Printf("Fetching origin from %s@%s\n", kf.Upstream.Git.Repo, kf.Upstream.Git.Ref) - if err := fetch.NewCloner(originRepoSpec, fetch.WithCachedRepo(u.cachedUpstreamRepos)).ClonerUsingGitExec(ctx); err != nil { - return errors.E(op, p.UniquePath, err) - } - origin = originRepoSpec - } else { - origin, err = newNilRepoClone() - if err != nil { - return errors.E(op, p.UniquePath, err) - } - } - defer os.RemoveAll(origin.AbsPath()) - - s := stack.New() - s.Push(".") - - for s.Len() > 0 { - relPath := s.Pop() - localPath := filepath.Join(p.UniquePath.String(), relPath) - updatedPath := filepath.Join(updated.AbsPath(), relPath) - originPath := filepath.Join(origin.AbsPath(), relPath) - - isRoot := false - if relPath == "." { - isRoot = true - } - - if err := u.updatePackage(ctx, relPath, localPath, updatedPath, originPath, isRoot); err != nil { - return errors.E(op, p.UniquePath, err) - } - - paths, err := pkgutil.FindSubpackagesForPaths(pkg.Remote, false, - localPath, updatedPath, originPath) - if err != nil { - return errors.E(op, p.UniquePath, err) - } - for _, path := range paths { - s.Push(filepath.Join(relPath, path)) - } - } - - if err := kptfileutil.UpdateUpstreamLockFromGit(p.UniquePath.String(), updated); err != nil { - return errors.E(op, p.UniquePath, err) - } - return nil -} - -// updatePackage takes care of updating a single package. The absolute paths to -// the local, updated and origin packages are provided, as well as the path to the -// package relative to the root. -// The last parameter tells if this package is the root, i.e. the package -// from which we got the information about upstream and origin. -// -//nolint:gocyclo -func (u Command) updatePackage(ctx context.Context, subPkgPath, localPath, updatedPath, originPath string, isRootPkg bool) error { - const op errors.Op = "update.updatePackage" - pr := printer.FromContextOrDie(ctx) - - localExists, err := pkg.IsPackageDir(filesys.FileSystemOrOnDisk{}, localPath) - if err != nil { - return errors.E(op, types.UniquePath(localPath), err) - } - - // We need to handle the root package special here, since the copies - // from updated and origin might not have a Kptfile at the root. - updatedExists := isRootPkg - if !isRootPkg { - updatedExists, err = pkg.IsPackageDir(filesys.FileSystemOrOnDisk{}, updatedPath) - if err != nil { - return errors.E(op, types.UniquePath(localPath), err) - } - } - - originExists := isRootPkg - if !isRootPkg { - originExists, err = pkg.IsPackageDir(filesys.FileSystemOrOnDisk{}, originPath) - if err != nil { - return errors.E(op, types.UniquePath(localPath), err) - } - } - - switch { - case !originExists && !localExists && !updatedExists: - break - // Check if subpackage has been added both in upstream and in local. We - // can't make a sane merge here, so we treat it as an error. - case !originExists && localExists && updatedExists: - pr.Printf("Package %q added in both local and upstream.\n", packageName(localPath)) - return errors.E(op, types.UniquePath(localPath), - fmt.Errorf("subpackage %q added in both upstream and local", subPkgPath)) - - // Package added in upstream. We just copy the package. If the package - // contains any unfetched subpackages, those will be handled when we traverse - // the package hierarchy and that package is the root. - case !originExists && !localExists && updatedExists: - pr.Printf("Adding package %q from upstream.\n", packageName(localPath)) - if err := pkgutil.CopyPackage(updatedPath, localPath, !isRootPkg, pkg.None); err != nil { - return errors.E(op, types.UniquePath(localPath), err) - } - - // Package added locally, so no action needed. - case !originExists && localExists && !updatedExists: - break - - // Package deleted from both upstream and local, so no action needed. - case originExists && !localExists && !updatedExists: - break - - // Package deleted from local - // In this case we assume the user knows what they are doing, so - // we don't re-add the updated package from upstream. - case originExists && !localExists && updatedExists: - pr.Printf("Ignoring package %q in upstream since it is deleted from local.\n", packageName(localPath)) - - // Package deleted from upstream - case originExists && localExists && !updatedExists: - // Check the diff. If there are local changes, we keep the subpackage. - diff, err := copyutil.Diff(originPath, localPath) - if err != nil { - return errors.E(op, types.UniquePath(localPath), err) - } - if diff.Len() == 0 { - pr.Printf("Deleting package %q from local since it is removed in upstream.\n", packageName(localPath)) - if err := os.RemoveAll(localPath); err != nil { - return errors.E(op, types.UniquePath(localPath), err) - } - } else { - pr.Printf("Package %q deleted from upstream, but keeping local since it has changes.\n", packageName(localPath)) - } - default: - if err := u.mergePackage(ctx, localPath, updatedPath, originPath, subPkgPath, isRootPkg); err != nil { - return errors.E(op, types.UniquePath(localPath), err) - } - } - return nil -} - -func (u Command) mergePackage(ctx context.Context, localPath, updatedPath, originPath, relPath string, isRootPkg bool) error { - const op errors.Op = "update.mergePackage" - pr := printer.FromContextOrDie(ctx) - // at this point, the localPath, updatedPath and originPath exists and are about to be merged - // make sure that the merge comments are added to all of them so that they are merged accurately - if err := addmergecomment.Process(localPath, updatedPath, originPath); err != nil { - return errors.E(op, types.UniquePath(localPath), - fmt.Errorf("failed to add merge comments %q", err.Error())) - } - updatedUnfetched, err := pkg.IsPackageUnfetched(updatedPath) - if err != nil { - if !errors.Is(err, os.ErrNotExist) || !isRootPkg { - return errors.E(op, types.UniquePath(localPath), err) - } - // For root packages, there might not be a Kptfile in the upstream repo. - updatedUnfetched = false - } - - originUnfetched, err := pkg.IsPackageUnfetched(originPath) - if err != nil { - if !errors.Is(err, os.ErrNotExist) || !isRootPkg { - return errors.E(op, types.UniquePath(localPath), err) - } - // For root packages, there might not be a Kptfile in origin. - originUnfetched = false - } - - switch { - case updatedUnfetched && originUnfetched: - fallthrough - case updatedUnfetched && !originUnfetched: - // updated is unfetched, so can't have changes except for Kptfile. - // we can just merge that one. - return kptfileutil.UpdateKptfile(localPath, updatedPath, originPath, true) - case !updatedUnfetched && originUnfetched: - // This means that the package was unfetched when local forked from upstream, - // so the local fork and upstream might have fetched different versions of - // the package. We just return an error here. - // We might be able to compare the commit SHAs from local and updated - // to determine if they share the common upstream and then fetch origin - // using the common commit SHA. But this is a very advanced scenario, - // so we just return the error for now. - return errors.E(op, types.UniquePath(localPath), fmt.Errorf("no origin available for package")) - default: - // Both exists, so just go ahead as normal. - } - - pkgKf, err := kptfileutil.ReadKptfile(filesys.FileSystemOrOnDisk{}, localPath) - if err != nil { - return errors.E(op, types.UniquePath(localPath), err) - } - updater, found := strategies[pkgKf.Upstream.UpdateStrategy] - if !found { - return errors.E(op, types.UniquePath(localPath), - fmt.Errorf("unrecognized update strategy %s", u.Strategy)) - } - pr.Printf("Updating package %q with strategy %q.\n", packageName(localPath), pkgKf.Upstream.UpdateStrategy) - if err := updater().Update(updatetypes.Options{ - RelPackagePath: relPath, - LocalPath: localPath, - UpdatedPath: updatedPath, - OriginPath: originPath, - IsRoot: isRootPkg, - }); err != nil { - return errors.E(op, types.UniquePath(localPath), err) - } - - return nil -} - -func packageName(path string) string { - return filepath.Base(path) -} diff --git a/pkg/api/kptfile/v1/validation.go b/pkg/api/kptfile/v1/validation.go index be2778b2bd..2a1fb59838 100644 --- a/pkg/api/kptfile/v1/validation.go +++ b/pkg/api/kptfile/v1/validation.go @@ -21,7 +21,7 @@ import ( "slices" "strings" - "github.com/kptdev/kpt/internal/types" + "github.com/kptdev/kpt/pkg/lib/types" "sigs.k8s.io/kustomize/api/konfig" kustomizetypes "sigs.k8s.io/kustomize/api/types" "sigs.k8s.io/kustomize/kyaml/filesys" diff --git a/pkg/api/kptfile/v1/validation_test.go b/pkg/api/kptfile/v1/validation_test.go index 6d6598d0ab..08c5e23d1e 100644 --- a/pkg/api/kptfile/v1/validation_test.go +++ b/pkg/api/kptfile/v1/validation_test.go @@ -18,7 +18,7 @@ import ( "path/filepath" "testing" - "github.com/kptdev/kpt/internal/types" + "github.com/kptdev/kpt/pkg/lib/types" "github.com/stretchr/testify/assert" "sigs.k8s.io/kustomize/kyaml/filesys" "sigs.k8s.io/kustomize/kyaml/yaml" diff --git a/pkg/fn/runtime/runner.go b/pkg/fn/runtime/runner.go index ae2c023564..4c193207e6 100644 --- a/pkg/fn/runtime/runner.go +++ b/pkg/fn/runtime/runner.go @@ -26,14 +26,14 @@ import ( "time" "github.com/google/shlex" - "github.com/kptdev/kpt/internal/builtins" - "github.com/kptdev/kpt/internal/pkg" - "github.com/kptdev/kpt/internal/types" fnresult "github.com/kptdev/kpt/pkg/api/fnresult/v1" kptfilev1 "github.com/kptdev/kpt/pkg/api/kptfile/v1" "github.com/kptdev/kpt/pkg/fn" + "github.com/kptdev/kpt/pkg/lib/builtins" "github.com/kptdev/kpt/pkg/lib/errors" + "github.com/kptdev/kpt/pkg/lib/pkg" "github.com/kptdev/kpt/pkg/lib/runneroptions" + "github.com/kptdev/kpt/pkg/lib/types" "github.com/kptdev/kpt/pkg/printer" "github.com/regclient/regclient" "sigs.k8s.io/kustomize/kyaml/filesys" diff --git a/pkg/fn/runtime/runner_test.go b/pkg/fn/runtime/runner_test.go index 74bdb5f786..e056fe551a 100644 --- a/pkg/fn/runtime/runner_test.go +++ b/pkg/fn/runtime/runner_test.go @@ -24,9 +24,9 @@ import ( "strings" "testing" - "github.com/kptdev/kpt/internal/types" kptfilev1 "github.com/kptdev/kpt/pkg/api/kptfile/v1" "github.com/kptdev/kpt/pkg/lib/runneroptions" + "github.com/kptdev/kpt/pkg/lib/types" "github.com/kptdev/kpt/pkg/printer" "github.com/stretchr/testify/assert" "sigs.k8s.io/kustomize/kyaml/filesys" diff --git a/pkg/fn/runtime/utils.go b/pkg/fn/runtime/utils.go index 6d4289c6b5..d182b60e1d 100644 --- a/pkg/fn/runtime/utils.go +++ b/pkg/fn/runtime/utils.go @@ -19,9 +19,9 @@ import ( "fmt" "path/filepath" - "github.com/kptdev/kpt/internal/types" fnresult "github.com/kptdev/kpt/pkg/api/fnresult/v1" kptfilev1 "github.com/kptdev/kpt/pkg/api/kptfile/v1" + "github.com/kptdev/kpt/pkg/lib/types" "sigs.k8s.io/kustomize/kyaml/filesys" "sigs.k8s.io/kustomize/kyaml/yaml" ) diff --git a/pkg/kptfile/kptfileutil/util.go b/pkg/kptfile/kptfileutil/util.go index 2070142470..f6cf55b1a5 100644 --- a/pkg/kptfile/kptfileutil/util.go +++ b/pkg/kptfile/kptfileutil/util.go @@ -24,10 +24,10 @@ import ( "slices" "strings" - "github.com/kptdev/kpt/internal/types" - "github.com/kptdev/kpt/internal/util/git" kptfilev1 "github.com/kptdev/kpt/pkg/api/kptfile/v1" "github.com/kptdev/kpt/pkg/lib/errors" + "github.com/kptdev/kpt/pkg/lib/types" + "github.com/kptdev/kpt/pkg/lib/util/git" "k8s.io/apimachinery/pkg/runtime/schema" "sigs.k8s.io/kustomize/kyaml/filesys" "sigs.k8s.io/kustomize/kyaml/sets" @@ -194,7 +194,7 @@ func UpdateKptfileWithoutOrigin(localPath, updatedPath string, updateUpstream bo updatedKf = &kptfilev1.KptFile{} } - err = merge(localKf, updatedKf, &kptfilev1.KptFile{}) + err = MergeKptfiles(localKf, updatedKf, &kptfilev1.KptFile{}) if err != nil { return err } @@ -241,7 +241,7 @@ func UpdateKptfile(localPath, updatedPath, originPath string, updateUpstream boo originKf = &kptfilev1.KptFile{} } - err = merge(localKf, updatedKf, originKf) + err = MergeKptfiles(localKf, updatedKf, originKf) if err != nil { return err } @@ -379,10 +379,10 @@ func isSupportedKptfileVersion(gvk schema.GroupVersionKind) bool { return slices.Contains(SupportedKptfileVersions, gvk) } -// merge merges the Kptfiles from various sources and updates localKf with output +// MergeKptfiles merges the Kptfiles from various sources and updates localKf with output // please refer to https://github.com/kptdev/kpt/blob/main/docs/design-docs/03-pipeline-merge.md // for related design -func merge(localKf, updatedKf, originalKf *kptfilev1.KptFile) error { +func MergeKptfiles(localKf, updatedKf, originalKf *kptfilev1.KptFile) error { shouldAddSyntheticMergeName := shouldAddFnKey(localKf, updatedKf, originalKf) if shouldAddSyntheticMergeName { addNameForMerge(localKf, updatedKf, originalKf) @@ -471,7 +471,7 @@ func shouldAddFnKeyUtil(fns []kptfilev1.Function) bool { } // addNameForMerge adds name field for all the functions if empty -// name is primarily used as merge-key +// name is primarily used as MergeKptfiles-key func addNameForMerge(kfs ...*kptfilev1.KptFile) { for _, kf := range kfs { if kf == nil || kf.Pipeline == nil { diff --git a/pkg/kptfile/kptfileutil/util_test.go b/pkg/kptfile/kptfileutil/util_test.go index 424ef11624..9d31b348cf 100644 --- a/pkg/kptfile/kptfileutil/util_test.go +++ b/pkg/kptfile/kptfileutil/util_test.go @@ -1386,7 +1386,7 @@ pipeline: assert.NoError(t, err) originKf, err := DecodeKptfile(strings.NewReader(tc.origin)) assert.NoError(t, err) - err = merge(localKf, updatedKf, originKf) + err = MergeKptfiles(localKf, updatedKf, originKf) if tc.err == nil { if !assert.NoError(t, err) { t.FailNow() diff --git a/pkg/kptpkg/init.go b/pkg/kptpkg/init.go index eb6a7e07c2..e4a4c41f7c 100644 --- a/pkg/kptpkg/init.go +++ b/pkg/kptpkg/init.go @@ -21,11 +21,11 @@ import ( "path/filepath" "strings" - "github.com/kptdev/kpt/internal/builtins" - "github.com/kptdev/kpt/internal/pkg" - "github.com/kptdev/kpt/internal/util/man" kptfilev1 "github.com/kptdev/kpt/pkg/api/kptfile/v1" - builtintypes "github.com/kptdev/kpt/pkg/lib/builtins/builtintypes" + "github.com/kptdev/kpt/pkg/lib/builtins" + "github.com/kptdev/kpt/pkg/lib/builtins/builtintypes" + "github.com/kptdev/kpt/pkg/lib/pkg" + "github.com/kptdev/kpt/pkg/lib/util/man" "github.com/kptdev/kpt/pkg/printer" "sigs.k8s.io/kustomize/kyaml/errors" "sigs.k8s.io/kustomize/kyaml/filesys" diff --git a/pkg/lib/builtins/builtins.go b/pkg/lib/builtins/builtins.go index 484dd56c0b..c05cf78a14 100644 --- a/pkg/lib/builtins/builtins.go +++ b/pkg/lib/builtins/builtins.go @@ -19,14 +19,13 @@ import ( "fmt" "reflect" - "github.com/kptdev/kpt/internal/builtins" - builtintypes "github.com/kptdev/kpt/pkg/lib/builtins/builtintypes" + "github.com/kptdev/kpt/pkg/lib/builtins/builtintypes" ) func GetBuiltinFn(config any) builtintypes.BuiltinFunction { if reflect.TypeOf(config) == reflect.TypeFor[*builtintypes.PackageConfig]() { packageConfig := config.(*builtintypes.PackageConfig) - return &builtins.PackageContextGenerator{ + return &PackageContextGenerator{ PackageConfig: packageConfig, } } diff --git a/internal/builtins/pkg_context.go b/pkg/lib/builtins/pkg_context.go similarity index 98% rename from internal/builtins/pkg_context.go rename to pkg/lib/builtins/pkg_context.go index 80d74df606..3f0680d3af 100644 --- a/internal/builtins/pkg_context.go +++ b/pkg/lib/builtins/pkg_context.go @@ -26,7 +26,7 @@ import ( "sigs.k8s.io/kustomize/kyaml/yaml" kptfilev1 "github.com/kptdev/kpt/pkg/api/kptfile/v1" - builtintypes "github.com/kptdev/kpt/pkg/lib/builtins/builtintypes" + "github.com/kptdev/kpt/pkg/lib/builtins/builtintypes" ) var ( diff --git a/internal/builtins/pkg_context_test.go b/pkg/lib/builtins/pkg_context_test.go similarity index 100% rename from internal/builtins/pkg_context_test.go rename to pkg/lib/builtins/pkg_context_test.go diff --git a/internal/builtins/testdata/pkg-with-existing-ctx/in.yaml b/pkg/lib/builtins/testdata/pkg-with-existing-ctx/in.yaml similarity index 100% rename from internal/builtins/testdata/pkg-with-existing-ctx/in.yaml rename to pkg/lib/builtins/testdata/pkg-with-existing-ctx/in.yaml diff --git a/internal/builtins/testdata/pkg-with-existing-ctx/out.yaml b/pkg/lib/builtins/testdata/pkg-with-existing-ctx/out.yaml similarity index 100% rename from internal/builtins/testdata/pkg-with-existing-ctx/out.yaml rename to pkg/lib/builtins/testdata/pkg-with-existing-ctx/out.yaml diff --git a/internal/builtins/testdata/pkg-with-nesting/in.yaml b/pkg/lib/builtins/testdata/pkg-with-nesting/in.yaml similarity index 100% rename from internal/builtins/testdata/pkg-with-nesting/in.yaml rename to pkg/lib/builtins/testdata/pkg-with-nesting/in.yaml diff --git a/internal/builtins/testdata/pkg-with-nesting/out.yaml b/pkg/lib/builtins/testdata/pkg-with-nesting/out.yaml similarity index 100% rename from internal/builtins/testdata/pkg-with-nesting/out.yaml rename to pkg/lib/builtins/testdata/pkg-with-nesting/out.yaml diff --git a/internal/builtins/testdata/pkg-wo-nesting/in.yaml b/pkg/lib/builtins/testdata/pkg-wo-nesting/in.yaml similarity index 100% rename from internal/builtins/testdata/pkg-wo-nesting/in.yaml rename to pkg/lib/builtins/testdata/pkg-wo-nesting/in.yaml diff --git a/internal/builtins/testdata/pkg-wo-nesting/out.yaml b/pkg/lib/builtins/testdata/pkg-wo-nesting/out.yaml similarity index 100% rename from internal/builtins/testdata/pkg-wo-nesting/out.yaml rename to pkg/lib/builtins/testdata/pkg-wo-nesting/out.yaml diff --git a/pkg/lib/errors/errors.go b/pkg/lib/errors/errors.go index a4a297b8ca..9feff62de4 100644 --- a/pkg/lib/errors/errors.go +++ b/pkg/lib/errors/errors.go @@ -22,7 +22,7 @@ import ( goerrors "errors" kyaml_errors "github.com/go-errors/errors" - "github.com/kptdev/kpt/internal/types" + "github.com/kptdev/kpt/pkg/lib/types" ) // Error is the type that implements error interface used in the kpt codebase. diff --git a/pkg/lib/errors/errors_test.go b/pkg/lib/errors/errors_test.go index c2e324e64f..75dd492c4c 100644 --- a/pkg/lib/errors/errors_test.go +++ b/pkg/lib/errors/errors_test.go @@ -19,7 +19,7 @@ import ( "strings" "testing" - "github.com/kptdev/kpt/internal/types" + "github.com/kptdev/kpt/pkg/lib/types" ) func TestErrorFormatting(t *testing.T) { diff --git a/pkg/lib/errors/resolver/live.go b/pkg/lib/errors/resolver/live.go index f57293809b..915abad922 100644 --- a/pkg/lib/errors/resolver/live.go +++ b/pkg/lib/errors/resolver/live.go @@ -20,7 +20,7 @@ import ( "strings" initialization "github.com/kptdev/kpt/commands/live/init" - "github.com/kptdev/kpt/internal/pkg" + "github.com/kptdev/kpt/pkg/lib/pkg" "github.com/kptdev/kpt/pkg/lib/util/cmdutil" "github.com/kptdev/kpt/pkg/live" "sigs.k8s.io/cli-utils/pkg/inventory" diff --git a/pkg/lib/errors/resolver/pkg.go b/pkg/lib/errors/resolver/pkg.go index 6f2ab4ca9b..35eeaa0f68 100644 --- a/pkg/lib/errors/resolver/pkg.go +++ b/pkg/lib/errors/resolver/pkg.go @@ -18,10 +18,10 @@ import ( "fmt" "os" - "github.com/kptdev/kpt/internal/pkg" kptfilev1 "github.com/kptdev/kpt/pkg/api/kptfile/v1" "github.com/kptdev/kpt/pkg/kptfile/kptfileutil" "github.com/kptdev/kpt/pkg/lib/errors" + "github.com/kptdev/kpt/pkg/lib/pkg" ) //nolint:gochecknoinits diff --git a/pkg/lib/errors/resolver/update.go b/pkg/lib/errors/resolver/update.go index a94c8f3e96..3730767756 100644 --- a/pkg/lib/errors/resolver/update.go +++ b/pkg/lib/errors/resolver/update.go @@ -17,8 +17,8 @@ package resolver import ( "fmt" - "github.com/kptdev/kpt/internal/util/update" "github.com/kptdev/kpt/pkg/lib/errors" + "github.com/kptdev/kpt/pkg/lib/update" ) //nolint:gochecknoinits diff --git a/pkg/lib/errors/validate.go b/pkg/lib/errors/validate.go index c098f1763d..ca9f7515c0 100644 --- a/pkg/lib/errors/validate.go +++ b/pkg/lib/errors/validate.go @@ -17,7 +17,7 @@ package errors import ( "fmt" - "github.com/kptdev/kpt/internal/util/strings" + "github.com/kptdev/kpt/pkg/lib/util/strings" ) // ValidationError is an error type used when validation fails. diff --git a/pkg/lib/kptops/fs_test.go b/pkg/lib/kptops/fs_test.go index d989f2fe15..1a03caf791 100644 --- a/pkg/lib/kptops/fs_test.go +++ b/pkg/lib/kptops/fs_test.go @@ -17,7 +17,6 @@ package kptops import ( "testing" - "github.com/kptdev/kpt/internal/util/render" "github.com/kptdev/kpt/pkg/lib/runneroptions" "github.com/kptdev/kpt/pkg/printer/fake" "sigs.k8s.io/kustomize/kyaml/filesys" @@ -101,7 +100,7 @@ spec: if err := fs.WriteFile("/a/b/c/Kptfile", []byte(kptfile)); err != nil { t.Errorf("Failed to write file: %v", err) } - r := render.Renderer{ + r := Renderer{ PkgPath: "/a/b/c", FileSystem: fs, Runtime: &runtime{}, @@ -215,7 +214,7 @@ spec: t.Errorf("Failed to write file: %v", err) } - r := render.Renderer{ + r := Renderer{ PkgPath: "/app", FileSystem: fs, Runtime: &runtime{}, diff --git a/internal/hook/executor.go b/pkg/lib/kptops/hook_executor.go similarity index 96% rename from internal/hook/executor.go rename to pkg/lib/kptops/hook_executor.go index 8595463b36..e01dcadb86 100644 --- a/internal/hook/executor.go +++ b/pkg/lib/kptops/hook_executor.go @@ -12,20 +12,20 @@ // See the License for the specific language governing permissions and // limitations under the License. -package hook +package kptops import ( "context" "fmt" "io" - "github.com/kptdev/kpt/internal/pkg" - "github.com/kptdev/kpt/internal/types" fnresult "github.com/kptdev/kpt/pkg/api/fnresult/v1" kptfilev1 "github.com/kptdev/kpt/pkg/api/kptfile/v1" "github.com/kptdev/kpt/pkg/fn" fnruntime "github.com/kptdev/kpt/pkg/fn/runtime" + "github.com/kptdev/kpt/pkg/lib/pkg" "github.com/kptdev/kpt/pkg/lib/runneroptions" + "github.com/kptdev/kpt/pkg/lib/types" "sigs.k8s.io/kustomize/kyaml/filesys" "sigs.k8s.io/kustomize/kyaml/kio" ) diff --git a/pkg/lib/kptops/pkgupdate.go b/pkg/lib/kptops/pkgupdate.go index 642cdedf39..63cb678a0a 100644 --- a/pkg/lib/kptops/pkgupdate.go +++ b/pkg/lib/kptops/pkgupdate.go @@ -20,12 +20,12 @@ import ( "os" "path/filepath" - "github.com/kptdev/kpt/internal/util/fetch" - "github.com/kptdev/kpt/internal/util/git" - "github.com/kptdev/kpt/internal/util/update" kptfilev1 "github.com/kptdev/kpt/pkg/api/kptfile/v1" "github.com/kptdev/kpt/pkg/kptfile/kptfileutil" + "github.com/kptdev/kpt/pkg/lib/update" "github.com/kptdev/kpt/pkg/lib/update/updatetypes" + "github.com/kptdev/kpt/pkg/lib/util/fetch" + "github.com/kptdev/kpt/pkg/lib/util/git" "github.com/kptdev/kpt/pkg/printer" "k8s.io/klog/v2" ) diff --git a/pkg/lib/kptops/render.go b/pkg/lib/kptops/render.go index 459f12ce5e..260c619c8a 100644 --- a/pkg/lib/kptops/render.go +++ b/pkg/lib/kptops/render.go @@ -20,10 +20,9 @@ import ( "io" "os" - "github.com/kptdev/kpt/internal/pkg" - "github.com/kptdev/kpt/internal/util/render" fnresult "github.com/kptdev/kpt/pkg/api/fnresult/v1" "github.com/kptdev/kpt/pkg/fn" + "github.com/kptdev/kpt/pkg/lib/pkg" "github.com/kptdev/kpt/pkg/lib/runneroptions" "github.com/kptdev/kpt/pkg/printer" "k8s.io/klog/v2" @@ -41,7 +40,7 @@ type renderer struct { var _ fn.Renderer = &renderer{} func (r *renderer) Render(ctx context.Context, pkg filesys.FileSystem, opts fn.RenderOptions) (*fnresult.ResultList, error) { - rr := render.Renderer{ + rr := Renderer{ PkgPath: opts.PkgPath, Runtime: opts.Runtime, DisplayName: opts.DisplayName, diff --git a/internal/util/render/executor.go b/pkg/lib/kptops/render_executor.go similarity index 99% rename from internal/util/render/executor.go rename to pkg/lib/kptops/render_executor.go index 3574ac0ccf..044a9fb0e7 100644 --- a/internal/util/render/executor.go +++ b/pkg/lib/kptops/render_executor.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package render +package kptops import ( "context" @@ -23,17 +23,16 @@ import ( "slices" "strings" - "github.com/kptdev/kpt/internal/pkg" - "github.com/kptdev/kpt/internal/types" - "github.com/kptdev/kpt/internal/util/attribution" - "github.com/kptdev/kpt/internal/util/printerutil" fnresult "github.com/kptdev/kpt/pkg/api/fnresult/v1" kptfilev1 "github.com/kptdev/kpt/pkg/api/kptfile/v1" "github.com/kptdev/kpt/pkg/fn" fnruntime "github.com/kptdev/kpt/pkg/fn/runtime" "github.com/kptdev/kpt/pkg/kptfile/kptfileutil" "github.com/kptdev/kpt/pkg/lib/errors" + "github.com/kptdev/kpt/pkg/lib/pkg" "github.com/kptdev/kpt/pkg/lib/runneroptions" + "github.com/kptdev/kpt/pkg/lib/types" + "github.com/kptdev/kpt/pkg/lib/util/attribution" "github.com/kptdev/kpt/pkg/printer" "k8s.io/klog/v2" "sigs.k8s.io/kustomize/kyaml/filesys" @@ -308,7 +307,7 @@ func (e *Renderer) saveFnResults(ctx context.Context, fnResults *fnresult.Result return fmt.Errorf("failed to save function results: %w", err) } - printerutil.PrintFnResultInfo(ctx, resultsFile, false) + printer.PrintFnResultInfo(ctx, resultsFile, false) return nil } diff --git a/internal/util/render/executor_test.go b/pkg/lib/kptops/render_executor_test.go similarity index 99% rename from internal/util/render/executor_test.go rename to pkg/lib/kptops/render_executor_test.go index ac07c74af5..a208d39a4a 100644 --- a/internal/util/render/executor_test.go +++ b/pkg/lib/kptops/render_executor_test.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package render +package kptops import ( "bytes" @@ -22,12 +22,12 @@ import ( "strings" "testing" - "github.com/kptdev/kpt/internal/pkg" - "github.com/kptdev/kpt/internal/types" fnresult "github.com/kptdev/kpt/pkg/api/fnresult/v1" kptfilev1 "github.com/kptdev/kpt/pkg/api/kptfile/v1" fnruntime "github.com/kptdev/kpt/pkg/fn/runtime" "github.com/kptdev/kpt/pkg/kptfile/kptfileutil" + "github.com/kptdev/kpt/pkg/lib/pkg" + "github.com/kptdev/kpt/pkg/lib/types" "github.com/kptdev/kpt/pkg/printer" "github.com/stretchr/testify/assert" "sigs.k8s.io/kustomize/kyaml/filesys" diff --git a/pkg/lib/kptops/render_test.go b/pkg/lib/kptops/render_test.go index d4527504e9..63cdf524d7 100644 --- a/pkg/lib/kptops/render_test.go +++ b/pkg/lib/kptops/render_test.go @@ -23,7 +23,7 @@ import ( "strings" "testing" - "github.com/kptdev/kpt/internal/pkg" + "github.com/kptdev/kpt/pkg/lib/pkg" "github.com/kptdev/kpt/pkg/printer" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" diff --git a/internal/util/diff/diff.go b/pkg/lib/pkg/diff/diff.go similarity index 98% rename from internal/util/diff/diff.go rename to pkg/lib/pkg/diff/diff.go index 864d6d2f4d..0f34ee7a56 100644 --- a/internal/util/diff/diff.go +++ b/pkg/lib/pkg/diff/diff.go @@ -25,12 +25,11 @@ import ( "strings" "github.com/kptdev/kpt/internal/gitutil" - "github.com/kptdev/kpt/internal/pkg" - "github.com/kptdev/kpt/internal/util/fetch" - "github.com/kptdev/kpt/internal/util/pkgutil" kptfilev1 "github.com/kptdev/kpt/pkg/api/kptfile/v1" "github.com/kptdev/kpt/pkg/kptfile/kptfileutil" + "github.com/kptdev/kpt/pkg/lib/pkg" "github.com/kptdev/kpt/pkg/lib/util/addmergecomment" + "github.com/kptdev/kpt/pkg/lib/util/fetch" "sigs.k8s.io/kustomize/kyaml/errors" "sigs.k8s.io/kustomize/kyaml/filesys" ) @@ -149,7 +148,7 @@ func (c *Command) Run(ctx context.Context) error { return errors.Errorf("failed to create stage dir for current package: %v", err) } - err = pkgutil.CopyPackage(c.Path, currPkg, true, pkg.Local) + err = pkg.CopyPackage(c.Path, currPkg, true, pkg.Local) if err != nil { return errors.Errorf("failed to stage current package: %v", err) } diff --git a/internal/util/diff/diff_test.go b/pkg/lib/pkg/diff/diff_test.go similarity index 99% rename from internal/util/diff/diff_test.go rename to pkg/lib/pkg/diff/diff_test.go index faea661428..dc037a1cd5 100644 --- a/internal/util/diff/diff_test.go +++ b/pkg/lib/pkg/diff/diff_test.go @@ -28,7 +28,7 @@ import ( "github.com/kptdev/kpt/internal/testutil" "github.com/kptdev/kpt/internal/testutil/pkgbuilder" - "github.com/kptdev/kpt/internal/util/diff" + "github.com/kptdev/kpt/pkg/lib/pkg/diff" "github.com/kptdev/kpt/pkg/printer/fake" "github.com/stretchr/testify/assert" ) diff --git a/internal/util/diff/pkgdiff.go b/pkg/lib/pkg/diff/pkgdiff.go similarity index 95% rename from internal/util/diff/pkgdiff.go rename to pkg/lib/pkg/diff/pkgdiff.go index e41681ed33..5049921c56 100644 --- a/internal/util/diff/pkgdiff.go +++ b/pkg/lib/pkg/diff/pkgdiff.go @@ -19,10 +19,10 @@ import ( "os" "path/filepath" - "github.com/kptdev/kpt/internal/util/attribution" - "github.com/kptdev/kpt/internal/util/pkgutil" kptfilev1 "github.com/kptdev/kpt/pkg/api/kptfile/v1" "github.com/kptdev/kpt/pkg/kptfile/kptfileutil" + "github.com/kptdev/kpt/pkg/lib/pkg" + "github.com/kptdev/kpt/pkg/lib/util/attribution" "sigs.k8s.io/kustomize/kyaml/filesys" "sigs.k8s.io/kustomize/kyaml/kio" "sigs.k8s.io/kustomize/kyaml/sets" @@ -107,7 +107,7 @@ func kptfilesEqual(pkg1, pkg2, filePath string) (bool, error) { func pkgSet(pkgPath string) (sets.String, error) { pkgFiles := sets.String{} - if err := pkgutil.WalkPackage(pkgPath, func(path string, _ os.FileInfo, err error) error { + if err := pkg.WalkPackage(pkgPath, func(path string, _ os.FileInfo, err error) error { if err != nil { return err } diff --git a/internal/util/diff/pkgdiff_test.go b/pkg/lib/pkg/diff/pkgdiff_test.go similarity index 97% rename from internal/util/diff/pkgdiff_test.go rename to pkg/lib/pkg/diff/pkgdiff_test.go index a5400164fb..6f4d53928d 100644 --- a/internal/util/diff/pkgdiff_test.go +++ b/pkg/lib/pkg/diff/pkgdiff_test.go @@ -12,13 +12,14 @@ // See the License for the specific language governing permissions and // limitations under the License. -package diff +package diff_test import ( "testing" "github.com/kptdev/kpt/internal/testutil" "github.com/kptdev/kpt/internal/testutil/pkgbuilder" + "github.com/kptdev/kpt/pkg/lib/pkg/diff" "github.com/stretchr/testify/assert" "sigs.k8s.io/kustomize/kyaml/sets" ) @@ -141,7 +142,7 @@ func TestPkgDiff(t *testing.T) { t.Run(test.name, func(t *testing.T) { pkg1Dir := test.pkg1.ExpandPkg(t, testutil.EmptyReposInfo) pkg2Dir := test.pkg2.ExpandPkg(t, testutil.EmptyReposInfo) - diff, err := PkgDiff(pkg1Dir, pkg2Dir) + diff, err := diff.PkgDiff(pkg1Dir, pkg2Dir) if !assert.NoError(t, err) { t.FailNow() } diff --git a/internal/pkg/pkg.go b/pkg/lib/pkg/pkg.go similarity index 99% rename from internal/pkg/pkg.go rename to pkg/lib/pkg/pkg.go index ff10b27706..46c3a904de 100644 --- a/internal/pkg/pkg.go +++ b/pkg/lib/pkg/pkg.go @@ -24,13 +24,13 @@ import ( "sort" "strings" - "github.com/kptdev/kpt/internal/types" - "github.com/kptdev/kpt/internal/util/git" - "github.com/kptdev/kpt/internal/util/pathutil" kptfilev1 "github.com/kptdev/kpt/pkg/api/kptfile/v1" rgfilev1alpha1 "github.com/kptdev/kpt/pkg/api/resourcegroup/v1alpha1" "github.com/kptdev/kpt/pkg/kptfile/kptfileutil" "github.com/kptdev/kpt/pkg/lib/errors" + "github.com/kptdev/kpt/pkg/lib/types" + "github.com/kptdev/kpt/pkg/lib/util/git" + "github.com/kptdev/kpt/pkg/lib/util/path" "sigs.k8s.io/kustomize/kyaml/filesys" "sigs.k8s.io/kustomize/kyaml/kio" "sigs.k8s.io/kustomize/kyaml/kio/kioutil" @@ -503,7 +503,7 @@ func ReadRGFile(pkgPath, rgfile string) (*rgfilev1alpha1.ResourceGroup, error) { if filepath.Base(rgfile) == rgfile { absPath = filepath.Join(pkgPath, rgfile) } else { - rgFilePath, _, err := pathutil.ResolveAbsAndRelPaths(rgfile) + rgFilePath, _, err := path.ResolveAbsAndRelPaths(rgfile) if err != nil { return nil, &RGError{ Path: types.UniquePath(rgfile), diff --git a/internal/pkg/pkg_test.go b/pkg/lib/pkg/pkg_test.go similarity index 97% rename from internal/pkg/pkg_test.go rename to pkg/lib/pkg/pkg_test.go index c70f0f4f51..1e39fc6527 100644 --- a/internal/pkg/pkg_test.go +++ b/pkg/lib/pkg/pkg_test.go @@ -23,8 +23,8 @@ import ( "testing" "github.com/kptdev/kpt/internal/testutil/pkgbuilder" - "github.com/kptdev/kpt/internal/util/pathutil" kptfilev1 "github.com/kptdev/kpt/pkg/api/kptfile/v1" + "github.com/kptdev/kpt/pkg/lib/util/path" "github.com/stretchr/testify/assert" "sigs.k8s.io/kustomize/kyaml/filesys" ) @@ -79,7 +79,7 @@ func TestNewPkg(t *testing.T) { assert.NoError(t, err) revert := Chdir(t, filepath.Join(dir, test.workingDir)) defer revert() - absInputPath, _, err := pathutil.ResolveAbsAndRelPaths(test.inputPath) + absInputPath, _, err := path.ResolveAbsAndRelPaths(test.inputPath) assert.NoError(t, err) p, err := New(filesys.FileSystemOrOnDisk{}, absInputPath) assert.NoError(t, err) @@ -163,18 +163,18 @@ func TestAdjustDisplayPathForSubpkg(t *testing.T) { assert.NoError(t, err) revert := Chdir(t, filepath.Join(dir, "rootPkgParentDir", test.workingDir)) defer revert() - absPkgPath, _, err := pathutil.ResolveAbsAndRelPaths(test.pkgPath) + absPkgPath, _, err := path.ResolveAbsAndRelPaths(test.pkgPath) assert.NoError(t, err) parent, err := New(filesys.FileSystemOrOnDisk{}, absPkgPath) assert.NoError(t, err) if test.rootPkgParentDirPath != "" { - absRootPkgPath, _, err := pathutil.ResolveAbsAndRelPaths(test.rootPkgParentDirPath) + absRootPkgPath, _, err := path.ResolveAbsAndRelPaths(test.rootPkgParentDirPath) assert.NoError(t, err) rootPkg, err := New(filesys.FileSystemOrOnDisk{}, absRootPkgPath) assert.NoError(t, err) parent.rootPkgParentDirPath = string(rootPkg.UniquePath) } - absSubPkgPath, _, err := pathutil.ResolveAbsAndRelPaths(test.subPkgPath) + absSubPkgPath, _, err := path.ResolveAbsAndRelPaths(test.subPkgPath) assert.NoError(t, err) subPkg, err := New(filesys.FileSystemOrOnDisk{}, absSubPkgPath) assert.NoError(t, err) @@ -278,7 +278,7 @@ func TestDirectSubpackages(t *testing.T) { t.Run(tn, func(t *testing.T) { pkgPath := tc.pkg.ExpandPkg(t, nil) defer os.RemoveAll(pkgPath) - absPkgPath, _, err := pathutil.ResolveAbsAndRelPaths(pkgPath) + absPkgPath, _, err := path.ResolveAbsAndRelPaths(pkgPath) if !assert.NoError(t, err) { t.FailNow() } diff --git a/internal/util/pkgutil/pkgutil.go b/pkg/lib/pkg/util.go similarity index 95% rename from internal/util/pkgutil/pkgutil.go rename to pkg/lib/pkg/util.go index 5daedf9ab9..5a05cf2f28 100644 --- a/internal/util/pkgutil/pkgutil.go +++ b/pkg/lib/pkg/util.go @@ -13,7 +13,7 @@ // limitations under the License. // Package pkgutil contains utility functions for packages -package pkgutil +package pkg import ( "io" @@ -22,7 +22,6 @@ import ( "sort" "strings" - "github.com/kptdev/kpt/internal/pkg" kptfilev1 "github.com/kptdev/kpt/pkg/api/kptfile/v1" "github.com/kptdev/kpt/pkg/kptfile/kptfileutil" "sigs.k8s.io/kustomize/kyaml/copyutil" @@ -69,8 +68,8 @@ func WalkPackage(src string, c func(string, os.FileInfo, error) error) error { // CopyPackage copies the content of a single package from src to dst. If includeSubpackages // is true, it will copy resources belonging to any subpackages. -func CopyPackage(src, dst string, copyRootKptfile bool, matcher pkg.SubpackageMatcher) error { - subpackagesToCopy, err := pkg.Subpackages(filesys.FileSystemOrOnDisk{}, src, matcher, true) +func CopyPackage(src, dst string, copyRootKptfile bool, matcher SubpackageMatcher) error { + subpackagesToCopy, err := Subpackages(filesys.FileSystemOrOnDisk{}, src, matcher, true) if err != nil { return err } @@ -172,7 +171,7 @@ func CopyPackage(src, dst string, copyRootKptfile bool, matcher pkg.SubpackageMa // RemoveStaleItems removes files and directories from the dst package that were present in the org package, // but are not present in the src package. It does not remove the root Kptfile of the dst package. -func RemoveStaleItems(org, src, dst string, _ bool, _ pkg.SubpackageMatcher) error { +func RemoveStaleItems(org, src, dst string, _ bool, _ SubpackageMatcher) error { var dirsToDelete []string walkErr := filepath.Walk(dst, func(path string, info os.FileInfo, err error) error { if err != nil { @@ -319,10 +318,10 @@ func SubPkgFirstSorter(paths []string) func(i, j int) bool { // FindSubpackagesForPaths traverses the provided package paths // and finds all subpackages using the provided pkgLocatorFunc -func FindSubpackagesForPaths(matcher pkg.SubpackageMatcher, recurse bool, pkgPaths ...string) ([]string, error) { +func FindSubpackagesForPaths(matcher SubpackageMatcher, recurse bool, pkgPaths ...string) ([]string, error) { uniquePaths := make(map[string]bool) for _, path := range pkgPaths { - paths, err := pkg.Subpackages(filesys.FileSystemOrOnDisk{}, path, matcher, recurse) + paths, err := Subpackages(filesys.FileSystemOrOnDisk{}, path, matcher, recurse) if err != nil { return []string{}, err } @@ -369,7 +368,7 @@ func FormatPackage(pkgPath string) { // subpackages. This is used to format Kptfiles in the order of go structures // TODO: phanimarupaka remove this method after addressing https://github.com/kptdev/kpt/issues/2052 func RoundTripKptfilesInPkg(pkgPath string) error { - paths, err := pkg.Subpackages(filesys.FileSystemOrOnDisk{}, pkgPath, pkg.All, true) + paths, err := Subpackages(filesys.FileSystemOrOnDisk{}, pkgPath, All, true) if err != nil { return err } diff --git a/internal/util/pkgutil/pkgutil_test.go b/pkg/lib/pkg/util_test.go similarity index 94% rename from internal/util/pkgutil/pkgutil_test.go rename to pkg/lib/pkg/util_test.go index 06d1dbaff8..35802ab0a7 100644 --- a/internal/util/pkgutil/pkgutil_test.go +++ b/pkg/lib/pkg/util_test.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package pkgutil_test +package pkg_test import ( "os" @@ -20,11 +20,10 @@ import ( "sort" "testing" - "github.com/kptdev/kpt/internal/pkg" "github.com/kptdev/kpt/internal/testutil" "github.com/kptdev/kpt/internal/testutil/pkgbuilder" - "github.com/kptdev/kpt/internal/util/pkgutil" kptfilev1 "github.com/kptdev/kpt/pkg/api/kptfile/v1" + . "github.com/kptdev/kpt/pkg/lib/pkg" "github.com/stretchr/testify/assert" ) @@ -83,7 +82,7 @@ func TestWalkPackage(t *testing.T) { pkgPath := tc.pkg.ExpandPkg(t, testutil.EmptyReposInfo) var visited []string - if err := pkgutil.WalkPackage(pkgPath, func(s string, _ os.FileInfo, err error) error { + if err := WalkPackage(pkgPath, func(s string, _ os.FileInfo, err error) error { if err != nil { return err } @@ -109,7 +108,7 @@ func TestCopyPackage(t *testing.T) { testCases := map[string]struct { pkg *pkgbuilder.RootPkg copyRootKptfile bool - subpackageMatcher pkg.SubpackageMatcher + subpackageMatcher SubpackageMatcher expected []string }{ "subpackages without root kptfile": { @@ -122,7 +121,7 @@ func TestCopyPackage(t *testing.T) { WithFile("def.yaml", "123"), ), copyRootKptfile: false, - subpackageMatcher: pkg.Local, + subpackageMatcher: Local, expected: []string{ ".", "abc.yaml", @@ -139,7 +138,7 @@ func TestCopyPackage(t *testing.T) { pkgbuilder.NewSubPkg(".git"). WithFile("INDEX", "ABC123"), ), - subpackageMatcher: pkg.None, + subpackageMatcher: None, expected: []string{ ".", "abc.yaml", @@ -156,7 +155,7 @@ func TestCopyPackage(t *testing.T) { WithFile("def.yaml", "123"), ), copyRootKptfile: true, - subpackageMatcher: pkg.None, + subpackageMatcher: None, expected: []string{ ".", "Kptfile", @@ -178,7 +177,7 @@ func TestCopyPackage(t *testing.T) { WithFile("def.yaml", "123"), ), copyRootKptfile: true, - subpackageMatcher: pkg.All, + subpackageMatcher: All, expected: []string{ ".", "Kptfile", @@ -206,7 +205,7 @@ func TestCopyPackage(t *testing.T) { WithFile("def.yaml", "123"), ), copyRootKptfile: true, - subpackageMatcher: pkg.Local, + subpackageMatcher: Local, expected: []string{ ".", "Kptfile", @@ -231,7 +230,7 @@ func TestCopyPackage(t *testing.T) { WithFile("def.yaml", "123"), ), copyRootKptfile: true, - subpackageMatcher: pkg.Remote, + subpackageMatcher: Remote, expected: []string{ ".", "Kptfile", @@ -257,7 +256,7 @@ func TestCopyPackage(t *testing.T) { ), ), copyRootKptfile: true, - subpackageMatcher: pkg.Local, + subpackageMatcher: Local, expected: []string{ ".", "Kptfile", @@ -286,7 +285,7 @@ func TestCopyPackage(t *testing.T) { ), ), copyRootKptfile: true, - subpackageMatcher: pkg.Local, + subpackageMatcher: Local, expected: []string{ ".", "Kptfile", @@ -315,7 +314,7 @@ func TestCopyPackage(t *testing.T) { ), ), copyRootKptfile: true, - subpackageMatcher: pkg.Remote, + subpackageMatcher: Remote, expected: []string{ ".", "Kptfile", @@ -344,7 +343,7 @@ func TestCopyPackage(t *testing.T) { ), ), copyRootKptfile: true, - subpackageMatcher: pkg.Remote, + subpackageMatcher: Remote, expected: []string{ ".", "Kptfile", @@ -365,7 +364,7 @@ func TestCopyPackage(t *testing.T) { pkgPath := tc.pkg.ExpandPkg(t, testutil.EmptyReposInfo) dest := t.TempDir() - err := pkgutil.CopyPackage(pkgPath, dest, tc.copyRootKptfile, tc.subpackageMatcher) + err := CopyPackage(pkgPath, dest, tc.copyRootKptfile, tc.subpackageMatcher) if !assert.NoError(t, err) { t.FailNow() } @@ -538,7 +537,7 @@ func TestFindLocalRecursiveSubpackagesForPaths(t *testing.T) { pkgPaths = append(pkgPaths, p.ExpandPkg(t, testutil.EmptyReposInfo)) } - paths, err := pkgutil.FindSubpackagesForPaths(pkg.Local, true, pkgPaths...) + paths, err := FindSubpackagesForPaths(Local, true, pkgPaths...) if !assert.NoError(t, err) { t.FailNow() } @@ -561,7 +560,7 @@ func TestRemoveStaleItems_RemovesFile(t *testing.T) { assert.NoError(t, os.WriteFile(filepath.Join(dst, fileName), []byte("content"), 0644)) // Should remove file.txt from dst - err := pkgutil.RemoveStaleItems(org, src, dst, true, pkg.All) + err := RemoveStaleItems(org, src, dst, true, All) assert.NoError(t, err) _, err = os.Stat(filepath.Join(dst, fileName)) assert.True(t, os.IsNotExist(err)) @@ -584,7 +583,7 @@ func TestRemoveStaleItems_ErrorOnRemove(t *testing.T) { assert.NoError(t, os.Mkdir(filePathDst, 0755)) assert.NoError(t, os.WriteFile(filepath.Join(filePathDst, "dummy"), []byte("x"), 0644)) - err := pkgutil.RemoveStaleItems(org, src, dst, true, pkg.All) + err := RemoveStaleItems(org, src, dst, true, All) assert.Error(t, err) assert.Contains(t, err.Error(), "directory not empty") } diff --git a/internal/types/types.go b/pkg/lib/types/types.go similarity index 100% rename from internal/types/types.go rename to pkg/lib/types/types.go diff --git a/internal/util/update/common.go b/pkg/lib/update/common.go similarity index 97% rename from internal/util/update/common.go rename to pkg/lib/update/common.go index 9c854a6841..0de48039e2 100644 --- a/internal/util/update/common.go +++ b/pkg/lib/update/common.go @@ -17,9 +17,9 @@ package update import ( "reflect" - "github.com/kptdev/kpt/internal/types" "github.com/kptdev/kpt/pkg/kptfile/kptfileutil" "github.com/kptdev/kpt/pkg/lib/errors" + "github.com/kptdev/kpt/pkg/lib/types" "sigs.k8s.io/kustomize/kyaml/filesys" ) diff --git a/internal/util/update/copy-merge.go b/pkg/lib/update/copy-merge.go similarity index 83% rename from internal/util/update/copy-merge.go rename to pkg/lib/update/copy-merge.go index 0c06d16bb5..c7d6e5b783 100644 --- a/internal/util/update/copy-merge.go +++ b/pkg/lib/update/copy-merge.go @@ -15,12 +15,11 @@ package update import ( - "github.com/kptdev/kpt/internal/pkg" - "github.com/kptdev/kpt/internal/types" - "github.com/kptdev/kpt/internal/util/pkgutil" "github.com/kptdev/kpt/pkg/kptfile/kptfileutil" "github.com/kptdev/kpt/pkg/lib/errors" - updatetypes "github.com/kptdev/kpt/pkg/lib/update/updatetypes" + "github.com/kptdev/kpt/pkg/lib/pkg" + "github.com/kptdev/kpt/pkg/lib/types" + "github.com/kptdev/kpt/pkg/lib/update/updatetypes" ) // CopyMergeUpdater is responsible for synchronizing the destination package @@ -44,10 +43,10 @@ func (u CopyMergeUpdater) Update(options updatetypes.Options) error { if err := kptfileutil.UpdateKptfile(dst, src, options.OriginPath, true); err != nil { return errors.E(op, types.UniquePath(dst), err) } - if err := pkgutil.CopyPackage(src, dst, options.IsRoot, pkg.All); err != nil { + if err := pkg.CopyPackage(src, dst, options.IsRoot, pkg.All); err != nil { return errors.E(op, types.UniquePath(dst), err) } - if err := pkgutil.RemoveStaleItems(org, src, dst, options.IsRoot, pkg.All); err != nil { + if err := pkg.RemoveStaleItems(org, src, dst, options.IsRoot, pkg.All); err != nil { return errors.E(op, types.UniquePath(dst), err) } return nil diff --git a/internal/util/update/copy-merge_test.go b/pkg/lib/update/copy-merge_test.go similarity index 99% rename from internal/util/update/copy-merge_test.go rename to pkg/lib/update/copy-merge_test.go index edbcd1d473..63eeca0060 100644 --- a/internal/util/update/copy-merge_test.go +++ b/pkg/lib/update/copy-merge_test.go @@ -21,8 +21,8 @@ import ( "github.com/kptdev/kpt/internal/testutil" "github.com/kptdev/kpt/internal/testutil/pkgbuilder" - "github.com/kptdev/kpt/internal/util/update" - updatetypes "github.com/kptdev/kpt/pkg/lib/update/updatetypes" + "github.com/kptdev/kpt/pkg/lib/update" + "github.com/kptdev/kpt/pkg/lib/update/updatetypes" "github.com/stretchr/testify/assert" ) diff --git a/internal/util/update/fastforward.go b/pkg/lib/update/fastforward.go similarity index 91% rename from internal/util/update/fastforward.go rename to pkg/lib/update/fastforward.go index 5c379becc0..fd43a24cec 100644 --- a/internal/util/update/fastforward.go +++ b/pkg/lib/update/fastforward.go @@ -20,14 +20,13 @@ import ( "path/filepath" "slices" - "github.com/kptdev/kpt/internal/pkg" - "github.com/kptdev/kpt/internal/types" - pkgdiff "github.com/kptdev/kpt/internal/util/diff" - "github.com/kptdev/kpt/internal/util/pkgutil" kptfilev1 "github.com/kptdev/kpt/pkg/api/kptfile/v1" "github.com/kptdev/kpt/pkg/kptfile/kptfileutil" "github.com/kptdev/kpt/pkg/lib/errors" - updatetypes "github.com/kptdev/kpt/pkg/lib/update/updatetypes" + "github.com/kptdev/kpt/pkg/lib/pkg" + "github.com/kptdev/kpt/pkg/lib/pkg/diff" + "github.com/kptdev/kpt/pkg/lib/types" + "github.com/kptdev/kpt/pkg/lib/update/updatetypes" "sigs.k8s.io/kustomize/kyaml/filesys" "sigs.k8s.io/kustomize/kyaml/sets" ) @@ -73,7 +72,7 @@ func (u FastForwardUpdater) Update(options updatetypes.Options) error { func (u FastForwardUpdater) checkForLocalChanges(localPath, originalPath string) error { const op errors.Op = "update.checkForLocalChanges" - found, err := pkgutil.Exists(originalPath) + found, err := pkg.Exists(originalPath) if err != nil { return errors.E(op, types.UniquePath(localPath), err) } @@ -81,7 +80,7 @@ func (u FastForwardUpdater) checkForLocalChanges(localPath, originalPath string) return nil } - subPkgPaths, err := pkgutil.FindSubpackagesForPaths(pkg.Local, true, localPath, originalPath) + subPkgPaths, err := pkg.FindSubpackagesForPaths(pkg.Local, true, localPath, originalPath) if err != nil { return errors.E(op, types.UniquePath(localPath), err) } @@ -90,11 +89,11 @@ func (u FastForwardUpdater) checkForLocalChanges(localPath, originalPath string) localSubPkgPath := filepath.Join(localPath, subPkgPath) originalSubPkgPath := filepath.Join(originalPath, subPkgPath) - localExists, err := pkgutil.Exists(localSubPkgPath) + localExists, err := pkg.Exists(localSubPkgPath) if err != nil { return errors.E(op, types.UniquePath(localSubPkgPath), err) } - originalExists, err := pkgutil.Exists(originalSubPkgPath) + originalExists, err := pkg.Exists(originalSubPkgPath) if err != nil { return errors.E(op, types.UniquePath(localSubPkgPath), err) } @@ -102,7 +101,7 @@ func (u FastForwardUpdater) checkForLocalChanges(localPath, originalPath string) aggDiff.Insert("%s (Package)", subPkgPath) continue } - d, err := pkgdiff.PkgDiff(localSubPkgPath, originalSubPkgPath) + d, err := diff.PkgDiff(localSubPkgPath, originalSubPkgPath) if err != nil { return errors.E(op, types.UniquePath(localSubPkgPath), err) } diff --git a/internal/util/update/fastforward_test.go b/pkg/lib/update/fastforward_test.go similarity index 99% rename from internal/util/update/fastforward_test.go rename to pkg/lib/update/fastforward_test.go index f37a4847fa..079a2540eb 100644 --- a/internal/util/update/fastforward_test.go +++ b/pkg/lib/update/fastforward_test.go @@ -21,8 +21,8 @@ import ( "github.com/kptdev/kpt/internal/testutil" "github.com/kptdev/kpt/internal/testutil/pkgbuilder" - "github.com/kptdev/kpt/internal/util/update" kptfilev1 "github.com/kptdev/kpt/pkg/api/kptfile/v1" + "github.com/kptdev/kpt/pkg/lib/update" "github.com/kptdev/kpt/pkg/lib/update/updatetypes" "github.com/stretchr/testify/assert" ) diff --git a/internal/util/update/merge3/MergeTestResources.go b/pkg/lib/update/merge3/MergeTestResources.go similarity index 100% rename from internal/util/update/merge3/MergeTestResources.go rename to pkg/lib/update/merge3/MergeTestResources.go diff --git a/internal/util/update/merge3/merge3.go b/pkg/lib/update/merge3/merge3.go similarity index 100% rename from internal/util/update/merge3/merge3.go rename to pkg/lib/update/merge3/merge3.go diff --git a/internal/util/update/merge3/merge3_test.go b/pkg/lib/update/merge3/merge3_test.go similarity index 100% rename from internal/util/update/merge3/merge3_test.go rename to pkg/lib/update/merge3/merge3_test.go diff --git a/internal/util/update/merge3/merge3_util_test.go b/pkg/lib/update/merge3/merge3_util_test.go similarity index 100% rename from internal/util/update/merge3/merge3_util_test.go rename to pkg/lib/update/merge3/merge3_util_test.go diff --git a/internal/util/update/merge3/resource_matcher.go b/pkg/lib/update/merge3/resource_matcher.go similarity index 100% rename from internal/util/update/merge3/resource_matcher.go rename to pkg/lib/update/merge3/resource_matcher.go diff --git a/internal/util/update/merge3/schema.go b/pkg/lib/update/merge3/schema.go similarity index 100% rename from internal/util/update/merge3/schema.go rename to pkg/lib/update/merge3/schema.go diff --git a/internal/util/update/merge3/strategy.go b/pkg/lib/update/merge3/strategy.go similarity index 98% rename from internal/util/update/merge3/strategy.go rename to pkg/lib/update/merge3/strategy.go index 854da15f0c..786bf962d2 100644 --- a/internal/util/update/merge3/strategy.go +++ b/pkg/lib/update/merge3/strategy.go @@ -16,7 +16,7 @@ package merge3 import ( - "github.com/kptdev/kpt/internal/util/attribution" + "github.com/kptdev/kpt/pkg/lib/util/attribution" "sigs.k8s.io/kustomize/kyaml/kio/filters" "sigs.k8s.io/kustomize/kyaml/kio/kioutil" "sigs.k8s.io/kustomize/kyaml/yaml" diff --git a/internal/util/update/merge3/strategy_test.go b/pkg/lib/update/merge3/strategy_test.go similarity index 100% rename from internal/util/update/merge3/strategy_test.go rename to pkg/lib/update/merge3/strategy_test.go diff --git a/internal/util/update/merge3/testdata/infer-crd-empty-dest/destination.yaml b/pkg/lib/update/merge3/testdata/infer-crd-empty-dest/destination.yaml similarity index 100% rename from internal/util/update/merge3/testdata/infer-crd-empty-dest/destination.yaml rename to pkg/lib/update/merge3/testdata/infer-crd-empty-dest/destination.yaml diff --git a/internal/util/update/merge3/testdata/infer-crd-empty-dest/original.yaml b/pkg/lib/update/merge3/testdata/infer-crd-empty-dest/original.yaml similarity index 100% rename from internal/util/update/merge3/testdata/infer-crd-empty-dest/original.yaml rename to pkg/lib/update/merge3/testdata/infer-crd-empty-dest/original.yaml diff --git a/internal/util/update/merge3/testdata/infer-crd-empty-dest/updated.yaml b/pkg/lib/update/merge3/testdata/infer-crd-empty-dest/updated.yaml similarity index 100% rename from internal/util/update/merge3/testdata/infer-crd-empty-dest/updated.yaml rename to pkg/lib/update/merge3/testdata/infer-crd-empty-dest/updated.yaml diff --git a/internal/util/update/merge3/testdata/infer-crd-empty-orig/destination.yaml b/pkg/lib/update/merge3/testdata/infer-crd-empty-orig/destination.yaml similarity index 100% rename from internal/util/update/merge3/testdata/infer-crd-empty-orig/destination.yaml rename to pkg/lib/update/merge3/testdata/infer-crd-empty-orig/destination.yaml diff --git a/internal/util/update/merge3/testdata/infer-crd-empty-orig/original.yaml b/pkg/lib/update/merge3/testdata/infer-crd-empty-orig/original.yaml similarity index 100% rename from internal/util/update/merge3/testdata/infer-crd-empty-orig/original.yaml rename to pkg/lib/update/merge3/testdata/infer-crd-empty-orig/original.yaml diff --git a/internal/util/update/merge3/testdata/infer-crd-empty-orig/updated.yaml b/pkg/lib/update/merge3/testdata/infer-crd-empty-orig/updated.yaml similarity index 100% rename from internal/util/update/merge3/testdata/infer-crd-empty-orig/updated.yaml rename to pkg/lib/update/merge3/testdata/infer-crd-empty-orig/updated.yaml diff --git a/internal/util/update/merge3/testdata/infer-crd-empty-updated/destination.yaml b/pkg/lib/update/merge3/testdata/infer-crd-empty-updated/destination.yaml similarity index 100% rename from internal/util/update/merge3/testdata/infer-crd-empty-updated/destination.yaml rename to pkg/lib/update/merge3/testdata/infer-crd-empty-updated/destination.yaml diff --git a/internal/util/update/merge3/testdata/infer-crd-empty-updated/original.yaml b/pkg/lib/update/merge3/testdata/infer-crd-empty-updated/original.yaml similarity index 100% rename from internal/util/update/merge3/testdata/infer-crd-empty-updated/original.yaml rename to pkg/lib/update/merge3/testdata/infer-crd-empty-updated/original.yaml diff --git a/internal/util/update/merge3/testdata/infer-crd-empty-updated/updated.yaml b/pkg/lib/update/merge3/testdata/infer-crd-empty-updated/updated.yaml similarity index 100% rename from internal/util/update/merge3/testdata/infer-crd-empty-updated/updated.yaml rename to pkg/lib/update/merge3/testdata/infer-crd-empty-updated/updated.yaml diff --git a/internal/util/update/merge3/testdata/infer-crd/destination.yaml b/pkg/lib/update/merge3/testdata/infer-crd/destination.yaml similarity index 100% rename from internal/util/update/merge3/testdata/infer-crd/destination.yaml rename to pkg/lib/update/merge3/testdata/infer-crd/destination.yaml diff --git a/internal/util/update/merge3/testdata/infer-crd/original.yaml b/pkg/lib/update/merge3/testdata/infer-crd/original.yaml similarity index 100% rename from internal/util/update/merge3/testdata/infer-crd/original.yaml rename to pkg/lib/update/merge3/testdata/infer-crd/original.yaml diff --git a/internal/util/update/merge3/testdata/infer-crd/updated.yaml b/pkg/lib/update/merge3/testdata/infer-crd/updated.yaml similarity index 100% rename from internal/util/update/merge3/testdata/infer-crd/updated.yaml rename to pkg/lib/update/merge3/testdata/infer-crd/updated.yaml diff --git a/internal/util/update/merge3/testdata/one-key-crd-empty-dest/destination.yaml b/pkg/lib/update/merge3/testdata/one-key-crd-empty-dest/destination.yaml similarity index 100% rename from internal/util/update/merge3/testdata/one-key-crd-empty-dest/destination.yaml rename to pkg/lib/update/merge3/testdata/one-key-crd-empty-dest/destination.yaml diff --git a/internal/util/update/merge3/testdata/one-key-crd-empty-dest/fruitstore.crd.yaml b/pkg/lib/update/merge3/testdata/one-key-crd-empty-dest/fruitstore.crd.yaml similarity index 100% rename from internal/util/update/merge3/testdata/one-key-crd-empty-dest/fruitstore.crd.yaml rename to pkg/lib/update/merge3/testdata/one-key-crd-empty-dest/fruitstore.crd.yaml diff --git a/internal/util/update/merge3/testdata/one-key-crd-empty-dest/original.yaml b/pkg/lib/update/merge3/testdata/one-key-crd-empty-dest/original.yaml similarity index 100% rename from internal/util/update/merge3/testdata/one-key-crd-empty-dest/original.yaml rename to pkg/lib/update/merge3/testdata/one-key-crd-empty-dest/original.yaml diff --git a/internal/util/update/merge3/testdata/one-key-crd-empty-dest/updated.yaml b/pkg/lib/update/merge3/testdata/one-key-crd-empty-dest/updated.yaml similarity index 100% rename from internal/util/update/merge3/testdata/one-key-crd-empty-dest/updated.yaml rename to pkg/lib/update/merge3/testdata/one-key-crd-empty-dest/updated.yaml diff --git a/internal/util/update/merge3/testdata/one-key-crd-empty-orig/destination.yaml b/pkg/lib/update/merge3/testdata/one-key-crd-empty-orig/destination.yaml similarity index 100% rename from internal/util/update/merge3/testdata/one-key-crd-empty-orig/destination.yaml rename to pkg/lib/update/merge3/testdata/one-key-crd-empty-orig/destination.yaml diff --git a/internal/util/update/merge3/testdata/one-key-crd-empty-orig/fruitstore.crd.yaml b/pkg/lib/update/merge3/testdata/one-key-crd-empty-orig/fruitstore.crd.yaml similarity index 100% rename from internal/util/update/merge3/testdata/one-key-crd-empty-orig/fruitstore.crd.yaml rename to pkg/lib/update/merge3/testdata/one-key-crd-empty-orig/fruitstore.crd.yaml diff --git a/internal/util/update/merge3/testdata/one-key-crd-empty-orig/original.yaml b/pkg/lib/update/merge3/testdata/one-key-crd-empty-orig/original.yaml similarity index 100% rename from internal/util/update/merge3/testdata/one-key-crd-empty-orig/original.yaml rename to pkg/lib/update/merge3/testdata/one-key-crd-empty-orig/original.yaml diff --git a/internal/util/update/merge3/testdata/one-key-crd-empty-orig/updated.yaml b/pkg/lib/update/merge3/testdata/one-key-crd-empty-orig/updated.yaml similarity index 100% rename from internal/util/update/merge3/testdata/one-key-crd-empty-orig/updated.yaml rename to pkg/lib/update/merge3/testdata/one-key-crd-empty-orig/updated.yaml diff --git a/internal/util/update/merge3/testdata/one-key-crd-empty-updated/destination.yaml b/pkg/lib/update/merge3/testdata/one-key-crd-empty-updated/destination.yaml similarity index 100% rename from internal/util/update/merge3/testdata/one-key-crd-empty-updated/destination.yaml rename to pkg/lib/update/merge3/testdata/one-key-crd-empty-updated/destination.yaml diff --git a/internal/util/update/merge3/testdata/one-key-crd-empty-updated/fruitstore.crd.yaml b/pkg/lib/update/merge3/testdata/one-key-crd-empty-updated/fruitstore.crd.yaml similarity index 100% rename from internal/util/update/merge3/testdata/one-key-crd-empty-updated/fruitstore.crd.yaml rename to pkg/lib/update/merge3/testdata/one-key-crd-empty-updated/fruitstore.crd.yaml diff --git a/internal/util/update/merge3/testdata/one-key-crd-empty-updated/original.yaml b/pkg/lib/update/merge3/testdata/one-key-crd-empty-updated/original.yaml similarity index 100% rename from internal/util/update/merge3/testdata/one-key-crd-empty-updated/original.yaml rename to pkg/lib/update/merge3/testdata/one-key-crd-empty-updated/original.yaml diff --git a/internal/util/update/merge3/testdata/one-key-crd-empty-updated/updated.yaml b/pkg/lib/update/merge3/testdata/one-key-crd-empty-updated/updated.yaml similarity index 100% rename from internal/util/update/merge3/testdata/one-key-crd-empty-updated/updated.yaml rename to pkg/lib/update/merge3/testdata/one-key-crd-empty-updated/updated.yaml diff --git a/internal/util/update/merge3/testdata/one-key-crd/destination.yaml b/pkg/lib/update/merge3/testdata/one-key-crd/destination.yaml similarity index 100% rename from internal/util/update/merge3/testdata/one-key-crd/destination.yaml rename to pkg/lib/update/merge3/testdata/one-key-crd/destination.yaml diff --git a/internal/util/update/merge3/testdata/one-key-crd/fruitstore.crd.yaml b/pkg/lib/update/merge3/testdata/one-key-crd/fruitstore.crd.yaml similarity index 100% rename from internal/util/update/merge3/testdata/one-key-crd/fruitstore.crd.yaml rename to pkg/lib/update/merge3/testdata/one-key-crd/fruitstore.crd.yaml diff --git a/internal/util/update/merge3/testdata/one-key-crd/original.yaml b/pkg/lib/update/merge3/testdata/one-key-crd/original.yaml similarity index 100% rename from internal/util/update/merge3/testdata/one-key-crd/original.yaml rename to pkg/lib/update/merge3/testdata/one-key-crd/original.yaml diff --git a/internal/util/update/merge3/testdata/one-key-crd/updated.yaml b/pkg/lib/update/merge3/testdata/one-key-crd/updated.yaml similarity index 100% rename from internal/util/update/merge3/testdata/one-key-crd/updated.yaml rename to pkg/lib/update/merge3/testdata/one-key-crd/updated.yaml diff --git a/internal/util/update/merge3/testdata/simple-conflict/destination.yaml b/pkg/lib/update/merge3/testdata/simple-conflict/destination.yaml similarity index 100% rename from internal/util/update/merge3/testdata/simple-conflict/destination.yaml rename to pkg/lib/update/merge3/testdata/simple-conflict/destination.yaml diff --git a/internal/util/update/merge3/testdata/simple-conflict/original.yaml b/pkg/lib/update/merge3/testdata/simple-conflict/original.yaml similarity index 100% rename from internal/util/update/merge3/testdata/simple-conflict/original.yaml rename to pkg/lib/update/merge3/testdata/simple-conflict/original.yaml diff --git a/internal/util/update/merge3/testdata/simple-conflict/updated.yaml b/pkg/lib/update/merge3/testdata/simple-conflict/updated.yaml similarity index 100% rename from internal/util/update/merge3/testdata/simple-conflict/updated.yaml rename to pkg/lib/update/merge3/testdata/simple-conflict/updated.yaml diff --git a/internal/util/update/merge3/testdata/simple-subpackage-conflict/destination.yaml b/pkg/lib/update/merge3/testdata/simple-subpackage-conflict/destination.yaml similarity index 100% rename from internal/util/update/merge3/testdata/simple-subpackage-conflict/destination.yaml rename to pkg/lib/update/merge3/testdata/simple-subpackage-conflict/destination.yaml diff --git a/internal/util/update/merge3/testdata/simple-subpackage-conflict/original.yaml b/pkg/lib/update/merge3/testdata/simple-subpackage-conflict/original.yaml similarity index 100% rename from internal/util/update/merge3/testdata/simple-subpackage-conflict/original.yaml rename to pkg/lib/update/merge3/testdata/simple-subpackage-conflict/original.yaml diff --git a/internal/util/update/merge3/testdata/simple-subpackage-conflict/updated.yaml b/pkg/lib/update/merge3/testdata/simple-subpackage-conflict/updated.yaml similarity index 100% rename from internal/util/update/merge3/testdata/simple-subpackage-conflict/updated.yaml rename to pkg/lib/update/merge3/testdata/simple-subpackage-conflict/updated.yaml diff --git a/internal/util/update/merge3/tuple.go b/pkg/lib/update/merge3/tuple.go similarity index 100% rename from internal/util/update/merge3/tuple.go rename to pkg/lib/update/merge3/tuple.go diff --git a/pkg/lib/update/pruninglocalpackagereader.go b/pkg/lib/update/pruninglocalpackagereader.go new file mode 100644 index 0000000000..1358e000e8 --- /dev/null +++ b/pkg/lib/update/pruninglocalpackagereader.go @@ -0,0 +1,51 @@ +package update + +import ( + "strings" + + "sigs.k8s.io/kustomize/kyaml/kio" + "sigs.k8s.io/kustomize/kyaml/kio/kioutil" + "sigs.k8s.io/kustomize/kyaml/yaml" +) + +// PruningLocalPackageReader implements the Reader interface. It is similar +// to the LocalPackageReader but allows for exclusion of subdirectories. +type PruningLocalPackageReader struct { + LocalPackageReader kio.LocalPackageReader + Exclusions []string +} + +func (p PruningLocalPackageReader) Read() ([]*yaml.RNode, error) { + // Delegate reading the resources to the LocalPackageReader. + nodes, err := p.LocalPackageReader.Read() + if err != nil { + return nil, err + } + + // Exclude any resources that exist underneath an excluded path. + var filteredNodes []*yaml.RNode + for _, node := range nodes { + if err := kioutil.CopyLegacyAnnotations(node); err != nil { + return nil, err + } + n, err := node.Pipe(yaml.GetAnnotation(kioutil.PathAnnotation)) + if err != nil { + return nil, err + } + path := n.YNode().Value + if p.isExcluded(path) { + continue + } + filteredNodes = append(filteredNodes, node) + } + return filteredNodes, nil +} + +func (p PruningLocalPackageReader) isExcluded(path string) bool { + for _, e := range p.Exclusions { + if strings.HasPrefix(path, e) { + return true + } + } + return false +} diff --git a/internal/util/update/replace.go b/pkg/lib/update/replace.go similarity index 83% rename from internal/util/update/replace.go rename to pkg/lib/update/replace.go index a59e118214..85fbed98e0 100644 --- a/internal/util/update/replace.go +++ b/pkg/lib/update/replace.go @@ -18,12 +18,11 @@ import ( "os" "path/filepath" - "github.com/kptdev/kpt/internal/pkg" - "github.com/kptdev/kpt/internal/types" - "github.com/kptdev/kpt/internal/util/pkgutil" "github.com/kptdev/kpt/pkg/kptfile/kptfileutil" "github.com/kptdev/kpt/pkg/lib/errors" - updatetypes "github.com/kptdev/kpt/pkg/lib/update/updatetypes" + "github.com/kptdev/kpt/pkg/lib/pkg" + "github.com/kptdev/kpt/pkg/lib/types" + "github.com/kptdev/kpt/pkg/lib/update/updatetypes" ) // Updater updates a package to a new upstream version. @@ -42,7 +41,7 @@ func (u ReplaceUpdater) Update(options updatetypes.Options) error { return errors.E(op, types.UniquePath(options.LocalPath), err) } - paths, err := pkgutil.FindSubpackagesForPaths(pkg.Local, true, options.LocalPath, options.UpdatedPath) + paths, err := pkg.FindSubpackagesForPaths(pkg.Local, true, options.LocalPath, options.UpdatedPath) if err != nil { return errors.E(op, types.UniquePath(options.LocalPath), err) } @@ -54,7 +53,7 @@ func (u ReplaceUpdater) Update(options updatetypes.Options) error { } localSubPkgPath := filepath.Join(options.LocalPath, p) updatedSubPkgPath := filepath.Join(options.UpdatedPath, p) - err = pkgutil.RemovePackageContent(localSubPkgPath, !isRootPkg) + err = pkg.RemovePackageContent(localSubPkgPath, !isRootPkg) if err != nil { return errors.E(op, types.UniquePath(localSubPkgPath), err) } @@ -71,7 +70,7 @@ func (u ReplaceUpdater) Update(options updatetypes.Options) error { return errors.E(op, types.UniquePath(localSubPkgPath), err) } } else { - if err = pkgutil.CopyPackage(updatedSubPkgPath, localSubPkgPath, !isRootPkg, pkg.None); err != nil { + if err = pkg.CopyPackage(updatedSubPkgPath, localSubPkgPath, !isRootPkg, pkg.None); err != nil { return errors.E(op, types.UniquePath(localSubPkgPath), err) } } diff --git a/internal/util/update/replace_test.go b/pkg/lib/update/replace_test.go similarity index 98% rename from internal/util/update/replace_test.go rename to pkg/lib/update/replace_test.go index 64b320a4e5..10733fe222 100644 --- a/internal/util/update/replace_test.go +++ b/pkg/lib/update/replace_test.go @@ -21,8 +21,8 @@ import ( "github.com/kptdev/kpt/internal/testutil" "github.com/kptdev/kpt/internal/testutil/pkgbuilder" - "github.com/kptdev/kpt/internal/util/update" - updatetypes "github.com/kptdev/kpt/pkg/lib/update/updatetypes" + "github.com/kptdev/kpt/pkg/lib/update" + "github.com/kptdev/kpt/pkg/lib/update/updatetypes" "github.com/stretchr/testify/assert" ) diff --git a/internal/util/update/resource-merge.go b/pkg/lib/update/resource-merge.go similarity index 92% rename from internal/util/update/resource-merge.go rename to pkg/lib/update/resource-merge.go index c9d0c05af1..b54e229ecf 100644 --- a/internal/util/update/resource-merge.go +++ b/pkg/lib/update/resource-merge.go @@ -21,18 +21,16 @@ import ( "path/filepath" "strings" + "github.com/kptdev/kpt/pkg/lib/pkg/diff" + "github.com/kptdev/kpt/pkg/lib/types" + merge4 "github.com/kptdev/kpt/pkg/lib/update/merge3" "sigs.k8s.io/kustomize/kyaml/pathutil" - "github.com/kptdev/kpt/internal/pkg" - "github.com/kptdev/kpt/internal/types" - pkgdiff "github.com/kptdev/kpt/internal/util/diff" - "github.com/kptdev/kpt/internal/util/merge" - "github.com/kptdev/kpt/internal/util/pkgutil" - "github.com/kptdev/kpt/internal/util/update/merge3" kptfilev1 "github.com/kptdev/kpt/pkg/api/kptfile/v1" "github.com/kptdev/kpt/pkg/kptfile/kptfileutil" "github.com/kptdev/kpt/pkg/lib/errors" - updatetypes "github.com/kptdev/kpt/pkg/lib/update/updatetypes" + "github.com/kptdev/kpt/pkg/lib/pkg" + "github.com/kptdev/kpt/pkg/lib/update/updatetypes" "github.com/kptdev/krm-functions-sdk/go/fn" "gopkg.in/yaml.v2" "k8s.io/klog/v2" @@ -66,7 +64,7 @@ func (u ResourceMergeUpdater) Update(options updatetypes.Options) error { // Find all subpackages in local, upstream and original. They are sorted // in increasing order based on the depth of the subpackage relative to the // root package. - subPkgPaths, err := pkgutil.FindSubpackagesForPaths(pkg.Local, true, + subPkgPaths, err := pkg.FindSubpackagesForPaths(pkg.Local, true, options.LocalPath, options.UpdatedPath, options.OriginPath) if err != nil { return errors.E(op, types.UniquePath(options.LocalPath), err) @@ -96,17 +94,17 @@ func (u ResourceMergeUpdater) Update(options updatetypes.Options) error { // original version of the package. func (u ResourceMergeUpdater) updatePackage(subPkgPath, localPath, updatedPath, originalPath string, isRootPkg bool) error { const op errors.Op = "update.updatePackage" - localExists, err := pkgutil.Exists(localPath) + localExists, err := pkg.Exists(localPath) if err != nil { return errors.E(op, types.UniquePath(localPath), err) } - updatedExists, err := pkgutil.Exists(updatedPath) + updatedExists, err := pkg.Exists(updatedPath) if err != nil { return errors.E(op, types.UniquePath(localPath), err) } - originalExists, err := pkgutil.Exists(originalPath) + originalExists, err := pkg.Exists(originalPath) if err != nil { return errors.E(op, types.UniquePath(localPath), err) } @@ -118,7 +116,7 @@ func (u ResourceMergeUpdater) updatePackage(subPkgPath, localPath, updatedPath, fmt.Errorf("subpackage %q added in both upstream and local", subPkgPath)) // Package added in upstream case !originalExists && !localExists && updatedExists: - if err := pkgutil.CopyPackage(updatedPath, localPath, !isRootPkg, pkg.None); err != nil { + if err := pkg.CopyPackage(updatedPath, localPath, !isRootPkg, pkg.None); err != nil { return errors.E(op, types.UniquePath(localPath), err) } // Package added locally @@ -134,7 +132,7 @@ func (u ResourceMergeUpdater) updatePackage(subPkgPath, localPath, updatedPath, // Package deleted from upstream case originalExists && localExists && !updatedExists: // Check the diff. If there are local changes, we keep the subpackage. - diff, err := pkgdiff.PkgDiff(originalPath, localPath) + diff, err := diff.PkgDiff(originalPath, localPath) if err != nil { return errors.E(op, types.UniquePath(localPath), err) } @@ -168,7 +166,7 @@ func (u ResourceMergeUpdater) mergePackage(localPath, updatedPath, originalPath, return err } - mergedKos, err := merge3.Merge( + mergedKos, err := merge4.Merge( originalKos, updatedKos, destinationKos, crdSchemas, ) if err != nil { @@ -287,7 +285,7 @@ func getSubDirsAndNonKrmFiles(root string) (sets.String, sets.String, error) { const op errors.Op = "update.getSubDirsAndNonKrmFiles" files := sets.String{} dirs := sets.String{} - err := pkgutil.WalkPackage(root, func(path string, info os.FileInfo, err error) error { + err := pkg.WalkPackage(root, func(path string, info os.FileInfo, err error) error { if err != nil { return errors.E(op, errors.IO, err) } @@ -372,8 +370,8 @@ func getCrdSchemas(updated fn.KubeObjects, destination fn.KubeObjects) ([]byte, var kubeobjects fn.KubeObjects copy(kubeobjects, updated) kubeobjects = append(kubeobjects, destination...) - _, crdObjects := merge3.FilterCrds(kubeobjects) - crdSchemas, err := merge3.SchemasFromCrdKubeObjects(crdObjects) + _, crdObjects := merge4.FilterCrds(kubeobjects) + crdSchemas, err := merge4.SchemasFromCrdKubeObjects(crdObjects) if err != nil { klog.Error("An error occurred during CRD extraction: %w", err) return nil, nil @@ -392,7 +390,7 @@ func loadResourcesFromDirectory(directoryPath string, mergeSourceAnnotation stri if err != nil { return nil, err } - reader := merge.PruningLocalPackageReader{ + reader := PruningLocalPackageReader{ LocalPackageReader: kio.LocalPackageReader{ PackagePath: directoryPath, IncludeSubpackages: false, diff --git a/internal/util/update/resource-merge_test.go b/pkg/lib/update/resource-merge_test.go similarity index 98% rename from internal/util/update/resource-merge_test.go rename to pkg/lib/update/resource-merge_test.go index 011f92ce63..b68072d607 100644 --- a/internal/util/update/resource-merge_test.go +++ b/pkg/lib/update/resource-merge_test.go @@ -21,8 +21,8 @@ import ( "github.com/kptdev/kpt/internal/testutil" "github.com/kptdev/kpt/internal/testutil/pkgbuilder" - "github.com/kptdev/kpt/internal/util/update" - updatetypes "github.com/kptdev/kpt/pkg/lib/update/updatetypes" + "github.com/kptdev/kpt/pkg/lib/update" + "github.com/kptdev/kpt/pkg/lib/update/updatetypes" "github.com/stretchr/testify/assert" ) diff --git a/pkg/lib/update/update.go b/pkg/lib/update/update.go index dfd14e26f6..b5c5483935 100644 --- a/pkg/lib/update/update.go +++ b/pkg/lib/update/update.go @@ -1,4 +1,4 @@ -// Copyright 2026 The kpt Authors +// Copyright 2019,2026 The kpt Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -12,14 +12,481 @@ // See the License for the specific language governing permissions and // limitations under the License. -// Package update returns a kpt updating function to a user +// Package update contains libraries for updating packages. package update import ( - internalupdate "github.com/kptdev/kpt/internal/util/update" - updatetypes "github.com/kptdev/kpt/pkg/lib/update/updatetypes" + "context" + "fmt" + "os" + "path" + "path/filepath" + "strings" + + git2 "github.com/kptdev/kpt/internal/gitutil" + kptfilev1 "github.com/kptdev/kpt/pkg/api/kptfile/v1" + "github.com/kptdev/kpt/pkg/kptfile/kptfileutil" + "github.com/kptdev/kpt/pkg/lib/errors" + "github.com/kptdev/kpt/pkg/lib/pkg" + "github.com/kptdev/kpt/pkg/lib/types" + "github.com/kptdev/kpt/pkg/lib/update/updatetypes" + "github.com/kptdev/kpt/pkg/lib/util/addmergecomment" + "github.com/kptdev/kpt/pkg/lib/util/fetch" + "github.com/kptdev/kpt/pkg/lib/util/git" + "github.com/kptdev/kpt/pkg/lib/util/stack" + "github.com/kptdev/kpt/pkg/printer" + "sigs.k8s.io/kustomize/kyaml/copyutil" + "sigs.k8s.io/kustomize/kyaml/filesys" ) +// PkgNotGitRepoError is the error type returned if the package being updated is not inside +// a git repository. +type PkgNotGitRepoError struct { + Path types.UniquePath +} + +func (p *PkgNotGitRepoError) Error() string { + return fmt.Sprintf("package %q is not a git repository", p.Path.String()) +} + +// PkgRepoDirtyError is the error type returned if the package being updated contains +// uncommitted changes. +type PkgRepoDirtyError struct { + Path types.UniquePath +} + +func (p *PkgRepoDirtyError) Error() string { + return fmt.Sprintf("package %q contains uncommitted changes", p.Path.String()) +} + +type Options struct { + // RelPackagePath is the relative path of a subpackage to the root. If the + // package is root, the value here will be ".". + RelPackagePath string + + // LocalPath is the absolute path to the package on the local fork. + LocalPath string + + // OriginPath is the absolute path to the package in the on-disk clone + // of the origin ref of the repo. + OriginPath string + + // UpdatedPath is the absolute path to the package in the on-disk clone + // of the updated ref of the repo. + UpdatedPath string + + // IsRoot is true if the package is the root, i.e. the clones of + // updated and origin were fetched based on the information in the + // Kptfile from this package. + IsRoot bool +} + +// Updater updates a local package +var strategies = map[kptfilev1.UpdateStrategyType]func() updatetypes.Updater{ + kptfilev1.FastForward: func() updatetypes.Updater { return FastForwardUpdater{} }, + kptfilev1.ForceDeleteReplace: func() updatetypes.Updater { return ReplaceUpdater{} }, + kptfilev1.ResourceMerge: func() updatetypes.Updater { return ResourceMergeUpdater{} }, + kptfilev1.CopyMerge: func() updatetypes.Updater { return CopyMergeUpdater{} }, +} + +// Command updates the contents of a local package to a different version. +type Command struct { + // Pkg captures information about the package that should be updated. + Pkg *pkg.Pkg + + // Ref is the ref to update to + Ref string + + // Strategy is the update strategy to use + Strategy kptfilev1.UpdateStrategyType + + // cachedUpstreamRepos is an upstream repo already fetched for a given repoSpec CloneRef + cachedUpstreamRepos map[string]*git2.GitUpstreamRepo +} + func GetUpdater(strategy string) updatetypes.Updater { - return internalupdate.GetUpdater(strategy) + switch strategy { + case "fast-forward": + return FastForwardUpdater{} + case "force-delete-replace": + return ReplaceUpdater{} + case "copy-merge": + return CopyMergeUpdater{} + default: + return ResourceMergeUpdater{} + } +} + +// Run runs the Command. +func (u *Command) Run(ctx context.Context) error { + const op errors.Op = "update.Run" + pr := printer.FromContextOrDie(ctx) + + if u.Pkg == nil { + return errors.E(op, errors.MissingParam, "pkg must be provided") + } + + rootKf, err := u.Pkg.Kptfile() + if err != nil { + return errors.E(op, u.Pkg.UniquePath, err) + } + + if rootKf.Upstream == nil || rootKf.Upstream.Git == nil { + return errors.E(op, u.Pkg.UniquePath, + fmt.Errorf("package must have an upstream reference")) + } + originalRootKfRef := rootKf.Upstream.Git.Ref + if u.Ref != "" { + rootKf.Upstream.Git.Ref = u.Ref + } + if u.Strategy != "" { + rootKf.Upstream.UpdateStrategy = u.Strategy + } + err = kptfileutil.WriteFile(u.Pkg.UniquePath.String(), rootKf) + if err != nil { + return errors.E(op, u.Pkg.UniquePath, err) + } + if u.cachedUpstreamRepos == nil { + u.cachedUpstreamRepos = make(map[string]*git2.GitUpstreamRepo) + } + packageCount := 0 + + // Use stack to keep track of paths with a Kptfile that might contain + // information about remote subpackages. + s := stack.NewPkgStack() + s.Push(u.Pkg) + + for s.Len() > 0 { + p := s.Pop() + packageCount++ + + if err := u.updateRootPackage(ctx, p); err != nil { + return errors.E(op, p.UniquePath, err) + } + + subPkgs, err := p.DirectSubpackages() + if err != nil { + return errors.E(op, p.UniquePath, err) + } + for _, subPkg := range subPkgs { + subKf, err := subPkg.Kptfile() + if err != nil { + return errors.E(op, p.UniquePath, err) + } + + if subKf.Upstream != nil && subKf.Upstream.Git != nil { + // update subpackage kf ref/strategy if current pkg is a subpkg of root pkg or is root pkg + // and if original root pkg ref matches the subpkg ref + if shouldUpdateSubPkgRef(subKf, rootKf, originalRootKfRef) { + updateSubKf(subKf, u.Ref, u.Strategy) + err = kptfileutil.WriteFile(subPkg.UniquePath.String(), subKf) + if err != nil { + return errors.E(op, subPkg.UniquePath, err) + } + } + s.Push(subPkg) + } + } + } + pr.Printf("\nUpdated %d package(s).\n", packageCount) + + // finally, make sure that the merge comments are added to all resources in the updated package + if err := addmergecomment.Process(string(u.Pkg.UniquePath)); err != nil { + return errors.E(op, u.Pkg.UniquePath, err) + } + return nil +} + +// GetCachedUpstreamRepos returns repos cached during update +func (u Command) GetCachedUpstreamRepos() map[string]*git2.GitUpstreamRepo { + return u.cachedUpstreamRepos +} + +// updateSubKf updates subpackage with given ref and update strategy +func updateSubKf(subKf *kptfilev1.KptFile, ref string, strategy kptfilev1.UpdateStrategyType) { + // check if explicit ref provided + if ref != "" { + subKf.Upstream.Git.Ref = ref + } + if strategy != "" { + subKf.Upstream.UpdateStrategy = strategy + } +} + +// shouldUpdateSubPkgRef checks if subpkg ref should be updated. +// This is true if pkg has the same upstream repo, upstream directory is within or equal to root pkg directory and original root pkg ref matches the subpkg ref. +func shouldUpdateSubPkgRef(subKf, rootKf *kptfilev1.KptFile, originalRootKfRef string) bool { + return subKf.Upstream.Git.Repo == rootKf.Upstream.Git.Repo && + subKf.Upstream.Git.Ref == originalRootKfRef && + strings.HasPrefix(path.Clean(subKf.Upstream.Git.Directory), path.Clean(rootKf.Upstream.Git.Directory)) +} + +// repoClone is an interface that represents a clone of a repo on the local +// disk. +type repoClone interface { + AbsPath() string +} + +// newNilRepoClone creates a new nilRepoClone that implements the repoClone +// interface +func newNilRepoClone() (*nilRepoClone, error) { + const op errors.Op = "update.newNilRepoClone" + dir, err := os.MkdirTemp("", "kpt-empty-") + if err != nil { + return nil, errors.E(op, errors.IO, fmt.Errorf("errors creating a temporary directory: %w", err)) + } + return &nilRepoClone{ + dir: dir, + }, nil +} + +// nilRepoClone is an implementation of the repoClone interface, but that +// just represents an empty directory. This simplifies the logic for update +// since we don't have to special case situations where we don't have +// upstream and/or origin. +type nilRepoClone struct { + dir string +} + +// AbsPath returns the absolute path to the local directory for the repo. For +// the nilRepoClone, this will always be an empty directory. +func (nrc *nilRepoClone) AbsPath() string { + return nrc.dir +} + +// updateRootPackage updates a local package. It will use the information +// about upstream in the Kptfile to fetch upstream and origin, and then +// recursively traverse the hierarchy to add/update/delete packages. +func (u Command) updateRootPackage(ctx context.Context, p *pkg.Pkg) error { + const op errors.Op = "update.updateRootPackage" + kf, err := p.Kptfile() + if err != nil { + return errors.E(op, p.UniquePath, err) + } + + pr := printer.FromContextOrDie(ctx) + pr.PrintPackage(p, p != u.Pkg) + + g := kf.Upstream.Git + updated := &git.RepoSpec{OrgRepo: g.Repo, Path: g.Directory, Ref: g.Ref} + pr.Printf("Fetching upstream from %s@%s\n", kf.Upstream.Git.Repo, kf.Upstream.Git.Ref) + cloner := fetch.NewCloner(updated, fetch.WithCachedRepo(u.cachedUpstreamRepos)) + if err := cloner.ClonerUsingGitExec(ctx); err != nil { + return errors.E(op, p.UniquePath, err) + } + defer os.RemoveAll(updated.AbsPath()) + + var origin repoClone + if kf.UpstreamLock != nil { + gLock := kf.UpstreamLock.Git + originRepoSpec := &git.RepoSpec{OrgRepo: gLock.Repo, Path: gLock.Directory, Ref: gLock.Commit} + pr.Printf("Fetching origin from %s@%s\n", kf.Upstream.Git.Repo, kf.Upstream.Git.Ref) + if err := fetch.NewCloner(originRepoSpec, fetch.WithCachedRepo(u.cachedUpstreamRepos)).ClonerUsingGitExec(ctx); err != nil { + return errors.E(op, p.UniquePath, err) + } + origin = originRepoSpec + } else { + origin, err = newNilRepoClone() + if err != nil { + return errors.E(op, p.UniquePath, err) + } + } + defer os.RemoveAll(origin.AbsPath()) + + s := stack.New() + s.Push(".") + + for s.Len() > 0 { + relPath := s.Pop() + localPath := filepath.Join(p.UniquePath.String(), relPath) + updatedPath := filepath.Join(updated.AbsPath(), relPath) + originPath := filepath.Join(origin.AbsPath(), relPath) + + isRoot := false + if relPath == "." { + isRoot = true + } + + if err := u.updatePackage(ctx, relPath, localPath, updatedPath, originPath, isRoot); err != nil { + return errors.E(op, p.UniquePath, err) + } + + paths, err := pkg.FindSubpackagesForPaths(pkg.Remote, false, + localPath, updatedPath, originPath) + if err != nil { + return errors.E(op, p.UniquePath, err) + } + for _, path := range paths { + s.Push(filepath.Join(relPath, path)) + } + } + + if err := kptfileutil.UpdateUpstreamLockFromGit(p.UniquePath.String(), updated); err != nil { + return errors.E(op, p.UniquePath, err) + } + return nil +} + +// updatePackage takes care of updating a single package. The absolute paths to +// the local, updated and origin packages are provided, as well as the path to the +// package relative to the root. +// The last parameter tells if this package is the root, i.e. the package +// from which we got the information about upstream and origin. +// +//nolint:gocyclo +func (u Command) updatePackage(ctx context.Context, subPkgPath, localPath, updatedPath, originPath string, isRootPkg bool) error { + const op errors.Op = "update.updatePackage" + pr := printer.FromContextOrDie(ctx) + + localExists, err := pkg.IsPackageDir(filesys.FileSystemOrOnDisk{}, localPath) + if err != nil { + return errors.E(op, types.UniquePath(localPath), err) + } + + // We need to handle the root package special here, since the copies + // from updated and origin might not have a Kptfile at the root. + updatedExists := isRootPkg + if !isRootPkg { + updatedExists, err = pkg.IsPackageDir(filesys.FileSystemOrOnDisk{}, updatedPath) + if err != nil { + return errors.E(op, types.UniquePath(localPath), err) + } + } + + originExists := isRootPkg + if !isRootPkg { + originExists, err = pkg.IsPackageDir(filesys.FileSystemOrOnDisk{}, originPath) + if err != nil { + return errors.E(op, types.UniquePath(localPath), err) + } + } + + switch { + case !originExists && !localExists && !updatedExists: + break + // Check if subpackage has been added both in upstream and in local. We + // can't make a sane merge here, so we treat it as an error. + case !originExists && localExists && updatedExists: + pr.Printf("Package %q added in both local and upstream.\n", packageName(localPath)) + return errors.E(op, types.UniquePath(localPath), + fmt.Errorf("subpackage %q added in both upstream and local", subPkgPath)) + + // Package added in upstream. We just copy the package. If the package + // contains any unfetched subpackages, those will be handled when we traverse + // the package hierarchy and that package is the root. + case !originExists && !localExists && updatedExists: + pr.Printf("Adding package %q from upstream.\n", packageName(localPath)) + if err := pkg.CopyPackage(updatedPath, localPath, !isRootPkg, pkg.None); err != nil { + return errors.E(op, types.UniquePath(localPath), err) + } + + // Package added locally, so no action needed. + case !originExists && localExists && !updatedExists: + break + + // Package deleted from both upstream and local, so no action needed. + case originExists && !localExists && !updatedExists: + break + + // Package deleted from local + // In this case we assume the user knows what they are doing, so + // we don't re-add the updated package from upstream. + case originExists && !localExists && updatedExists: + pr.Printf("Ignoring package %q in upstream since it is deleted from local.\n", packageName(localPath)) + + // Package deleted from upstream + case originExists && localExists && !updatedExists: + // Check the diff. If there are local changes, we keep the subpackage. + diff, err := copyutil.Diff(originPath, localPath) + if err != nil { + return errors.E(op, types.UniquePath(localPath), err) + } + if diff.Len() == 0 { + pr.Printf("Deleting package %q from local since it is removed in upstream.\n", packageName(localPath)) + if err := os.RemoveAll(localPath); err != nil { + return errors.E(op, types.UniquePath(localPath), err) + } + } else { + pr.Printf("Package %q deleted from upstream, but keeping local since it has changes.\n", packageName(localPath)) + } + default: + if err := u.mergePackage(ctx, localPath, updatedPath, originPath, subPkgPath, isRootPkg); err != nil { + return errors.E(op, types.UniquePath(localPath), err) + } + } + return nil +} + +func (u Command) mergePackage(ctx context.Context, localPath, updatedPath, originPath, relPath string, isRootPkg bool) error { + const op errors.Op = "update.mergePackage" + pr := printer.FromContextOrDie(ctx) + // at this point, the localPath, updatedPath and originPath exists and are about to be merged + // make sure that the merge comments are added to all of them so that they are merged accurately + if err := addmergecomment.Process(localPath, updatedPath, originPath); err != nil { + return errors.E(op, types.UniquePath(localPath), + fmt.Errorf("failed to add merge comments %q", err.Error())) + } + updatedUnfetched, err := pkg.IsPackageUnfetched(updatedPath) + if err != nil { + if !errors.Is(err, os.ErrNotExist) || !isRootPkg { + return errors.E(op, types.UniquePath(localPath), err) + } + // For root packages, there might not be a Kptfile in the upstream repo. + updatedUnfetched = false + } + + originUnfetched, err := pkg.IsPackageUnfetched(originPath) + if err != nil { + if !errors.Is(err, os.ErrNotExist) || !isRootPkg { + return errors.E(op, types.UniquePath(localPath), err) + } + // For root packages, there might not be a Kptfile in origin. + originUnfetched = false + } + + switch { + case updatedUnfetched && originUnfetched: + fallthrough + case updatedUnfetched && !originUnfetched: + // updated is unfetched, so can't have changes except for Kptfile. + // we can just merge that one. + return kptfileutil.UpdateKptfile(localPath, updatedPath, originPath, true) + case !updatedUnfetched && originUnfetched: + // This means that the package was unfetched when local forked from upstream, + // so the local fork and upstream might have fetched different versions of + // the package. We just return an error here. + // We might be able to compare the commit SHAs from local and updated + // to determine if they share the common upstream and then fetch origin + // using the common commit SHA. But this is a very advanced scenario, + // so we just return the error for now. + return errors.E(op, types.UniquePath(localPath), fmt.Errorf("no origin available for package")) + default: + // Both exists, so just go ahead as normal. + } + + pkgKf, err := kptfileutil.ReadKptfile(filesys.FileSystemOrOnDisk{}, localPath) + if err != nil { + return errors.E(op, types.UniquePath(localPath), err) + } + updater, found := strategies[pkgKf.Upstream.UpdateStrategy] + if !found { + return errors.E(op, types.UniquePath(localPath), + fmt.Errorf("unrecognized update strategy %s", u.Strategy)) + } + pr.Printf("Updating package %q with strategy %q.\n", packageName(localPath), pkgKf.Upstream.UpdateStrategy) + if err := updater().Update(updatetypes.Options{ + RelPackagePath: relPath, + LocalPath: localPath, + UpdatedPath: updatedPath, + OriginPath: originPath, + IsRoot: isRootPkg, + }); err != nil { + return errors.E(op, types.UniquePath(localPath), err) + } + + return nil +} + +func packageName(path string) string { + return filepath.Base(path) } diff --git a/internal/util/update/update_test.go b/pkg/lib/update/update_test.go similarity index 98% rename from internal/util/update/update_test.go rename to pkg/lib/update/update_test.go index c8bb6955f7..230ad6951a 100644 --- a/internal/util/update/update_test.go +++ b/pkg/lib/update/update_test.go @@ -23,12 +23,11 @@ import ( "slices" "testing" - pkgtest "github.com/kptdev/kpt/internal/pkg/testing" "github.com/kptdev/kpt/internal/testutil" "github.com/kptdev/kpt/internal/testutil/pkgbuilder" - "github.com/kptdev/kpt/internal/util/update" kptfilev1 "github.com/kptdev/kpt/pkg/api/kptfile/v1" "github.com/kptdev/kpt/pkg/kptfile/kptfileutil" + update2 "github.com/kptdev/kpt/pkg/lib/update" "github.com/kptdev/kpt/pkg/printer/fake" "github.com/stretchr/testify/assert" "sigs.k8s.io/kustomize/kyaml/copyutil" @@ -75,8 +74,8 @@ func TestCommand_Run_noRefChanges(t *testing.T) { return } upstreamRepo := g.Repos[testutil.Upstream] - cmd := &update.Command{ - Pkg: pkgtest.CreatePkgOrFail(t, g.LocalWorkspace.FullPackagePath()), + cmd := &update2.Command{ + Pkg: testutil.CreatePkgOrFail(t, g.LocalWorkspace.FullPackagePath()), Strategy: strategy, } // Update the local package @@ -138,8 +137,8 @@ func TestCommand_Run_subDir(t *testing.T) { upstreamRepo := g.Repos[testutil.Upstream] // Update the local package - if !assert.NoError(t, (&update.Command{ - Pkg: pkgtest.CreatePkgOrFail(t, g.LocalWorkspace.FullPackagePath()), + if !assert.NoError(t, (&update2.Command{ + Pkg: testutil.CreatePkgOrFail(t, g.LocalWorkspace.FullPackagePath()), Ref: "v1.2", Strategy: strategy, }).Run(fake.CtxWithDefaultPrinter())) { @@ -194,8 +193,8 @@ func TestCommand_Run_noChanges(t *testing.T) { upstreamRepo := g.Repos[testutil.Upstream] // Update the local package - err := (&update.Command{ - Pkg: pkgtest.CreatePkgOrFail(t, g.LocalWorkspace.FullPackagePath()), + err := (&update2.Command{ + Pkg: testutil.CreatePkgOrFail(t, g.LocalWorkspace.FullPackagePath()), Strategy: u.updater, }).Run(fake.CtxWithDefaultPrinter()) if u.err == "" { @@ -376,8 +375,8 @@ func TestCommand_Run_localPackageChanges(t *testing.T) { } // run the command - err = (&update.Command{ - Pkg: pkgtest.CreatePkgOrFail(t, g.LocalWorkspace.FullPackagePath()), + err = (&update2.Command{ + Pkg: testutil.CreatePkgOrFail(t, g.LocalWorkspace.FullPackagePath()), Ref: masterBranch, Strategy: tc.strategy, }).Run(fake.CtxWithDefaultPrinter()) @@ -446,8 +445,8 @@ func TestCommand_Run_toBranchRef(t *testing.T) { upstreamRepo := g.Repos[testutil.Upstream] // Update the local package - if !assert.NoError(t, (&update.Command{ - Pkg: pkgtest.CreatePkgOrFail(t, g.LocalWorkspace.FullPackagePath()), + if !assert.NoError(t, (&update2.Command{ + Pkg: testutil.CreatePkgOrFail(t, g.LocalWorkspace.FullPackagePath()), Strategy: strategy, Ref: "exp", }).Run(fake.CtxWithDefaultPrinter())) { @@ -810,8 +809,8 @@ func TestCommand_Run_toBranchRefWithSubpkgs(t *testing.T) { } // Update the local package - if !assert.NoError(t, (&update.Command{ - Pkg: pkgtest.CreatePkgOrFail(t, path.Join(g.LocalWorkspace.FullPackagePath(), tc.updateSubPkg)), + if !assert.NoError(t, (&update2.Command{ + Pkg: testutil.CreatePkgOrFail(t, path.Join(g.LocalWorkspace.FullPackagePath(), tc.updateSubPkg)), Strategy: tc.strategy, Ref: tc.updateRef, }).Run(fake.CtxWithDefaultPrinter())) { @@ -856,8 +855,8 @@ func TestCommand_Run_toTagRef(t *testing.T) { upstreamRepo := g.Repos[testutil.Upstream] // Update the local package - if !assert.NoError(t, (&update.Command{ - Pkg: pkgtest.CreatePkgOrFail(t, g.LocalWorkspace.FullPackagePath()), + if !assert.NoError(t, (&update2.Command{ + Pkg: testutil.CreatePkgOrFail(t, g.LocalWorkspace.FullPackagePath()), Strategy: strategy, Ref: "v1.0", }).Run(fake.CtxWithDefaultPrinter())) { @@ -913,8 +912,8 @@ func TestCommand_ResourceMerge_NonKRMUpdates(t *testing.T) { upstreamRepo := g.Repos[testutil.Upstream] // Update the local package - if !assert.NoError(t, (&update.Command{ - Pkg: pkgtest.CreatePkgOrFail(t, g.LocalWorkspace.FullPackagePath()), + if !assert.NoError(t, (&update2.Command{ + Pkg: testutil.CreatePkgOrFail(t, g.LocalWorkspace.FullPackagePath()), Strategy: strategy, Ref: "v1.0", }).Run(fake.CtxWithDefaultPrinter())) { @@ -956,8 +955,8 @@ func TestCommand_Run_noUpstreamReference(t *testing.T) { testutil.AddKptfileToWorkspace(t, w, kf) // Update the local package - err := (&update.Command{ - Pkg: pkgtest.CreatePkgOrFail(t, w.FullPackagePath()), + err := (&update2.Command{ + Pkg: testutil.CreatePkgOrFail(t, w.FullPackagePath()), }).Run(fake.CtxWithDefaultPrinter()) assert.Contains(t, err.Error(), "must have an upstream reference") @@ -969,8 +968,8 @@ func TestCommand_Run_failInvalidPath(t *testing.T) { strategy := kptfilev1.UpdateStrategies[i] t.Run(string(strategy), func(t *testing.T) { path := filepath.Join("fake", "path") - err := (&update.Command{ - Pkg: pkgtest.CreatePkgOrFail(t, path), + err := (&update2.Command{ + Pkg: testutil.CreatePkgOrFail(t, path), Strategy: strategy, }).Run(fake.CtxWithDefaultPrinter()) if assert.Error(t, err) { @@ -1034,8 +1033,8 @@ func TestCommand_Run_badUpstreamLock(t *testing.T) { } // Update the local package. - err = (&update.Command{ - Pkg: pkgtest.CreatePkgOrFail(t, g.LocalWorkspace.FullPackagePath()), + err = (&update2.Command{ + Pkg: testutil.CreatePkgOrFail(t, g.LocalWorkspace.FullPackagePath()), }).Run(fake.CtxWithDefaultPrinter()) if assert.Error(t, err) { @@ -1069,8 +1068,8 @@ func TestCommand_Run_failInvalidRef(t *testing.T) { return } - err := (&update.Command{ - Pkg: pkgtest.CreatePkgOrFail(t, g.LocalWorkspace.FullPackagePath()), + err := (&update2.Command{ + Pkg: testutil.CreatePkgOrFail(t, g.LocalWorkspace.FullPackagePath()), Ref: "exp", Strategy: strategy, }).Run(fake.CtxWithDefaultPrinter()) @@ -1127,8 +1126,8 @@ func TestCommand_Run_manualChange(t *testing.T) { return } - err := (&update.Command{ - Pkg: pkgtest.CreatePkgOrFail(t, g.LocalWorkspace.FullPackagePath()), + err := (&update2.Command{ + Pkg: testutil.CreatePkgOrFail(t, g.LocalWorkspace.FullPackagePath()), }).Run(fake.CtxWithDefaultPrinter()) if !assert.NoError(t, err) { t.FailNow() @@ -1181,8 +1180,8 @@ func TestCommand_Run_symlinks(t *testing.T) { } upstreamRepo := g.Repos[testutil.Upstream] - err := (&update.Command{ - Pkg: pkgtest.CreatePkgOrFail(t, g.LocalWorkspace.FullPackagePath()), + err := (&update2.Command{ + Pkg: testutil.CreatePkgOrFail(t, g.LocalWorkspace.FullPackagePath()), }).Run(fake.CtxWithDefaultPrinter()) if !assert.NoError(t, err) { t.FailNow() @@ -1229,8 +1228,8 @@ func TestCommand_Run_badStrategy(t *testing.T) { } // Update the local package - err := (&update.Command{ - Pkg: pkgtest.CreatePkgOrFail(t, g.LocalWorkspace.FullPackagePath()), + err := (&update2.Command{ + Pkg: testutil.CreatePkgOrFail(t, g.LocalWorkspace.FullPackagePath()), Strategy: strategy, }).Run(fake.CtxWithDefaultPrinter()) if !assert.Error(t, err, strategy) { @@ -2008,8 +2007,8 @@ func TestCommand_Run_local_subpackages(t *testing.T) { return } - err := (&update.Command{ - Pkg: pkgtest.CreatePkgOrFail(t, g.LocalWorkspace.FullPackagePath()), + err := (&update2.Command{ + Pkg: testutil.CreatePkgOrFail(t, g.LocalWorkspace.FullPackagePath()), Strategy: strategy, }).Run(fake.CtxWithDefaultPrinter()) @@ -3544,8 +3543,8 @@ func TestRun_remote_subpackages(t *testing.T) { return } - err := (&update.Command{ - Pkg: pkgtest.CreatePkgOrFail(t, g.LocalWorkspace.FullPackagePath()), + err := (&update2.Command{ + Pkg: testutil.CreatePkgOrFail(t, g.LocalWorkspace.FullPackagePath()), }).Run(fake.CtxWithDefaultPrinter()) if tc.expectedErrMsg != "" { @@ -3689,8 +3688,8 @@ func TestRootPackageIsUnfetched(t *testing.T) { } testutil.AddKptfileToWorkspace(t, w, kf) - err := (&update.Command{ - Pkg: pkgtest.CreatePkgOrFail(t, w.FullPackagePath()), + err := (&update2.Command{ + Pkg: testutil.CreatePkgOrFail(t, w.FullPackagePath()), }).Run(fake.CtxWithDefaultPrinter()) if !assert.NoError(t, err) { t.FailNow() @@ -3760,8 +3759,8 @@ func TestMultiUpdateCache(t *testing.T) { UpdateStrategy: kptfilev1.ResourceMerge, } testutil.AddKptfileToWorkspace(t, w, kf) - cmd := update.Command{ - Pkg: pkgtest.CreatePkgOrFail(t, w.FullPackagePath()), + cmd := update2.Command{ + Pkg: testutil.CreatePkgOrFail(t, w.FullPackagePath()), } err := cmd.Run(fake.CtxWithDefaultPrinter()) if !assert.NoError(t, err) { @@ -3865,7 +3864,7 @@ func TestReplaceNonKRMFiles(t *testing.T) { // expectedLocal. err = os.WriteFile(filepath.Join(updated, "new.yaml"), []byte("a: b"), 0600) assert.NoError(t, err) - err = update.ReplaceNonKRMFiles(updated, original, local) + err = update2.ReplaceNonKRMFiles(updated, original, local) assert.NoError(t, err) tg := testutil.TestGitRepo{} tg.AssertEqual(t, local, expectedLocal, false) diff --git a/pkg/lib/util/addmergecomment/addmergecomment.go b/pkg/lib/util/addmergecomment/addmergecomment.go index 0ac5c9b2b2..92f7f5fd31 100644 --- a/pkg/lib/util/addmergecomment/addmergecomment.go +++ b/pkg/lib/util/addmergecomment/addmergecomment.go @@ -19,7 +19,6 @@ import ( "os" "strings" - "github.com/kptdev/kpt/internal/util/merge" "sigs.k8s.io/kustomize/kyaml/copyutil" "sigs.k8s.io/kustomize/kyaml/filesys" "sigs.k8s.io/kustomize/kyaml/kio" @@ -37,6 +36,8 @@ const ( upstreamIdentifier = "internal.kpt.dev/upstream-identifier" unknownNamespace = "~C" defaultNamespace = "default" + + MergeCommentPrefix = "kpt-merge:" ) // AddMergeComment adds merge comments with format "kpt-merge: namespace/name" @@ -73,8 +74,8 @@ func Process(paths ...string) error { func addUpstreamAnnotation(object *kyaml.RNode, mergeComment string) error { group, _ := resid.ParseGroupVersion(object.GetApiVersion()) var name, namespace string - if strings.Contains(mergeComment, merge.MergeCommentPrefix) { - nsAndName := merge.NsAndNameForMerge(mergeComment) + if strings.Contains(mergeComment, MergeCommentPrefix) { + nsAndName := NsAndNameForMerge(mergeComment) namespace = nsAndName[0] name = nsAndName[1] } else { @@ -93,6 +94,23 @@ func addUpstreamAnnotation(object *kyaml.RNode, mergeComment string) error { return object.PipeE(kyaml.SetAnnotation(upstreamIdentifier, upstreamIdentifierValue)) } +// NsAndNameForMerge returns the namespace and name for merge +// from the line comment on the metadata field +// e.g. metadata: # kpt-merge: default/foo returns [default, foo] +func NsAndNameForMerge(metadataComment string) []string { + comment := strings.TrimPrefix(metadataComment, "#") + comment = strings.TrimSpace(comment) + if !strings.HasPrefix(comment, MergeCommentPrefix) { + return nil + } + comment = strings.TrimPrefix(comment, MergeCommentPrefix) + nsAndName := strings.SplitN(strings.TrimSpace(comment), "/", 2) + if len(nsAndName) != 2 { + return nil + } + return nsAndName +} + // Filter implements kyaml.Filter // this filter adds merge comment with format "kpt-merge: namespace/name" to // the input resource, if the namespace field doesn't exist on the resource, @@ -123,8 +141,8 @@ func (amc *AddMergeComment) Filter(object *kyaml.RNode) (*kyaml.RNode, error) { } // Only add merge comment if merge comment does not present - if !strings.Contains(mf.Key.YNode().LineComment, merge.MergeCommentPrefix) { - mf.Key.YNode().LineComment = fmt.Sprintf("%s %s/%s", merge.MergeCommentPrefix, rm.Namespace, rm.Name) + if !strings.Contains(mf.Key.YNode().LineComment, MergeCommentPrefix) { + mf.Key.YNode().LineComment = fmt.Sprintf("%s %s/%s", MergeCommentPrefix, rm.Namespace, rm.Name) } // We will migrate kpt-merge comment to upstream-identifier annotation. As an intermediate stage, this filter // preserves the mergeComment behavior to guarantee the backward compatibility. diff --git a/internal/util/argutil/argutil.go b/pkg/lib/util/args/args.go similarity index 97% rename from internal/util/argutil/argutil.go rename to pkg/lib/util/args/args.go index dfcaa2a082..9401d21860 100644 --- a/internal/util/argutil/argutil.go +++ b/pkg/lib/util/args/args.go @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -// The argutil package contains libraries for parsing commandline args. -package argutil +// Package args contains libraries for parsing commandline args. +package args import ( "context" diff --git a/internal/util/argutil/argutil_test.go b/pkg/lib/util/args/args_test.go similarity index 83% rename from internal/util/argutil/argutil_test.go rename to pkg/lib/util/args/args_test.go index d8b9230c66..7295fae5ab 100644 --- a/internal/util/argutil/argutil_test.go +++ b/pkg/lib/util/args/args_test.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package argutil_test +package args_test import ( "os" @@ -20,7 +20,7 @@ import ( "testing" "github.com/kptdev/kpt/internal/testutil" - "github.com/kptdev/kpt/internal/util/argutil" + "github.com/kptdev/kpt/pkg/lib/util/args" "github.com/kptdev/kpt/pkg/printer/fake" "github.com/stretchr/testify/assert" ) @@ -54,7 +54,7 @@ func TestParseDirVersion(t *testing.T) { in: "/some@dir2@ver1", expDir: "", expVer: "", - expErr: argutil.ErrMultiVersion, + expErr: args.ErrMultiVersion, }, { // empty in: "", @@ -65,7 +65,7 @@ func TestParseDirVersion(t *testing.T) { } for _, test := range tests { - gotDir, gotVer, gotErr := argutil.ParseDirVersion(test.in) + gotDir, gotVer, gotErr := args.ParseDirVersion(test.in) assert.Equal(t, gotErr, test.expErr) assert.Equal(t, gotDir, test.expDir) @@ -102,7 +102,7 @@ func TestParseDirVersionWithDefaults(t *testing.T) { in: "/some@dir2@ver1", expDir: "", expVer: "", - expErr: argutil.ErrMultiVersion, + expErr: args.ErrMultiVersion, }, { // empty in: "", @@ -113,7 +113,7 @@ func TestParseDirVersionWithDefaults(t *testing.T) { } for _, test := range tests { - gotDir, gotVer, gotErr := argutil.ParseDirVersionWithDefaults(test.in) + gotDir, gotVer, gotErr := args.ParseDirVersionWithDefaults(test.in) assert.Equal(t, gotErr, test.expErr) assert.Equal(t, gotDir, test.expDir) @@ -131,19 +131,19 @@ func TestResolveSymlink(t *testing.T) { err = os.Symlink("foo-link", "link-to-foo-link") assert.NoError(t, err) - actual1, err := argutil.ResolveSymlink(fake.CtxWithDefaultPrinter(), "foo-link") + actual1, err := args.ResolveSymlink(fake.CtxWithDefaultPrinter(), "foo-link") assert.NoError(t, err) assert.Equal(t, "foo", actual1) - actual2, err := argutil.ResolveSymlink(fake.CtxWithDefaultPrinter(), "link-to-foo-link") + actual2, err := args.ResolveSymlink(fake.CtxWithDefaultPrinter(), "link-to-foo-link") assert.NoError(t, err) assert.Equal(t, "foo", actual2) - actual3, err := argutil.ResolveSymlink(fake.CtxWithDefaultPrinter(), ".") + actual3, err := args.ResolveSymlink(fake.CtxWithDefaultPrinter(), ".") assert.NoError(t, err) assert.Equal(t, ".", actual3) - _, err = argutil.ResolveSymlink(fake.CtxWithDefaultPrinter(), "baz") + _, err = args.ResolveSymlink(fake.CtxWithDefaultPrinter(), "baz") assert.Error(t, err) assert.Equal(t, "lstat baz: no such file or directory", err.Error()) } diff --git a/internal/util/attribution/attribution.go b/pkg/lib/util/attribution/attribution.go similarity index 100% rename from internal/util/attribution/attribution.go rename to pkg/lib/util/attribution/attribution.go diff --git a/internal/util/attribution/attribution_test.go b/pkg/lib/util/attribution/attribution_test.go similarity index 100% rename from internal/util/attribution/attribution_test.go rename to pkg/lib/util/attribution/attribution_test.go diff --git a/internal/util/fetch/fetch.go b/pkg/lib/util/fetch/fetch.go similarity index 97% rename from internal/util/fetch/fetch.go rename to pkg/lib/util/fetch/fetch.go index 8a0636203e..5aabd0064c 100644 --- a/internal/util/fetch/fetch.go +++ b/pkg/lib/util/fetch/fetch.go @@ -22,17 +22,16 @@ import ( "path/filepath" "strings" - "github.com/kptdev/kpt/internal/types" + "github.com/kptdev/kpt/internal/gitutil" "github.com/kptdev/kpt/pkg/lib/errors" + "github.com/kptdev/kpt/pkg/lib/types" "github.com/otiai10/copy" "sigs.k8s.io/kustomize/kyaml/filesys" - "github.com/kptdev/kpt/internal/gitutil" - "github.com/kptdev/kpt/internal/pkg" - "github.com/kptdev/kpt/internal/util/git" - "github.com/kptdev/kpt/internal/util/pkgutil" kptfilev1 "github.com/kptdev/kpt/pkg/api/kptfile/v1" "github.com/kptdev/kpt/pkg/kptfile/kptfileutil" + "github.com/kptdev/kpt/pkg/lib/pkg" + "github.com/kptdev/kpt/pkg/lib/util/git" "github.com/kptdev/kpt/pkg/printer" ) @@ -142,7 +141,7 @@ func (c *Cloner) cloneAndCopy(ctx context.Context, dest string) error { sourcePath := filepath.Join(c.repoSpec.Dir, c.repoSpec.Path) pr.Printf("Adding package %q.\n", strings.TrimPrefix(c.repoSpec.Path, "/")) - if err := pkgutil.CopyPackage(sourcePath, dest, true, pkg.All); err != nil { + if err := pkg.CopyPackage(sourcePath, dest, true, pkg.All); err != nil { return errors.E(op, types.UniquePath(dest), err) } diff --git a/internal/util/fetch/fetch_test.go b/pkg/lib/util/fetch/fetch_test.go similarity index 95% rename from internal/util/fetch/fetch_test.go rename to pkg/lib/util/fetch/fetch_test.go index 44458d903c..cd1537c638 100644 --- a/internal/util/fetch/fetch_test.go +++ b/pkg/lib/util/fetch/fetch_test.go @@ -19,12 +19,11 @@ import ( "path/filepath" "testing" - pkgtesting "github.com/kptdev/kpt/internal/pkg/testing" "github.com/kptdev/kpt/internal/testutil" "github.com/kptdev/kpt/internal/testutil/pkgbuilder" - "github.com/kptdev/kpt/internal/util/fetch" kptfilev1 "github.com/kptdev/kpt/pkg/api/kptfile/v1" "github.com/kptdev/kpt/pkg/kptfile/kptfileutil" + "github.com/kptdev/kpt/pkg/lib/util/fetch" "github.com/kptdev/kpt/pkg/printer/fake" "github.com/stretchr/testify/assert" "sigs.k8s.io/kustomize/kyaml/filesys" @@ -85,7 +84,7 @@ func TestCommand_Run_failNoKptfile(t *testing.T) { } err = fetch.Command{ - Pkg: pkgtesting.CreatePkgOrFail(t, pkgPath), + Pkg: testutil.CreatePkgOrFail(t, pkgPath), }.Run(fake.CtxWithDefaultPrinter()) if !assert.Error(t, err) { t.FailNow() @@ -104,7 +103,7 @@ func TestCommand_Run_failNoGit(t *testing.T) { } err = fetch.Command{ - Pkg: pkgtesting.CreatePkgOrFail(t, w.FullPackagePath()), + Pkg: testutil.CreatePkgOrFail(t, w.FullPackagePath()), }.Run(fake.CtxWithDefaultPrinter()) if !assert.Error(t, err) { t.FailNow() @@ -127,7 +126,7 @@ func TestCommand_Run_failEmptyRepo(t *testing.T) { } err = fetch.Command{ - Pkg: pkgtesting.CreatePkgOrFail(t, w.FullPackagePath()), + Pkg: testutil.CreatePkgOrFail(t, w.FullPackagePath()), }.Run(fake.CtxWithDefaultPrinter()) if !assert.Error(t, err) { t.FailNow() @@ -150,7 +149,7 @@ func TestCommand_Run_failNoRevision(t *testing.T) { } err = fetch.Command{ - Pkg: pkgtesting.CreatePkgOrFail(t, w.FullPackagePath()), + Pkg: testutil.CreatePkgOrFail(t, w.FullPackagePath()), }.Run(fake.CtxWithDefaultPrinter()) if !assert.Error(t, err) { t.FailNow() @@ -177,7 +176,7 @@ func TestCommand_Run(t *testing.T) { absPath := filepath.Join(w.WorkspaceDirectory, g.RepoName) err = fetch.Command{ - Pkg: pkgtesting.CreatePkgOrFail(t, w.FullPackagePath()), + Pkg: testutil.CreatePkgOrFail(t, w.FullPackagePath()), }.Run(fake.CtxWithDefaultPrinter()) assert.NoError(t, err) @@ -240,7 +239,7 @@ func TestCommand_Run_subdir(t *testing.T) { absPath := filepath.Join(w.WorkspaceDirectory, g.RepoName) err = fetch.Command{ - Pkg: pkgtesting.CreatePkgOrFail(t, w.FullPackagePath()), + Pkg: testutil.CreatePkgOrFail(t, w.FullPackagePath()), }.Run(fake.CtxWithDefaultPrinter()) assert.NoError(t, err) @@ -318,7 +317,7 @@ func TestCommand_Run_branch(t *testing.T) { } err = fetch.Command{ - Pkg: pkgtesting.CreatePkgOrFail(t, w.FullPackagePath()), + Pkg: testutil.CreatePkgOrFail(t, w.FullPackagePath()), }.Run(fake.CtxWithDefaultPrinter()) assert.NoError(t, err) @@ -400,7 +399,7 @@ func TestCommand_Run_tag(t *testing.T) { } err = fetch.Command{ - Pkg: pkgtesting.CreatePkgOrFail(t, w.FullPackagePath()), + Pkg: testutil.CreatePkgOrFail(t, w.FullPackagePath()), }.Run(fake.CtxWithDefaultPrinter()) assert.NoError(t, err) @@ -508,7 +507,7 @@ func TestCommand_Run_subdir_at_tag(t *testing.T) { t.FailNow() } - actualPkg := pkgtesting.CreatePkgOrFail(t, rw.FullPackagePath()) + actualPkg := testutil.CreatePkgOrFail(t, rw.FullPackagePath()) err = fetch.Command{ Pkg: actualPkg, }.Run(fake.CtxWithDefaultPrinter()) @@ -566,7 +565,7 @@ func TestCommand_Run_no_subdir_at_valid_tag(t *testing.T) { t.FailNow() } - actualPkg := pkgtesting.CreatePkgOrFail(t, rw.FullPackagePath()) + actualPkg := testutil.CreatePkgOrFail(t, rw.FullPackagePath()) err = fetch.Command{ Pkg: actualPkg, }.Run(fake.CtxWithDefaultPrinter()) @@ -613,7 +612,7 @@ func TestCommand_Run_no_subdir_at_invalid_tag(t *testing.T) { t.FailNow() } - actualPkg := pkgtesting.CreatePkgOrFail(t, rw.FullPackagePath()) + actualPkg := testutil.CreatePkgOrFail(t, rw.FullPackagePath()) err = fetch.Command{ Pkg: actualPkg, }.Run(fake.CtxWithDefaultPrinter()) @@ -637,7 +636,7 @@ func TestCommand_Run_failInvalidRepo(t *testing.T) { } err = fetch.Command{ - Pkg: pkgtesting.CreatePkgOrFail(t, w.FullPackagePath()), + Pkg: testutil.CreatePkgOrFail(t, w.FullPackagePath()), }.Run(fake.CtxWithDefaultPrinter()) if !assert.Error(t, err) { t.FailNow() @@ -661,7 +660,7 @@ func TestCommand_Run_failInvalidBranch(t *testing.T) { } err = fetch.Command{ - Pkg: pkgtesting.CreatePkgOrFail(t, w.FullPackagePath()), + Pkg: testutil.CreatePkgOrFail(t, w.FullPackagePath()), }.Run(fake.CtxWithDefaultPrinter()) if !assert.Error(t, err) { t.FailNow() @@ -688,7 +687,7 @@ func TestCommand_Run_failInvalidTag(t *testing.T) { } err = fetch.Command{ - Pkg: pkgtesting.CreatePkgOrFail(t, w.FullPackagePath()), + Pkg: testutil.CreatePkgOrFail(t, w.FullPackagePath()), }.Run(fake.CtxWithDefaultPrinter()) if !assert.Error(t, err) { t.FailNow() diff --git a/internal/util/get/example_test.go b/pkg/lib/util/get/example_test.go similarity index 98% rename from internal/util/get/example_test.go rename to pkg/lib/util/get/example_test.go index ed5f11268a..52ee77fe2c 100644 --- a/internal/util/get/example_test.go +++ b/pkg/lib/util/get/example_test.go @@ -18,8 +18,8 @@ import ( "fmt" "path/filepath" - "github.com/kptdev/kpt/internal/util/get" kptfilev1 "github.com/kptdev/kpt/pkg/api/kptfile/v1" + "github.com/kptdev/kpt/pkg/lib/util/get" "github.com/kptdev/kpt/pkg/printer/fake" ) diff --git a/internal/util/get/get.go b/pkg/lib/util/get/get.go similarity index 95% rename from internal/util/get/get.go rename to pkg/lib/util/get/get.go index 1d74f85c40..fd20085c70 100644 --- a/internal/util/get/get.go +++ b/pkg/lib/util/get/get.go @@ -23,18 +23,18 @@ import ( "path/filepath" "strings" - "github.com/kptdev/kpt/internal/hook" - "github.com/kptdev/kpt/internal/pkg" - "github.com/kptdev/kpt/internal/types" - "github.com/kptdev/kpt/internal/util/attribution" - "github.com/kptdev/kpt/internal/util/fetch" - "github.com/kptdev/kpt/internal/util/pathutil" - "github.com/kptdev/kpt/internal/util/stack" kptfilev1 "github.com/kptdev/kpt/pkg/api/kptfile/v1" "github.com/kptdev/kpt/pkg/kptfile/kptfileutil" "github.com/kptdev/kpt/pkg/lib/errors" + "github.com/kptdev/kpt/pkg/lib/kptops" + "github.com/kptdev/kpt/pkg/lib/pkg" "github.com/kptdev/kpt/pkg/lib/runneroptions" + "github.com/kptdev/kpt/pkg/lib/types" "github.com/kptdev/kpt/pkg/lib/util/addmergecomment" + "github.com/kptdev/kpt/pkg/lib/util/attribution" + "github.com/kptdev/kpt/pkg/lib/util/fetch" + "github.com/kptdev/kpt/pkg/lib/util/path" + "github.com/kptdev/kpt/pkg/lib/util/stack" "github.com/kptdev/kpt/pkg/printer" "sigs.k8s.io/kustomize/kyaml/filesys" "sigs.k8s.io/kustomize/kyaml/kio" @@ -122,7 +122,7 @@ func (c Command) Run(ctx context.Context) error { return cleanUpDirAndError(c.Destination, err) } - absDestPath, _, err := pathutil.ResolveAbsAndRelPaths(c.Destination) + absDestPath, _, err := path.ResolveAbsAndRelPaths(c.Destination) if err != nil { return err } @@ -148,7 +148,7 @@ func (c Command) Run(ctx context.Context) error { if c.IsDeploymentInstance { pr := printer.FromContextOrDie(ctx) pr.Printf("\nCustomizing package for deployment.\n") - hookCmd := hook.Executor{} + hookCmd := kptops.Executor{} hookCmd.RunnerOptions.InitDefaults(c.DefaultKrmFunctionImagePrefix) hookCmd.PkgPath = c.Destination diff --git a/internal/util/get/get_test.go b/pkg/lib/util/get/get_test.go similarity index 99% rename from internal/util/get/get_test.go rename to pkg/lib/util/get/get_test.go index ab965599b1..fe8ce0815a 100644 --- a/internal/util/get/get_test.go +++ b/pkg/lib/util/get/get_test.go @@ -22,8 +22,8 @@ import ( "github.com/kptdev/kpt/internal/testutil" "github.com/kptdev/kpt/internal/testutil/pkgbuilder" - "github.com/kptdev/kpt/internal/util/get" kptfilev1 "github.com/kptdev/kpt/pkg/api/kptfile/v1" + "github.com/kptdev/kpt/pkg/lib/util/get" "github.com/kptdev/kpt/pkg/printer/fake" "github.com/stretchr/testify/assert" "sigs.k8s.io/kustomize/kyaml/kio" diff --git a/internal/util/git/git.go b/pkg/lib/util/git/git.go similarity index 96% rename from internal/util/git/git.go rename to pkg/lib/util/git/git.go index e8c7b1741c..c484f37b57 100644 --- a/internal/util/git/git.go +++ b/pkg/lib/util/git/git.go @@ -53,7 +53,7 @@ type RepoSpec struct { } // AbsPath is the absolute path to the subdirectory -func (rs RepoSpec) AbsPath() string { +func (rs *RepoSpec) AbsPath() string { return filepath.Join(rs.Dir, rs.Path) } @@ -80,7 +80,7 @@ func isAWSHost(host string) bool { return strings.Contains(host, "amazonaws.com") } -// lookupCommit looks up the sha of the current commit on the repo at the +// LookupCommit looks up the sha of the current commit on the repo at the // provided path. func LookupCommit(repoPath string) (string, error) { const op errors.Op = "git.LookupCommit" diff --git a/internal/util/man/man.go b/pkg/lib/util/man/man.go similarity index 100% rename from internal/util/man/man.go rename to pkg/lib/util/man/man.go diff --git a/internal/util/man/man_test.go b/pkg/lib/util/man/man_test.go similarity index 99% rename from internal/util/man/man_test.go rename to pkg/lib/util/man/man_test.go index e6d5c3cafe..2b2b0ada2c 100644 --- a/internal/util/man/man_test.go +++ b/pkg/lib/util/man/man_test.go @@ -21,8 +21,8 @@ import ( "path/filepath" "testing" - man "github.com/kptdev/kpt/internal/util/man" kptfilev1 "github.com/kptdev/kpt/pkg/api/kptfile/v1" + "github.com/kptdev/kpt/pkg/lib/util/man" "github.com/stretchr/testify/assert" ) diff --git a/internal/util/pathutil/pathutil.go b/pkg/lib/util/path/path.go similarity index 98% rename from internal/util/pathutil/pathutil.go rename to pkg/lib/util/path/path.go index 5270ace41e..42a837f3fc 100644 --- a/internal/util/pathutil/pathutil.go +++ b/pkg/lib/util/path/path.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package pathutil +package path import ( "os" diff --git a/internal/util/stack/stack.go b/pkg/lib/util/stack/stack.go similarity index 97% rename from internal/util/stack/stack.go rename to pkg/lib/util/stack/stack.go index 7d3ec8ef93..9b08f494ba 100644 --- a/internal/util/stack/stack.go +++ b/pkg/lib/util/stack/stack.go @@ -17,7 +17,7 @@ package stack import ( "fmt" - "github.com/kptdev/kpt/internal/pkg" + "github.com/kptdev/kpt/pkg/lib/pkg" ) // New returns a new stack for elements of string type. diff --git a/internal/util/strings/strings.go b/pkg/lib/util/strings/strings.go similarity index 100% rename from internal/util/strings/strings.go rename to pkg/lib/util/strings/strings.go diff --git a/internal/util/strings/strings_test.go b/pkg/lib/util/strings/strings_test.go similarity index 100% rename from internal/util/strings/strings_test.go rename to pkg/lib/util/strings/strings_test.go diff --git a/pkg/live/load.go b/pkg/live/load.go index c08ff48e48..18282a3637 100644 --- a/pkg/live/load.go +++ b/pkg/live/load.go @@ -19,13 +19,13 @@ import ( "fmt" "io" - "github.com/kptdev/kpt/internal/pkg" - "github.com/kptdev/kpt/internal/util/pathutil" - "github.com/kptdev/kpt/internal/util/strings" kptfilev1 "github.com/kptdev/kpt/pkg/api/kptfile/v1" rgfilev1alpha1 "github.com/kptdev/kpt/pkg/api/resourcegroup/v1alpha1" "github.com/kptdev/kpt/pkg/kptfile/kptfileutil" "github.com/kptdev/kpt/pkg/lib/errors" + "github.com/kptdev/kpt/pkg/lib/pkg" + pathutil "github.com/kptdev/kpt/pkg/lib/util/path" + "github.com/kptdev/kpt/pkg/lib/util/strings" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/klog/v2" diff --git a/pkg/live/rgpath.go b/pkg/live/rgpath.go index 1093528f5a..56b98e0205 100644 --- a/pkg/live/rgpath.go +++ b/pkg/live/rgpath.go @@ -18,8 +18,8 @@ import ( "encoding/json" "fmt" - "github.com/kptdev/kpt/internal/util/pathutil" rgfilev1alpha1 "github.com/kptdev/kpt/pkg/api/resourcegroup/v1alpha1" + "github.com/kptdev/kpt/pkg/lib/util/path" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "sigs.k8s.io/cli-utils/pkg/manifestreader" "sigs.k8s.io/kustomize/kyaml/kio" @@ -41,7 +41,7 @@ type ResourceGroupPathManifestReader struct { // Kptfile data. If unable to generate the ResourceGroup inventory // object from the Kptfile, it is NOT an error. func (r *ResourceGroupPathManifestReader) Read() ([]*unstructured.Unstructured, error) { - absPkgPath, _, err := pathutil.ResolveAbsAndRelPaths(r.PkgPath) + absPkgPath, _, err := path.ResolveAbsAndRelPaths(r.PkgPath) if err != nil { return nil, err } diff --git a/pkg/printer/fake/fake.go b/pkg/printer/fake/fake.go index dcbde829d8..0821398061 100644 --- a/pkg/printer/fake/fake.go +++ b/pkg/printer/fake/fake.go @@ -18,7 +18,7 @@ import ( "context" "io" - "github.com/kptdev/kpt/internal/pkg" + "github.com/kptdev/kpt/pkg/lib/pkg" "github.com/kptdev/kpt/pkg/printer" ) diff --git a/pkg/printer/printer.go b/pkg/printer/printer.go index 9d7475ca96..08f75cb26e 100644 --- a/pkg/printer/printer.go +++ b/pkg/printer/printer.go @@ -21,8 +21,8 @@ import ( "io" "os" - "github.com/kptdev/kpt/internal/pkg" - "github.com/kptdev/kpt/internal/types" + "github.com/kptdev/kpt/pkg/lib/pkg" + "github.com/kptdev/kpt/pkg/lib/types" ) // TruncateOutput defines should output be truncated diff --git a/pkg/printer/printer_test.go b/pkg/printer/printer_test.go index 165f705b37..fe685823b3 100644 --- a/pkg/printer/printer_test.go +++ b/pkg/printer/printer_test.go @@ -18,7 +18,7 @@ import ( "bytes" "testing" - "github.com/kptdev/kpt/internal/pkg" + "github.com/kptdev/kpt/pkg/lib/pkg" ) func TestOptPrintf_WithDisplayPath(t *testing.T) { diff --git a/internal/alpha/printers/table/collector.go b/pkg/printer/table/collector.go similarity index 100% rename from internal/alpha/printers/table/collector.go rename to pkg/printer/table/collector.go diff --git a/internal/alpha/printers/table/printer.go b/pkg/printer/table/printer.go similarity index 98% rename from internal/alpha/printers/table/printer.go rename to pkg/printer/table/printer.go index 39eda062a7..e295458798 100644 --- a/internal/alpha/printers/table/printer.go +++ b/pkg/printer/table/printer.go @@ -10,7 +10,7 @@ import ( "time" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/cli-runtime/pkg/genericclioptions" + "k8s.io/cli-runtime/pkg/genericiooptions" "k8s.io/klog/v2" "sigs.k8s.io/cli-utils/pkg/apply/event" "sigs.k8s.io/cli-utils/pkg/common" @@ -21,7 +21,7 @@ import ( ) type Printer struct { - IOStreams genericclioptions.IOStreams + IOStreams genericiooptions.IOStreams } func (t *Printer) Print(ch <-chan event.Event, _ common.DryRunStrategy, _ bool) error { diff --git a/internal/util/printerutil/printerutil.go b/pkg/printer/util.go similarity index 90% rename from internal/util/printerutil/printerutil.go rename to pkg/printer/util.go index 6e1fac468f..044b4e335f 100644 --- a/internal/util/printerutil/printerutil.go +++ b/pkg/printer/util.go @@ -12,17 +12,15 @@ // See the License for the specific language governing permissions and // limitations under the License. -package printerutil +package printer import ( "context" - - "github.com/kptdev/kpt/pkg/printer" ) // PrintFnResultInfo displays information about the function results file. func PrintFnResultInfo(ctx context.Context, resultsFile string, withNewLine bool) { - pr := printer.FromContextOrDie(ctx) + pr := FromContextOrDie(ctx) if resultsFile != "" { if withNewLine { pr.Printf("\n") diff --git a/pkg/test/runner/config.go b/pkg/test/runner/config.go index 7a4c9b57ca..0809e5c6c7 100644 --- a/pkg/test/runner/config.go +++ b/pkg/test/runner/config.go @@ -19,7 +19,7 @@ import ( "os" "path/filepath" - "github.com/kptdev/kpt/internal/types" + "github.com/kptdev/kpt/pkg/lib/types" "sigs.k8s.io/kustomize/kyaml/yaml" ) diff --git a/thirdparty/cmdconfig/commands/cmdeval/cmdeval.go b/thirdparty/cmdconfig/commands/cmdeval/cmdeval.go index f4ba0fbe46..4958914873 100644 --- a/thirdparty/cmdconfig/commands/cmdeval/cmdeval.go +++ b/thirdparty/cmdconfig/commands/cmdeval/cmdeval.go @@ -14,12 +14,13 @@ import ( "github.com/google/shlex" docs "github.com/kptdev/kpt/internal/docs/generated/fndocs" - "github.com/kptdev/kpt/internal/util/argutil" - "github.com/kptdev/kpt/internal/util/pathutil" kptfile "github.com/kptdev/kpt/pkg/api/kptfile/v1" "github.com/kptdev/kpt/pkg/kptfile/kptfileutil" "github.com/kptdev/kpt/pkg/lib/runneroptions" + argsutil "github.com/kptdev/kpt/pkg/lib/util/args" "github.com/kptdev/kpt/pkg/lib/util/cmdutil" + "github.com/kptdev/kpt/pkg/lib/util/path" + pathutil "github.com/kptdev/kpt/pkg/lib/util/path" "github.com/kptdev/kpt/pkg/printer" "github.com/kptdev/kpt/thirdparty/cmdconfig/commands/runner" "github.com/kptdev/kpt/thirdparty/kyaml/runfn" @@ -200,8 +201,8 @@ func (r *EvalFnRunner) NewFunction() *kptfile.Function { newFn.Exclusions = []kptfile.Selector{r.Exclusion} } if r.FnConfigPath != "" { - fnConfigAbsPath, _, _ := pathutil.ResolveAbsAndRelPaths(r.FnConfigPath) - pkgAbsPath, _, _ := pathutil.ResolveAbsAndRelPaths(r.runFns.Path) + fnConfigAbsPath, _, _ := path.ResolveAbsAndRelPaths(r.FnConfigPath) + pkgAbsPath, _, _ := path.ResolveAbsAndRelPaths(r.runFns.Path) newFn.ConfigPath, _ = filepath.Rel(pkgAbsPath, fnConfigAbsPath) } else { data := map[string]string{} @@ -519,7 +520,7 @@ func (r *EvalFnRunner) preRunE(c *cobra.Command, args []string) error { } if path != "" { - path, err = argutil.ResolveSymlink(r.Ctx, path) + path, err = argsutil.ResolveSymlink(r.Ctx, path) if err != nil { return err } diff --git a/thirdparty/cmdconfig/commands/cmdsource/cmdsource.go b/thirdparty/cmdconfig/commands/cmdsource/cmdsource.go index 5cffb1a670..7fba739a4a 100644 --- a/thirdparty/cmdconfig/commands/cmdsource/cmdsource.go +++ b/thirdparty/cmdconfig/commands/cmdsource/cmdsource.go @@ -9,9 +9,9 @@ import ( "path/filepath" "github.com/kptdev/kpt/internal/docs/generated/fndocs" - "github.com/kptdev/kpt/internal/pkg" - "github.com/kptdev/kpt/internal/util/argutil" kptfile "github.com/kptdev/kpt/pkg/api/kptfile/v1" + "github.com/kptdev/kpt/pkg/lib/pkg" + argsutil "github.com/kptdev/kpt/pkg/lib/util/args" "github.com/kptdev/kpt/pkg/lib/util/cmdutil" "github.com/kptdev/kpt/pkg/printer" "github.com/kptdev/kpt/thirdparty/cmdconfig/commands/runner" @@ -102,7 +102,7 @@ func (r *SourceRunner) runE(c *cobra.Command, args []string) error { if err != nil { return fmt.Errorf("cannot convert input path %q to absolute path: %w", a, err) } - resolvedPath, err := argutil.ResolveSymlink(r.Ctx, pkgPath) + resolvedPath, err := argsutil.ResolveSymlink(r.Ctx, pkgPath) if err != nil { return err } diff --git a/thirdparty/cmdconfig/commands/cmdtree/cmdtree.go b/thirdparty/cmdconfig/commands/cmdtree/cmdtree.go index d81d910258..dbec01da9b 100644 --- a/thirdparty/cmdconfig/commands/cmdtree/cmdtree.go +++ b/thirdparty/cmdconfig/commands/cmdtree/cmdtree.go @@ -8,8 +8,8 @@ import ( "path/filepath" "github.com/kptdev/kpt/internal/docs/generated/pkgdocs" - "github.com/kptdev/kpt/internal/util/argutil" kptfilev1 "github.com/kptdev/kpt/pkg/api/kptfile/v1" + argsutil "github.com/kptdev/kpt/pkg/lib/util/args" "github.com/kptdev/kpt/pkg/printer" "github.com/kptdev/kpt/thirdparty/cmdconfig/commands/runner" "github.com/spf13/cobra" @@ -51,7 +51,7 @@ func (r *TreeRunner) runE(c *cobra.Command, args []string) error { args = append(args, root) } root = filepath.Clean(args[0]) - resolvedPath, err := argutil.ResolveSymlink(r.Ctx, args[0]) + resolvedPath, err := argsutil.ResolveSymlink(r.Ctx, args[0]) if err != nil { return err } diff --git a/thirdparty/kyaml/runfn/runfn.go b/thirdparty/kyaml/runfn/runfn.go index a1264791ef..5306156b36 100644 --- a/thirdparty/kyaml/runfn/runfn.go +++ b/thirdparty/kyaml/runfn/runfn.go @@ -12,9 +12,9 @@ import ( "path/filepath" "strings" - "github.com/kptdev/kpt/internal/types" fnruntime "github.com/kptdev/kpt/pkg/fn/runtime" "github.com/kptdev/kpt/pkg/lib/runneroptions" + "github.com/kptdev/kpt/pkg/lib/types" "github.com/kptdev/kpt/pkg/printer" "sigs.k8s.io/kustomize/kyaml/errors" "sigs.k8s.io/kustomize/kyaml/filesys" @@ -22,10 +22,9 @@ import ( "sigs.k8s.io/kustomize/kyaml/kio" "sigs.k8s.io/kustomize/kyaml/yaml" - "github.com/kptdev/kpt/internal/pkg" - "github.com/kptdev/kpt/internal/util/printerutil" fnresult "github.com/kptdev/kpt/pkg/api/fnresult/v1" kptfile "github.com/kptdev/kpt/pkg/api/kptfile/v1" + "github.com/kptdev/kpt/pkg/lib/pkg" ) // RunFns runs the set of configuration functions in a local directory against @@ -249,7 +248,7 @@ func (r RunFns) runFunctions(input kio.Reader, output kio.Writer, fltrs []kio.Fi } func (r RunFns) printFnResultsStatus(resultsFile string) { - printerutil.PrintFnResultInfo(r.Ctx, resultsFile, true) + printer.PrintFnResultInfo(r.Ctx, resultsFile, true) } // mergeContainerEnv will merge the envs specified by command line (imperative) and config