diff --git a/pkg/client/client.go b/pkg/client/client.go index ea3bd0fd..d980aac3 100644 --- a/pkg/client/client.go +++ b/pkg/client/client.go @@ -52,6 +52,8 @@ type KpmClient struct { settings settings.Settings // The flag of whether to check the checksum of the package and update kcl.mod.lock. noSumCheck bool + // The subpackage within a directory + subPackage string } // NewKpmClient will create a new kpm client with default settings. @@ -500,6 +502,9 @@ func (c *KpmClient) Compile(kclPkg *pkg.KclPkg, kclvmCompiler *runner.Compiler) if !filepath.IsAbs(dPath) { dPath = filepath.Join(c.homePath, dPath) } + if c.subPackage != "" { + dPath, _ = utils.FindPackage(dPath, c.subPackage) + } kclvmCompiler.AddDepPath(dName, dPath) } @@ -1877,6 +1882,14 @@ func (c *KpmClient) DownloadDeps(deps *pkg.Dependencies, lockDeps *pkg.Dependenc return &newDeps, nil } +func (c *KpmClient) SetSubPackage(pkgName string) { + c.subPackage = pkgName +} + +func (c *KpmClient) GetSubPackage() string { + return c.subPackage +} + // pullTarFromOci will pull a kcl package tar file from oci registry. func (c *KpmClient) pullTarFromOci(localPath string, ociOpts *opt.OciOptions) error { absPullPath, err := filepath.Abs(localPath) diff --git a/pkg/cmd/cmd_flags.go b/pkg/cmd/cmd_flags.go index 47ed65cb..45eef40e 100644 --- a/pkg/cmd/cmd_flags.go +++ b/pkg/cmd/cmd_flags.go @@ -17,6 +17,7 @@ const FLAG_DISABLE_NONE = "disable_none" const FLAG_ARGUMENT = "argument" const FLAG_OVERRIDES = "overrides" const FLAG_SORT_KEYS = "sort_keys" +const FLAG_PACKAGE = "package" const FLAG_QUIET = "quiet" const FLAG_NO_SUM_CHECK = "no_sum_check" diff --git a/pkg/cmd/cmd_run.go b/pkg/cmd/cmd_run.go index 4564e5d5..61cdee7e 100644 --- a/pkg/cmd/cmd_run.go +++ b/pkg/cmd/cmd_run.go @@ -81,6 +81,12 @@ func NewRunCmd(kpmcli *client.KpmClient) *cli.Command { Aliases: []string{"k"}, Usage: "sort result keys", }, + + // KCL arg: --package + &cli.StringFlag{ + Name: FLAG_PACKAGE, + Usage: "specify the package name", + }, }, Action: func(c *cli.Context) error { return KpmRun(c, kpmcli) @@ -103,6 +109,8 @@ func KpmRun(c *cli.Context, kpmcli *client.KpmClient) error { } }() + kpmcli.SetSubPackage(c.String(FLAG_PACKAGE)) + kclOpts := CompileOptionFromCli(c) kclOpts.SetNoSumCheck(c.Bool(FLAG_NO_SUM_CHECK)) runEntry, errEvent := runner.FindRunEntryFrom(c.Args().Slice()) diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go index 14bc9b06..6c7cdff2 100644 --- a/pkg/utils/utils.go +++ b/pkg/utils/utils.go @@ -17,6 +17,7 @@ import ( "runtime" "strings" + "github.com/BurntSushi/toml" "github.com/distribution/reference" "github.com/moby/term" "github.com/otiai10/copy" @@ -599,3 +600,50 @@ func AbsTarPath(tarPath string) (string, error) { return absTarPath, nil } + +// FindPackage finds the package with the package name 'targetPackage' under the 'root' directory kcl.mod file. +func FindPackage(root, targetPackage string) (string, error) { + var result string + err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + if info.IsDir() { + kclModPath := filepath.Join(path, constants.KCL_MOD) + if _, err := os.Stat(kclModPath); err == nil { + if matchesPackageName(kclModPath, targetPackage) { + result = path + return filepath.SkipAll + } + } + } + return nil + }) + + if err != nil { + return "", err + } + if result == "" { + return "", fmt.Errorf("kcl.mod with package '%s' not found", targetPackage) + } + return result, nil +} + +// MatchesPackageName checks whether the package name in the kcl.mod file under 'kclModPath' is equal to 'targetPackage'. +func matchesPackageName(kclModPath, targetPackage string) bool { + type Package struct { + Name string `toml:"name"` + } + type ModFile struct { + Package Package `toml:"package"` + } + + var modFile ModFile + _, err := toml.DecodeFile(kclModPath, &modFile) + if err != nil { + fmt.Printf("Error parsing kcl.mod file: %v\n", err) + return false + } + + return modFile.Package.Name == targetPackage +}