diff --git a/pkg/client/client_test.go b/pkg/client/client_test.go index 40ced291..3248f9ab 100644 --- a/pkg/client/client_test.go +++ b/pkg/client/client_test.go @@ -61,6 +61,17 @@ func TestWithGlobalLock(t *testing.T) { test.RunTestWithGlobalLock(t, "TestPullWithModSpec", testPullWithModSpec) test.RunTestWithGlobalLock(t, "testPullWithOnlySpec", testPullWithOnlySpec) test.RunTestWithGlobalLock(t, "TestGraph", testGraph) + test.RunTestWithGlobalLock(t, "testCyclicDependency", testCyclicDependency) + test.RunTestWithGlobalLock(t, "testNewKpmClient", testNewKpmClient) + test.RunTestWithGlobalLock(t, "testLoadPkgFormOci", testLoadPkgFormOci) + test.RunTestWithGlobalLock(t, "testAddWithLocalPath", testAddWithLocalPath) + test.RunTestWithGlobalLock(t, "testRunLocalWithoutArgs", testRunLocalWithoutArgs) + test.RunTestWithGlobalLock(t, "TestRunLocalWithArgs", testRunLocalWithArgs) + test.RunTestWithGlobalLock(t, "testInsecureSkipTLSverifyOCIRegistry", testInsecureSkipTLSverifyOCIRegistry) + test.RunTestWithGlobalLock(t, "testRunWithInsecureSkipTLSverify", testRunWithInsecureSkipTLSverify) + test.RunTestWithGlobalLock(t, "TestAddDepsWithInsecureSkipTLSverify", testAddDepsWithInsecureSkipTLSverify) + test.RunTestWithGlobalLock(t, "testPushWithInsecureSkipTLSverify", testPushWithInsecureSkipTLSverify) + test.RunTestWithGlobalLock(t, "testMetadataOffline", testMetadataOffline) } // TestDownloadOci test download from oci registry. @@ -347,7 +358,7 @@ func testDependencyGraph(t *testing.T) { assert.Equal(t, err, nil) } -func TestCyclicDependency(t *testing.T) { +func testCyclicDependency(t *testing.T) { testDir := getTestDir("test_cyclic_dependency") assert.Equal(t, utils.DirExists(filepath.Join(testDir, "aaa")), true) assert.Equal(t, utils.DirExists(filepath.Join(testDir, "aaa/kcl.mod")), true) @@ -972,7 +983,7 @@ func hasSubdirInTar(tarPath, subdir string) (bool, error) { return false, nil } -func TestNewKpmClient(t *testing.T) { +func testNewKpmClient(t *testing.T) { kpmcli, err := NewKpmClient() assert.Equal(t, err, nil) kpmhome, err := env.GetAbsPkgPath() @@ -1108,7 +1119,7 @@ func testUpdateWithKclModlock(t *testing.T, kpmcli *KpmClient) { }() } -func TestMetadataOffline(t *testing.T) { +func testMetadataOffline(t *testing.T) { kpmcli, err := NewKpmClient() assert.Equal(t, err, nil) @@ -1405,7 +1416,7 @@ func testAddWithGitCommit(t *testing.T) { }() } -func TestLoadPkgFormOci(t *testing.T) { +func testLoadPkgFormOci(t *testing.T) { type testCase struct { Reg string Repo string @@ -1452,7 +1463,7 @@ func TestLoadPkgFormOci(t *testing.T) { } } -func TestAddWithLocalPath(t *testing.T) { +func testAddWithLocalPath(t *testing.T) { testpath := getTestDir("add_with_local_path") @@ -1804,7 +1815,7 @@ func testDependenciesOrder(t *testing.T) { assert.Equal(t, utils.RmNewline(string(got)), utils.RmNewline(string(expect))) } -func TestRunLocalWithoutArgs(t *testing.T) { +func testRunLocalWithoutArgs(t *testing.T) { pkgPath := getTestDir("test_run_options") kpmcli, err := NewKpmClient() @@ -1844,7 +1855,7 @@ func TestRunLocalWithoutArgs(t *testing.T) { } } -func TestRunLocalWithArgs(t *testing.T) { +func testRunLocalWithArgs(t *testing.T) { pkgPath := getTestDir("test_run_options") kpmcli, err := NewKpmClient() @@ -2115,7 +2126,7 @@ func TestVirtualPackageVisiter(t *testing.T) { assert.Equal(t, os.IsNotExist(err), true) } -func TestRunWithInsecureSkipTLSverify(t *testing.T) { +func testRunWithInsecureSkipTLSverify(t *testing.T) { var buf bytes.Buffer @@ -2154,7 +2165,7 @@ func TestRunWithInsecureSkipTLSverify(t *testing.T) { assert.Equal(t, buf.String(), "Called Success\n") } -func TestAddDepsWithInsecureSkipTLSverify(t *testing.T) { +func testAddDepsWithInsecureSkipTLSverify(t *testing.T) { var buf bytes.Buffer @@ -2207,7 +2218,7 @@ func TestAddDepsWithInsecureSkipTLSverify(t *testing.T) { assert.Equal(t, buf.String(), "Called Success\n") } -func TestPushWithInsecureSkipTLSverify(t *testing.T) { +func testPushWithInsecureSkipTLSverify(t *testing.T) { var buf bytes.Buffer mux := http.NewServeMux() diff --git a/pkg/client/pull_test.go b/pkg/client/pull_test.go index 387f2426..a24546ca 100644 --- a/pkg/client/pull_test.go +++ b/pkg/client/pull_test.go @@ -88,7 +88,7 @@ func testPullWithInsecureSkipTLSverify(t *testing.T) { }() } -func TestInsecureSkipTLSverifyOCIRegistry(t *testing.T) { +func testInsecureSkipTLSverifyOCIRegistry(t *testing.T) { var buf bytes.Buffer mux := http.NewServeMux() diff --git a/pkg/client/run.go b/pkg/client/run.go index 8447f81b..e5dffb96 100644 --- a/pkg/client/run.go +++ b/pkg/client/run.go @@ -68,6 +68,7 @@ import ( "io" "os" "path/filepath" + "strings" "kcl-lang.io/kcl-go/pkg/kcl" "kcl-lang.io/kpm/pkg/constants" @@ -440,7 +441,7 @@ func (o *RunOptions) applyCompileOptions(source downloader.Source, kclPkg *pkg.K pkgHome = filepath.Join(workDir, pkgHome) } - return sourcePath == pkgHome + return strings.EqualFold(sourcePath, pkgHome) } // If the sources from cli is not empty, use the sources from cli. @@ -503,6 +504,21 @@ func (o *RunOptions) applyCompileOptions(source downloader.Source, kclPkg *pkg.K } } + // Iterate all the kcl files and transform the '-' in mod relative path to '_' + for i, kfile := range o.KFilenameList { + if utils.IsModRelativePath(kfile) { + modName, entriesPath, err := utils.ParseModRelativePath(kfile) + if err != nil { + return err + } + if modName != "" { + modName = strings.ReplaceAll(modName, "-", "_") + } + modRelativePath := utils.GenerateModRelativePath(modName, entriesPath) + o.KFilenameList[i] = modRelativePath + } + } + return nil } diff --git a/pkg/client/run_test.go b/pkg/client/run_test.go index f3864edf..890eb9a3 100644 --- a/pkg/client/run_test.go +++ b/pkg/client/run_test.go @@ -105,3 +105,31 @@ func TestRun(t *testing.T) { RunTestWithGlobalLockAndKpmCli(t, "TestRunOciWithSettingsFile", testRunOciWithSettingsFile) RunTestWithGlobalLockAndKpmCli(t, "TestRunWithModSpecVersion", testRunWithModSpecVersion) } +func TestRunWithHyphenEntries(t *testing.T) { + testFunc := func(t *testing.T, kpmcli *KpmClient) { + pkgPath := getTestDir("test_run_hyphen_entries") + + res, err := kpmcli.Run( + WithRunSource( + &downloader.Source{ + Local: &downloader.Local{ + Path: pkgPath, + }, + }, + ), + ) + + if err != nil { + t.Fatal(err) + } + + expect, err := os.ReadFile(filepath.Join(pkgPath, "stdout")) + if err != nil { + t.Fatal(err) + } + + assert.Equal(t, utils.RmNewline(res.GetRawYamlResult()), utils.RmNewline(string(expect))) + } + + RunTestWithGlobalLockAndKpmCli(t, "testRunWithHyphenEntries", testFunc) +} diff --git a/pkg/client/test_data/test_run_hyphen_entries/kcl.mod b/pkg/client/test_data/test_run_hyphen_entries/kcl.mod new file mode 100644 index 00000000..c8f8c895 --- /dev/null +++ b/pkg/client/test_data/test_run_hyphen_entries/kcl.mod @@ -0,0 +1,10 @@ +[package] +name = "test_run_hyphen_entries" +edition = "v0.10.0" +version = "0.0.1" + +[dependencies] +flask_manifests = { git = "https://github.com/kcl-lang/flask-demo-kcl-manifests.git", commit = "ade147b", version = "0.0.1" } + +[profile] +entries = ["main.k", "${flask-manifests:KCL_MOD}/main.k"] diff --git a/pkg/client/test_data/test_run_hyphen_entries/kcl.mod.lock b/pkg/client/test_data/test_run_hyphen_entries/kcl.mod.lock new file mode 100644 index 00000000..4dc84770 --- /dev/null +++ b/pkg/client/test_data/test_run_hyphen_entries/kcl.mod.lock @@ -0,0 +1,7 @@ +[dependencies] + [dependencies.flask_manifests] + name = "flask_manifests" + full_name = "flask_manifests_0.0.1" + version = "0.0.1" + url = "https://github.com/kcl-lang/flask-demo-kcl-manifests.git" + commit = "ade147b" diff --git a/pkg/client/test_data/test_run_hyphen_entries/main.k b/pkg/client/test_data/test_run_hyphen_entries/main.k new file mode 100644 index 00000000..a070914a --- /dev/null +++ b/pkg/client/test_data/test_run_hyphen_entries/main.k @@ -0,0 +1 @@ +The_first_kcl_program_current_mod = 'Hello Current Mod World!' \ No newline at end of file diff --git a/pkg/client/test_data/test_run_hyphen_entries/stdout b/pkg/client/test_data/test_run_hyphen_entries/stdout new file mode 100644 index 00000000..09c74f64 --- /dev/null +++ b/pkg/client/test_data/test_run_hyphen_entries/stdout @@ -0,0 +1,18 @@ +The_first_kcl_program_current_mod: Hello Current Mod World! +config: + name: flask-demo + replicas: 1 + labels: + app: flask-demo + service: + type: NodePort + ports: + - port: 5000 + protocol: TCP + targetPort: 5000 + containers: + flaskdemo: + image: kcllang/flask_demo:8d31498e765ff67a2fa9933d4adffe067544b2fe + ports: + - protocol: TCP + containerPort: 5000 diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go index 20b810ac..07b81be8 100644 --- a/pkg/utils/utils.go +++ b/pkg/utils/utils.go @@ -307,6 +307,32 @@ func IsModRelativePath(s string) bool { return re.MatchString(s) } +// ParseModRelativePath parses the package name and path from a mod relative path +func ParseModRelativePath(s string) (string, string, error) { + re := regexp.MustCompile(`^\$\{([a-zA-Z0-9_-]+:)?KCL_MOD\}(.*)$`) + matches := re.FindStringSubmatch(s) + if len(matches) == 0 { + return "", "", fmt.Errorf("invalid mod relative path: %s", s) + } + + // Extract package name and path + var pkgName, path string + if matches[1] != "" { + pkgName = matches[1][:len(matches[1])-1] // Remove the trailing colon + } + path = matches[2] + + return pkgName, path, nil +} + +// GenerateModRelativePath generates a mod relative path from the package name and path +func GenerateModRelativePath(pkgName, path string) string { + if pkgName != "" { + return fmt.Sprintf("${%s:KCL_MOD}%s", pkgName, path) + } + return fmt.Sprintf("${KCL_MOD}%s", path) +} + // MoveFile will move the file from 'src' to 'dest'. // On windows, it will copy the file from 'src' to 'dest', and then delete the file under 'src'. // On unix-like systems, it will rename the file from 'src' to 'dest'.