kcl-lang.io/kpm@v0.8.7-0.20240520061008-9fc4c5efc8c7/pkg/cmd/cmd_run.go (about)

     1  // Copyright 2023 The KCL Authors. All rights reserved.
     2  // Deprecated: The entire contents of this file will be deprecated.
     3  // Please use the kcl cli - https://github.com/kcl-lang/cli.
     4  
     5  package cmd
     6  
     7  import (
     8  	"fmt"
     9  	"os"
    10  
    11  	"github.com/urfave/cli/v2"
    12  	"kcl-lang.io/kcl-go/pkg/kcl"
    13  	"kcl-lang.io/kpm/pkg/api"
    14  	"kcl-lang.io/kpm/pkg/client"
    15  	"kcl-lang.io/kpm/pkg/git"
    16  	"kcl-lang.io/kpm/pkg/opt"
    17  	"kcl-lang.io/kpm/pkg/reporter"
    18  	"kcl-lang.io/kpm/pkg/runner"
    19  )
    20  
    21  // NewRunCmd new a Command for `kpm run`.
    22  func NewRunCmd(kpmcli *client.KpmClient) *cli.Command {
    23  	return &cli.Command{
    24  		Hidden: false,
    25  		Name:   "run",
    26  		Usage:  "compile kcl package.",
    27  		Flags: []cli.Flag{
    28  			// The entry kcl file.
    29  			&cli.StringSliceFlag{
    30  				Name:  FLAG_INPUT,
    31  				Usage: "a kcl file as the compile entry file",
    32  			},
    33  			&cli.StringFlag{
    34  				Name:  FLAG_TAG,
    35  				Usage: "the tag for oci artifact",
    36  			},
    37  			// '--vendor' will trigger the vendor mode
    38  			// In the vendor mode, the package search path is the subdirectory 'vendor' in current package.
    39  			// In the non-vendor mode, the package search path is the $KCL_PKG_PATH.
    40  			&cli.BoolFlag{
    41  				Name:  FLAG_VENDOR,
    42  				Usage: "run in vendor mode",
    43  			},
    44  			// --no_sum_check
    45  			&cli.BoolFlag{
    46  				Name:  FLAG_NO_SUM_CHECK,
    47  				Usage: "do not check the checksum of the package and update kcl.mod.lock",
    48  			},
    49  
    50  			// KCL arg: --setting, -Y
    51  			&cli.StringSliceFlag{
    52  				Name:    FLAG_SETTING,
    53  				Aliases: []string{"Y"},
    54  				Usage:   "specify the input setting file",
    55  			},
    56  
    57  			// KCL arg: --argument, -D
    58  			&cli.StringSliceFlag{
    59  				Name:    FLAG_ARGUMENT,
    60  				Aliases: []string{"D"},
    61  				Usage:   "specify the top-level argument",
    62  			},
    63  
    64  			// KCL arg: --overrides, -O
    65  			&cli.StringSliceFlag{
    66  				Name:    FLAG_OVERRIDES,
    67  				Aliases: []string{"O"},
    68  				Usage:   "specify the configuration override path and value",
    69  			},
    70  
    71  			// KCL arg: --disable_none, -n
    72  			&cli.BoolFlag{
    73  				Name:    FLAG_DISABLE_NONE,
    74  				Aliases: []string{"n"},
    75  				Usage:   "disable dumping None values",
    76  			},
    77  
    78  			// KCL arg: --sort_keys -k
    79  			&cli.BoolFlag{
    80  				Name:    FLAG_SORT_KEYS,
    81  				Aliases: []string{"k"},
    82  				Usage:   "sort result keys",
    83  			},
    84  		},
    85  		Action: func(c *cli.Context) error {
    86  			return KpmRun(c, kpmcli)
    87  		},
    88  	}
    89  }
    90  
    91  func KpmRun(c *cli.Context, kpmcli *client.KpmClient) error {
    92  	// acquire the lock of the package cache.
    93  	err := kpmcli.AcquirePackageCacheLock()
    94  	if err != nil {
    95  		return err
    96  	}
    97  
    98  	defer func() {
    99  		// release the lock of the package cache after the function returns.
   100  		releaseErr := kpmcli.ReleasePackageCacheLock()
   101  		if releaseErr != nil && err == nil {
   102  			err = releaseErr
   103  		}
   104  	}()
   105  
   106  	kclOpts := CompileOptionFromCli(c)
   107  	kclOpts.SetNoSumCheck(c.Bool(FLAG_NO_SUM_CHECK))
   108  	runEntry, errEvent := runner.FindRunEntryFrom(c.Args().Slice())
   109  	if errEvent != nil {
   110  		return errEvent
   111  	}
   112  
   113  	// 'kpm run' compile the current package under '$pwd'.
   114  	if runEntry.IsEmpty() {
   115  		pwd, err := os.Getwd()
   116  		kclOpts.SetPkgPath(pwd)
   117  
   118  		if err != nil {
   119  			return reporter.NewErrorEvent(
   120  				reporter.Bug, err, "internal bugs, please contact us to fix it.",
   121  			)
   122  		}
   123  		compileResult, err := kpmcli.CompileWithOpts(kclOpts)
   124  		if err != nil {
   125  			return err
   126  		}
   127  		fmt.Println(compileResult.GetRawYamlResult())
   128  	} else {
   129  		var compileResult *kcl.KCLResultList
   130  		var err error
   131  		// 'kpm run' compile the package from the local file system.
   132  		if runEntry.IsLocalFile() || runEntry.IsLocalFileWithKclMod() {
   133  			kclOpts.SetPkgPath(runEntry.PackageSource())
   134  			kclOpts.ExtendEntries(runEntry.EntryFiles())
   135  			if runEntry.IsLocalFile() {
   136  				// If there is only kcl file without kcl package,
   137  				compileResult, err = api.RunWithOpt(kclOpts)
   138  			} else {
   139  				// Else compile the kcl pacakge.
   140  				compileResult, err = kpmcli.CompileWithOpts(kclOpts)
   141  			}
   142  		} else if runEntry.IsTar() {
   143  			// 'kpm run' compile the package from the kcl package tar.
   144  			compileResult, err = kpmcli.CompileTarPkg(runEntry.PackageSource(), kclOpts)
   145  		} else if runEntry.IsGit() {
   146  			gitOpts := git.NewCloneOptions(runEntry.PackageSource(), "", c.String(FLAG_TAG), "", "", nil)
   147  			// 'kpm run' compile the package from the git url
   148  			compileResult, err = kpmcli.CompileGitPkg(gitOpts, kclOpts)
   149  		} else {
   150  			// 'kpm run' compile the package from the OCI reference or url.
   151  			compileResult, err = kpmcli.CompileOciPkg(runEntry.PackageSource(), c.String(FLAG_TAG), kclOpts)
   152  		}
   153  
   154  		if err != nil {
   155  			return err
   156  		}
   157  		fmt.Println(compileResult.GetRawYamlResult())
   158  	}
   159  	return nil
   160  }
   161  
   162  // CompileOptionFromCli will parse the kcl options from the cli context.
   163  func CompileOptionFromCli(c *cli.Context) *opt.CompileOptions {
   164  	opts := opt.DefaultCompileOptions()
   165  
   166  	// --input
   167  	opts.ExtendEntries(c.StringSlice(FLAG_INPUT))
   168  
   169  	// --vendor
   170  	opts.SetVendor(c.Bool(FLAG_VENDOR))
   171  
   172  	// --setting, -Y
   173  	settingsOpt := c.StringSlice(FLAG_SETTING)
   174  	if len(settingsOpt) != 0 {
   175  		for _, sPath := range settingsOpt {
   176  			opts.Merge(kcl.WithSettings(sPath))
   177  		}
   178  		opts.SetHasSettingsYaml(true)
   179  	}
   180  
   181  	// --argument, -D
   182  	opts.Merge(kcl.WithOptions(c.StringSlice(FLAG_ARGUMENT)...))
   183  
   184  	// --overrides, -O
   185  	opts.Merge(kcl.WithOverrides(c.StringSlice(FLAG_OVERRIDES)...))
   186  
   187  	// --disable_none, -n
   188  	opts.Merge(kcl.WithDisableNone(c.Bool(FLAG_DISABLE_NONE)))
   189  
   190  	// --sort_keys, -k
   191  	opts.Merge(kcl.WithSortKeys(c.Bool(FLAG_SORT_KEYS)))
   192  
   193  	return opts
   194  }