kcl-lang.io/kpm@v0.8.7-0.20240520061008-9fc4c5efc8c7/pkg/client/client_test.go (about) 1 package client 2 3 import ( 4 "archive/tar" 5 "bytes" 6 "encoding/json" 7 "fmt" 8 "io" 9 "log" 10 "os" 11 "path/filepath" 12 "runtime" 13 "sort" 14 "strings" 15 "testing" 16 17 "github.com/dominikbraun/graph" 18 "github.com/hashicorp/go-version" 19 "github.com/otiai10/copy" 20 "github.com/stretchr/testify/assert" 21 "golang.org/x/mod/module" 22 "gopkg.in/yaml.v3" 23 "kcl-lang.io/kcl-go/pkg/kcl" 24 "kcl-lang.io/kpm/pkg/downloader" 25 "kcl-lang.io/kpm/pkg/env" 26 "kcl-lang.io/kpm/pkg/git" 27 "kcl-lang.io/kpm/pkg/opt" 28 pkg "kcl-lang.io/kpm/pkg/package" 29 "kcl-lang.io/kpm/pkg/reporter" 30 "kcl-lang.io/kpm/pkg/runner" 31 "kcl-lang.io/kpm/pkg/utils" 32 ) 33 34 const testDataDir = "test_data" 35 36 func getTestDir(subDir string) string { 37 pwd, _ := os.Getwd() 38 testDir := filepath.Join(pwd, testDataDir) 39 testDir = filepath.Join(testDir, subDir) 40 41 return testDir 42 } 43 44 func initTestDir(subDir string) string { 45 testDir := getTestDir(subDir) 46 // clean the test data 47 _ = os.RemoveAll(testDir) 48 _ = os.Mkdir(testDir, 0755) 49 50 return testDir 51 } 52 53 // TestDownloadGit test download from oci registry. 54 func TestDownloadOci(t *testing.T) { 55 testPath := filepath.Join(getTestDir("download"), "k8s_1.27") 56 err := os.MkdirAll(testPath, 0755) 57 assert.Equal(t, err, nil) 58 59 defer func() { 60 err := os.RemoveAll(getTestDir("download")) 61 if err != nil { 62 t.Errorf("Failed to remove directory: %v", err) 63 } 64 }() 65 66 depFromOci := pkg.Dependency{ 67 Name: "k8s", 68 Version: "1.27", 69 Source: pkg.Source{ 70 Oci: &pkg.Oci{ 71 Reg: "ghcr.io", 72 Repo: "kcl-lang/k8s", 73 Tag: "1.27", 74 }, 75 }, 76 } 77 kpmcli, err := NewKpmClient() 78 assert.Equal(t, err, nil) 79 dep, err := kpmcli.Download(&depFromOci, "", testPath) 80 assert.Equal(t, err, nil) 81 assert.Equal(t, dep.Name, "k8s") 82 assert.Equal(t, dep.FullName, "k8s_1.27") 83 assert.Equal(t, dep.Version, "1.27") 84 assert.Equal(t, dep.Sum, "xnYM1FWHAy3m+KcQMQb2rjZouTxumqYt6FGZpu2T4yM=") 85 assert.NotEqual(t, dep.Source.Oci, nil) 86 assert.Equal(t, dep.Source.Oci.Reg, "ghcr.io") 87 assert.Equal(t, dep.Source.Oci.Repo, "kcl-lang/k8s") 88 assert.Equal(t, dep.Source.Oci.Tag, "1.27") 89 assert.Equal(t, dep.LocalFullPath, testPath) 90 91 // Check whether the tar downloaded by `kpm add` has been deleted. 92 downloadPath := getTestDir("download") 93 assert.Equal(t, utils.DirExists(filepath.Join(downloadPath, "k8s_1.27.tar")), false) 94 95 assert.Equal(t, utils.DirExists(filepath.Join(downloadPath, "k8s_1.27")), true) 96 assert.Equal(t, utils.DirExists(filepath.Join(downloadPath, "k8s")), false) 97 } 98 99 // TestDownloadLatestOci tests the case that the version is empty. 100 func TestDownloadLatestOci(t *testing.T) { 101 testPath := filepath.Join(getTestDir("download"), "a_random_name") 102 defer func() { 103 err := os.RemoveAll(getTestDir("download")) 104 if err != nil { 105 t.Errorf("Failed to remove directory: %v", err) 106 } 107 }() 108 err := os.MkdirAll(testPath, 0755) 109 assert.Equal(t, err, nil) 110 depFromOci := pkg.Dependency{ 111 Name: "helloworld", 112 Version: "", 113 Source: pkg.Source{ 114 Oci: &pkg.Oci{ 115 Reg: "ghcr.io", 116 Repo: "kcl-lang/helloworld", 117 Tag: "", 118 }, 119 }, 120 } 121 kpmcli, err := NewKpmClient() 122 assert.Equal(t, err, nil) 123 dep, err := kpmcli.Download(&depFromOci, "", testPath) 124 assert.Equal(t, err, nil) 125 assert.Equal(t, dep.Name, "helloworld") 126 assert.Equal(t, dep.FullName, "helloworld_0.1.2") 127 assert.Equal(t, dep.Version, "0.1.2") 128 assert.Equal(t, dep.Sum, "PN0OMEV9M8VGFn1CtA/T3bcgZmMJmOo+RkBrLKIWYeQ=") 129 assert.NotEqual(t, dep.Source.Oci, nil) 130 assert.Equal(t, dep.Source.Oci.Reg, "ghcr.io") 131 assert.Equal(t, dep.Source.Oci.Repo, "kcl-lang/helloworld") 132 assert.Equal(t, dep.Source.Oci.Tag, "0.1.2") 133 assert.Equal(t, dep.LocalFullPath, testPath) 134 assert.Equal(t, err, nil) 135 136 // Check whether the tar downloaded by `kpm add` has been deleted. 137 assert.Equal(t, utils.DirExists(filepath.Join(testPath, "helloworld_0.1.2.tar")), false) 138 139 assert.Equal(t, utils.DirExists(filepath.Join(getTestDir("download"), "helloworld")), false) 140 } 141 142 func TestDependencyGraph(t *testing.T) { 143 testDir := getTestDir("test_dependency_graph") 144 assert.Equal(t, utils.DirExists(filepath.Join(testDir, "kcl.mod.lock")), false) 145 kpmcli, err := NewKpmClient() 146 assert.Equal(t, err, nil) 147 kclPkg, err := kpmcli.LoadPkgFromPath(testDir) 148 assert.Equal(t, err, nil) 149 150 _, depGraph, err := kpmcli.InitGraphAndDownloadDeps(kclPkg) 151 assert.Equal(t, err, nil) 152 adjMap, err := depGraph.AdjacencyMap() 153 assert.Equal(t, err, nil) 154 155 m := func(Path, Version string) module.Version { 156 return module.Version{Path: Path, Version: Version} 157 } 158 159 edgeProp := graph.EdgeProperties{ 160 Attributes: map[string]string{}, 161 Weight: 0, 162 Data: nil, 163 } 164 assert.Equal(t, adjMap, 165 map[module.Version]map[module.Version]graph.Edge[module.Version]{ 166 m("dependency_graph", "0.0.1"): { 167 m("teleport", "0.1.0"): {Source: m("dependency_graph", "0.0.1"), Target: m("teleport", "0.1.0"), Properties: edgeProp}, 168 m("rabbitmq", "0.0.1"): {Source: m("dependency_graph", "0.0.1"), Target: m("rabbitmq", "0.0.1"), Properties: edgeProp}, 169 m("agent", "0.1.0"): {Source: m("dependency_graph", "0.0.1"), Target: m("agent", "0.1.0"), Properties: edgeProp}, 170 }, 171 m("teleport", "0.1.0"): { 172 m("k8s", "1.28"): {Source: m("teleport", "0.1.0"), Target: m("k8s", "1.28"), Properties: edgeProp}, 173 }, 174 m("rabbitmq", "0.0.1"): { 175 m("k8s", "1.28"): {Source: m("rabbitmq", "0.0.1"), Target: m("k8s", "1.28"), Properties: edgeProp}, 176 }, 177 m("agent", "0.1.0"): { 178 m("k8s", "1.28"): {Source: m("agent", "0.1.0"), Target: m("k8s", "1.28"), Properties: edgeProp}, 179 }, 180 m("k8s", "1.28"): {}, 181 }, 182 ) 183 } 184 185 func TestCyclicDependency(t *testing.T) { 186 testDir := getTestDir("test_cyclic_dependency") 187 assert.Equal(t, utils.DirExists(filepath.Join(testDir, "aaa")), true) 188 assert.Equal(t, utils.DirExists(filepath.Join(testDir, "aaa/kcl.mod")), true) 189 assert.Equal(t, utils.DirExists(filepath.Join(testDir, "bbb")), true) 190 assert.Equal(t, utils.DirExists(filepath.Join(testDir, "bbb/kcl.mod")), true) 191 192 pkg_path := filepath.Join(testDir, "aaa") 193 194 kpmcli, err := NewKpmClient() 195 assert.Equal(t, err, nil) 196 kclPkg, err := kpmcli.LoadPkgFromPath(pkg_path) 197 assert.Equal(t, err, nil) 198 199 currentDir, err := os.Getwd() 200 assert.Equal(t, err, nil) 201 err = os.Chdir(pkg_path) 202 assert.Equal(t, err, nil) 203 204 _, _, err = kpmcli.InitGraphAndDownloadDeps(kclPkg) 205 assert.Equal(t, err, reporter.NewErrorEvent( 206 reporter.CircularDependencyExist, nil, "adding aaa@0.0.1 as a dependency results in a cycle", 207 )) 208 209 err = os.Chdir(currentDir) 210 assert.Equal(t, err, nil) 211 } 212 213 func TestParseKclModFile(t *testing.T) { 214 // Create a temporary directory for testing 215 testDir := initTestDir("test_parse_kcl_mod_file") 216 217 assert.Equal(t, utils.DirExists(filepath.Join(testDir, "kcl.mod")), false) 218 219 kpmcli, err := NewKpmClient() 220 assert.Nil(t, err, "error creating KpmClient") 221 222 // Construct the modFilePath using filepath.Join 223 modFilePath := filepath.Join(testDir, "kcl.mod") 224 225 // Write modFileContent to modFilePath 226 modFileContent := `[dependencies] 227 teleport = "0.1.0" 228 rabbitmq = "0.0.1" 229 gitdep = { git = "git://example.com/repo.git", tag = "v1.0.0" } 230 localdep = { path = "/path/to/local/dependency" } 231 ` 232 233 err = os.WriteFile(modFilePath, []byte(modFileContent), 0644) 234 assert.Nil(t, err, "error writing mod file") 235 236 // Create a mock KclPkg 237 mockKclPkg, err := kpmcli.LoadPkgFromPath(testDir) 238 239 assert.Nil(t, err, "error loading package from path") 240 241 // Test the ParseKclModFile function 242 dependencies, err := kpmcli.ParseKclModFile(mockKclPkg) 243 assert.Nil(t, err, "error parsing kcl.mod file") 244 245 expectedDependencies := map[string]map[string]string{ 246 "teleport": {"version": "0.1.0"}, 247 "rabbitmq": {"version": "0.0.1"}, 248 "gitdep": {"git": "git://example.com/repo.git", "tag": "v1.0.0"}, 249 "localdep": {"path": "/path/to/local/dependency"}, 250 } 251 252 assert.Equal(t, expectedDependencies, dependencies, "parsed dependencies do not match expected dependencies") 253 } 254 func TestInitEmptyPkg(t *testing.T) { 255 testDir := initTestDir("test_init_empty_mod") 256 kclPkg := pkg.NewKclPkg(&opt.InitOptions{Name: "test_name", InitPath: testDir}) 257 kpmcli, err := NewKpmClient() 258 assert.Equal(t, err, nil) 259 err = kpmcli.InitEmptyPkg(&kclPkg) 260 assert.Equal(t, err, nil) 261 262 testKclPkg, err := pkg.LoadKclPkg(testDir) 263 assert.Equal(t, err, nil) 264 assert.Equal(t, testKclPkg.ModFile.Pkg.Name, "test_name") 265 assert.Equal(t, testKclPkg.ModFile.Pkg.Version, "0.0.1") 266 assert.Equal(t, testKclPkg.ModFile.Pkg.Edition, runner.GetKclVersion()) 267 } 268 269 func TestUpdateKclModAndLock(t *testing.T) { 270 testDir := initTestDir("test_data_add_deps") 271 // Init an empty package 272 kclPkg := pkg.NewKclPkg(&opt.InitOptions{ 273 Name: "test_add_deps", 274 InitPath: testDir, 275 }) 276 277 kpmcli, err := NewKpmClient() 278 assert.Equal(t, err, nil) 279 err = kpmcli.InitEmptyPkg(&kclPkg) 280 assert.Equal(t, err, nil) 281 282 dep := pkg.Dependency{ 283 Name: "name", 284 FullName: "test_version", 285 Version: "test_version", 286 Sum: "test_sum", 287 Source: pkg.Source{ 288 Git: &pkg.Git{ 289 Url: "test_url", 290 Tag: "test_tag", 291 }, 292 }, 293 } 294 295 oci_dep := pkg.Dependency{ 296 Name: "oci_name", 297 FullName: "test_version", 298 Version: "test_version", 299 Sum: "test_sum", 300 Source: pkg.Source{ 301 Oci: &pkg.Oci{ 302 Reg: "test_reg", 303 Repo: "test_repo", 304 Tag: "test_tag", 305 }, 306 }, 307 } 308 309 kclPkg.Dependencies.Deps["oci_test"] = oci_dep 310 kclPkg.ModFile.Dependencies.Deps["oci_test"] = oci_dep 311 312 kclPkg.Dependencies.Deps["test"] = dep 313 kclPkg.ModFile.Dependencies.Deps["test"] = dep 314 315 err = kclPkg.ModFile.StoreModFile() 316 assert.Equal(t, err, nil) 317 err = kclPkg.LockDepsVersion() 318 assert.Equal(t, err, nil) 319 320 expectDir := getTestDir("expected") 321 322 if gotKclMod, err := os.ReadFile(filepath.Join(testDir, "kcl.mod")); os.IsNotExist(err) { 323 t.Errorf("failed to find kcl.mod.") 324 } else { 325 assert.Equal(t, len(kclPkg.Dependencies.Deps), 2) 326 assert.Equal(t, len(kclPkg.ModFile.Deps), 2) 327 expectKclMod, _ := os.ReadFile(filepath.Join(expectDir, "kcl.mod")) 328 expectKclModReverse, _ := os.ReadFile(filepath.Join(expectDir, "kcl.reverse.mod")) 329 330 gotKclModStr := utils.RmNewline(string(gotKclMod)) 331 expectKclModStr := utils.RmNewline(string(expectKclMod)) 332 expectKclModReverseStr := utils.RmNewline(string(expectKclModReverse)) 333 334 assert.Equal(t, 335 true, 336 (gotKclModStr == expectKclModStr || gotKclModStr == expectKclModReverseStr), 337 "'%v'\n'%v'\n'%v'\n", 338 gotKclModStr, 339 expectKclModStr, 340 expectKclModReverseStr, 341 ) 342 } 343 344 if gotKclModLock, err := os.ReadFile(filepath.Join(testDir, "kcl.mod.lock")); os.IsNotExist(err) { 345 t.Errorf("failed to find kcl.mod.lock.") 346 } else { 347 assert.Equal(t, len(kclPkg.Dependencies.Deps), 2) 348 assert.Equal(t, len(kclPkg.ModFile.Deps), 2) 349 expectKclModLock, _ := os.ReadFile(filepath.Join(expectDir, "kcl.mod.lock")) 350 expectKclModLockReverse, _ := os.ReadFile(filepath.Join(expectDir, "kcl.mod.reverse.lock")) 351 352 gotKclModLockStr := utils.RmNewline(string(gotKclModLock)) 353 expectKclModLockStr := utils.RmNewline(string(expectKclModLock)) 354 expectKclModLockReverseStr := utils.RmNewline(string(expectKclModLockReverse)) 355 356 assert.Equal(t, 357 true, 358 (gotKclModLockStr == expectKclModLockStr) || (gotKclModLockStr == expectKclModLockReverseStr), 359 "'%v'\n'%v'\n'%v'\n", 360 gotKclModLockStr, 361 expectKclModLockStr, 362 expectKclModLockReverseStr, 363 ) 364 } 365 } 366 367 func TestVendorDeps(t *testing.T) { 368 testDir := getTestDir("resolve_deps") 369 kpm_home := filepath.Join(testDir, "kpm_home") 370 os.RemoveAll(filepath.Join(testDir, "my_kcl")) 371 kcl1Sum, _ := utils.HashDir(filepath.Join(kpm_home, "kcl1")) 372 kcl2Sum, _ := utils.HashDir(filepath.Join(kpm_home, "kcl2")) 373 374 depKcl1 := pkg.Dependency{ 375 Name: "kcl1", 376 FullName: "kcl1", 377 Sum: kcl1Sum, 378 } 379 380 depKcl2 := pkg.Dependency{ 381 Name: "kcl2", 382 FullName: "kcl2", 383 Sum: kcl2Sum, 384 } 385 386 kclPkg := pkg.KclPkg{ 387 ModFile: pkg.ModFile{ 388 HomePath: filepath.Join(testDir, "my_kcl"), 389 // Whether the current package uses the vendor mode 390 // In the vendor mode, kpm will look for the package in the vendor subdirectory 391 // in the current package directory. 392 VendorMode: false, 393 Dependencies: pkg.Dependencies{ 394 Deps: map[string]pkg.Dependency{ 395 "kcl1": depKcl1, 396 "kcl2": depKcl2, 397 }, 398 }, 399 }, 400 HomePath: filepath.Join(testDir, "my_kcl"), 401 // The dependencies in the current kcl package are the dependencies of kcl.mod.lock, 402 // not the dependencies in kcl.mod. 403 Dependencies: pkg.Dependencies{ 404 Deps: map[string]pkg.Dependency{ 405 "kcl1": depKcl1, 406 "kcl2": depKcl2, 407 }, 408 }, 409 } 410 411 mykclVendorPath := filepath.Join(filepath.Join(testDir, "my_kcl"), "vendor") 412 assert.Equal(t, utils.DirExists(mykclVendorPath), false) 413 kpmcli, err := NewKpmClient() 414 kpmcli.homePath = kpm_home 415 assert.Equal(t, err, nil) 416 err = kpmcli.VendorDeps(&kclPkg) 417 assert.Equal(t, err, nil) 418 assert.Equal(t, utils.DirExists(mykclVendorPath), true) 419 assert.Equal(t, utils.DirExists(filepath.Join(mykclVendorPath, "kcl1")), true) 420 assert.Equal(t, utils.DirExists(filepath.Join(mykclVendorPath, "kcl2")), true) 421 422 maps, err := kpmcli.ResolveDepsIntoMap(&kclPkg) 423 assert.Equal(t, err, nil) 424 assert.Equal(t, len(maps), 2) 425 426 os.RemoveAll(filepath.Join(testDir, "my_kcl")) 427 } 428 429 func TestResolveDepsWithOnlyKclMod(t *testing.T) { 430 testDir := getTestDir("resolve_dep_with_kclmod") 431 assert.Equal(t, utils.DirExists(filepath.Join(testDir, "kcl.mod.lock")), false) 432 kpmcli, err := NewKpmClient() 433 assert.Equal(t, err, nil) 434 kclPkg, err := kpmcli.LoadPkgFromPath(testDir) 435 assert.Equal(t, err, nil) 436 depsMap, err := kpmcli.ResolveDepsIntoMap(kclPkg) 437 assert.Equal(t, err, nil) 438 assert.Equal(t, len(depsMap), 1) 439 assert.Equal(t, utils.DirExists(filepath.Join(testDir, "kcl.mod.lock")), true) 440 assert.Equal(t, depsMap["k8s"], filepath.Join(kpmcli.homePath, "k8s_1.17")) 441 assert.Equal(t, utils.DirExists(filepath.Join(kpmcli.homePath, "k8s_1.17")), true) 442 defer func() { 443 err := os.Remove(filepath.Join(testDir, "kcl.mod.lock")) 444 assert.Equal(t, err, nil) 445 }() 446 } 447 448 func TestResolveDepsVendorMode(t *testing.T) { 449 testDir := getTestDir("resolve_deps") 450 kpm_home := filepath.Join(testDir, "kpm_home") 451 home_path := filepath.Join(testDir, "my_kcl_resolve_deps_vendor_mode") 452 os.RemoveAll(home_path) 453 kcl1Sum, _ := utils.HashDir(filepath.Join(kpm_home, "kcl1")) 454 kcl2Sum, _ := utils.HashDir(filepath.Join(kpm_home, "kcl2")) 455 456 depKcl1 := pkg.Dependency{ 457 Name: "kcl1", 458 FullName: "kcl1", 459 Sum: kcl1Sum, 460 } 461 462 depKcl2 := pkg.Dependency{ 463 Name: "kcl2", 464 FullName: "kcl2", 465 Sum: kcl2Sum, 466 } 467 468 kclPkg := pkg.KclPkg{ 469 ModFile: pkg.ModFile{ 470 HomePath: home_path, 471 // Whether the current package uses the vendor mode 472 // In the vendor mode, kpm will look for the package in the vendor subdirectory 473 // in the current package directory. 474 VendorMode: true, 475 Dependencies: pkg.Dependencies{ 476 Deps: map[string]pkg.Dependency{ 477 "kcl1": depKcl1, 478 "kcl2": depKcl2, 479 }, 480 }, 481 }, 482 HomePath: home_path, 483 // The dependencies in the current kcl package are the dependencies of kcl.mod.lock, 484 // not the dependencies in kcl.mod. 485 Dependencies: pkg.Dependencies{ 486 Deps: map[string]pkg.Dependency{ 487 "kcl1": depKcl1, 488 "kcl2": depKcl2, 489 }, 490 }, 491 } 492 mySearchPath := filepath.Join(home_path, "vendor") 493 assert.Equal(t, utils.DirExists(mySearchPath), false) 494 495 kpmcli, err := NewKpmClient() 496 assert.Equal(t, err, nil) 497 kpmcli.homePath = kpm_home 498 499 maps, err := kpmcli.ResolveDepsIntoMap(&kclPkg) 500 assert.Equal(t, err, nil) 501 assert.Equal(t, len(maps), 2) 502 checkDepsMapInSearchPath(t, depKcl1, mySearchPath, maps) 503 504 kclPkg.SetVendorMode(false) 505 maps, err = kpmcli.ResolveDepsIntoMap(&kclPkg) 506 assert.Equal(t, err, nil) 507 assert.Equal(t, len(maps), 2) 508 checkDepsMapInSearchPath(t, depKcl1, kpm_home, maps) 509 510 os.RemoveAll(home_path) 511 } 512 513 func TestCompileWithEntryFile(t *testing.T) { 514 testDir := getTestDir("resolve_deps") 515 kpm_home := filepath.Join(testDir, "kpm_home") 516 home_path := filepath.Join(testDir, "my_kcl_compile") 517 vendor_path := filepath.Join(home_path, "vendor") 518 entry_file := filepath.Join(home_path, "main.k") 519 os.RemoveAll(vendor_path) 520 521 kcl1Sum, _ := utils.HashDir(filepath.Join(kpm_home, "kcl1")) 522 depKcl1 := pkg.Dependency{ 523 Name: "kcl1", 524 FullName: "kcl1", 525 Sum: kcl1Sum, 526 } 527 kcl2Sum, _ := utils.HashDir(filepath.Join(kpm_home, "kcl2")) 528 depKcl2 := pkg.Dependency{ 529 Name: "kcl2", 530 FullName: "kcl2", 531 Sum: kcl2Sum, 532 } 533 534 kclPkg := pkg.KclPkg{ 535 ModFile: pkg.ModFile{ 536 HomePath: home_path, 537 // Whether the current package uses the vendor mode 538 // In the vendor mode, kpm will look for the package in the vendor subdirectory 539 // in the current package directory. 540 VendorMode: true, 541 Dependencies: pkg.Dependencies{ 542 Deps: map[string]pkg.Dependency{ 543 "kcl1": depKcl1, 544 "kcl2": depKcl2, 545 }, 546 }, 547 }, 548 HomePath: home_path, 549 // The dependencies in the current kcl package are the dependencies of kcl.mod.lock, 550 // not the dependencies in kcl.mod. 551 Dependencies: pkg.Dependencies{ 552 Deps: map[string]pkg.Dependency{ 553 "kcl1": depKcl1, 554 "kcl2": depKcl2, 555 }, 556 }, 557 } 558 559 assert.Equal(t, utils.DirExists(vendor_path), false) 560 561 compiler := runner.DefaultCompiler() 562 compiler.AddKFile(entry_file) 563 kpmcli, err := NewKpmClient() 564 assert.Equal(t, err, nil) 565 kpmcli.homePath = kpm_home 566 result, err := kpmcli.Compile(&kclPkg, compiler) 567 assert.Equal(t, err, nil) 568 assert.Equal(t, utils.DirExists(filepath.Join(vendor_path, "kcl1")), true) 569 assert.Equal(t, utils.DirExists(filepath.Join(vendor_path, "kcl2")), true) 570 assert.Equal(t, result.GetRawYamlResult(), "c1: 1\nc2: 2") 571 os.RemoveAll(vendor_path) 572 573 kclPkg.SetVendorMode(false) 574 assert.Equal(t, utils.DirExists(vendor_path), false) 575 576 result, err = kpmcli.Compile(&kclPkg, compiler) 577 assert.Equal(t, err, nil) 578 assert.Equal(t, utils.DirExists(vendor_path), false) 579 assert.Equal(t, result.GetRawYamlResult(), "c1: 1\nc2: 2") 580 os.RemoveAll(vendor_path) 581 } 582 583 func checkDepsMapInSearchPath(t *testing.T, dep pkg.Dependency, searchPath string, maps map[string]string) { 584 assert.Equal(t, maps[dep.Name], filepath.Join(searchPath, dep.FullName)) 585 assert.Equal(t, utils.DirExists(filepath.Join(searchPath, dep.FullName)), true) 586 } 587 588 func TestPackageCurrentPkgPath(t *testing.T) { 589 testDir := getTestDir("tar_kcl_pkg") 590 591 kclPkg, err := pkg.LoadKclPkg(testDir) 592 assert.Equal(t, err, nil) 593 assert.Equal(t, kclPkg.GetPkgTag(), "0.0.1") 594 assert.Equal(t, kclPkg.GetPkgName(), "test_tar") 595 assert.Equal(t, kclPkg.GetPkgFullName(), "test_tar_0.0.1") 596 assert.Equal(t, kclPkg.GetPkgTarName(), "test_tar_0.0.1.tar") 597 598 assert.Equal(t, utils.DirExists(filepath.Join(testDir, kclPkg.GetPkgTarName())), false) 599 600 kpmcli, err := NewKpmClient() 601 assert.Equal(t, err, nil) 602 path, err := kpmcli.PackagePkg(kclPkg, true) 603 assert.Equal(t, err, nil) 604 assert.Equal(t, path, filepath.Join(testDir, kclPkg.GetPkgTarName())) 605 assert.Equal(t, utils.DirExists(filepath.Join(testDir, kclPkg.GetPkgTarName())), true) 606 defer func() { 607 if r := os.RemoveAll(filepath.Join(testDir, kclPkg.GetPkgTarName())); r != nil { 608 err = fmt.Errorf("panic: %v", r) 609 } 610 }() 611 } 612 613 func TestResolveMetadataInJsonStr(t *testing.T) { 614 originalValue := os.Getenv(env.PKG_PATH) 615 defer os.Setenv(env.PKG_PATH, originalValue) 616 617 testDir := getTestDir("resolve_metadata") 618 619 testHomePath := filepath.Join(filepath.Dir(testDir), "test_home_path") 620 prepareKpmHomeInPath(testHomePath) 621 defer os.RemoveAll(testHomePath) 622 623 os.Setenv(env.PKG_PATH, testHomePath) 624 625 kclpkg, err := pkg.LoadKclPkg(testDir) 626 assert.Equal(t, err, nil) 627 628 globalPkgPath, _ := env.GetAbsPkgPath() 629 kpmcli, err := NewKpmClient() 630 assert.Equal(t, err, nil) 631 res, err := kpmcli.ResolveDepsMetadataInJsonStr(kclpkg, true) 632 assert.Equal(t, err, nil) 633 634 expectedDep := pkg.Dependencies{ 635 Deps: make(map[string]pkg.Dependency), 636 } 637 638 expectedDep.Deps["konfig"] = pkg.Dependency{ 639 Name: "konfig", 640 FullName: "konfig_v0.0.1", 641 LocalFullPath: filepath.Join(globalPkgPath, "konfig_v0.0.1"), 642 } 643 644 expectedDepStr, err := json.Marshal(expectedDep) 645 assert.Equal(t, err, nil) 646 647 assert.Equal(t, res, string(expectedDepStr)) 648 649 vendorDir := filepath.Join(testDir, "vendor") 650 if utils.DirExists(vendorDir) { 651 err = os.RemoveAll(vendorDir) 652 assert.Equal(t, err, nil) 653 } 654 kclpkg.SetVendorMode(true) 655 res, err = kpmcli.ResolveDepsMetadataInJsonStr(kclpkg, true) 656 assert.Equal(t, err, nil) 657 assert.Equal(t, utils.DirExists(vendorDir), true) 658 assert.Equal(t, utils.DirExists(filepath.Join(vendorDir, "konfig_v0.0.1")), true) 659 660 expectedDep.Deps["konfig"] = pkg.Dependency{ 661 Name: "konfig", 662 FullName: "konfig_v0.0.1", 663 LocalFullPath: filepath.Join(vendorDir, "konfig_v0.0.1"), 664 } 665 666 expectedDepStr, err = json.Marshal(expectedDep) 667 assert.Equal(t, err, nil) 668 669 assert.Equal(t, res, string(expectedDepStr)) 670 if utils.DirExists(vendorDir) { 671 err = os.RemoveAll(vendorDir) 672 assert.Equal(t, err, nil) 673 } 674 675 kclpkg, err = kpmcli.LoadPkgFromPath(testDir) 676 assert.Equal(t, err, nil) 677 kpmcli.homePath = "not_exist" 678 res, err = kpmcli.ResolveDepsMetadataInJsonStr(kclpkg, false) 679 fmt.Printf("err: %v\n", err) 680 assert.Equal(t, err, nil) 681 assert.Equal(t, utils.DirExists(vendorDir), false) 682 assert.Equal(t, utils.DirExists(filepath.Join(vendorDir, "konfig_v0.0.1")), false) 683 jsonPath, err := json.Marshal(filepath.Join("not_exist", "konfig_v0.0.1")) 684 assert.Equal(t, err, nil) 685 expectedStr := fmt.Sprintf("{\"packages\":{\"konfig\":{\"name\":\"konfig\",\"manifest_path\":%s}}}", string(jsonPath)) 686 assert.Equal(t, res, expectedStr) 687 defer func() { 688 if r := os.RemoveAll(filepath.Join("not_exist", "konfig_v0.0.1")); r != nil { 689 err = fmt.Errorf("panic: %v", r) 690 } 691 }() 692 } 693 694 func prepareKpmHomeInPath(path string) { 695 dirPath := filepath.Join(filepath.Join(path, ".kpm"), "config") 696 _ = os.MkdirAll(dirPath, 0755) 697 698 filePath := filepath.Join(dirPath, "kpm.json") 699 700 _ = os.WriteFile(filePath, []byte("{\"DefaultOciRegistry\":\"ghcr.io\",\"DefaultOciRepo\":\"awesome-kusion\"}"), 0644) 701 } 702 703 func TestPkgWithInVendorMode(t *testing.T) { 704 testDir := getTestDir("test_pkg_with_vendor") 705 kcl1Path := filepath.Join(testDir, "kcl1") 706 707 createKclPkg1 := func() { 708 assert.Equal(t, utils.DirExists(kcl1Path), false) 709 err := os.MkdirAll(kcl1Path, 0755) 710 assert.Equal(t, err, nil) 711 } 712 713 defer func() { 714 if err := os.RemoveAll(kcl1Path); err != nil { 715 log.Printf("failed to close file: %v", err) 716 } 717 }() 718 719 createKclPkg1() 720 721 initOpts := opt.InitOptions{ 722 Name: "kcl1", 723 InitPath: kcl1Path, 724 } 725 kclPkg1 := pkg.NewKclPkg(&initOpts) 726 kpmcli, err := NewKpmClient() 727 assert.Equal(t, err, nil) 728 _, err = kpmcli.AddDepWithOpts(&kclPkg1, &opt.AddOptions{ 729 LocalPath: "localPath", 730 RegistryOpts: opt.RegistryOptions{ 731 Local: &opt.LocalOptions{ 732 Path: filepath.Join(testDir, "kcl2"), 733 }, 734 }, 735 }) 736 737 assert.Equal(t, err, nil) 738 739 // package the kcl1 into tar in vendor mode. 740 tarPath, err := kpmcli.PackagePkg(&kclPkg1, true) 741 assert.Equal(t, err, nil) 742 hasSubDir, err := hasSubdirInTar(tarPath, "vendor") 743 assert.Equal(t, err, nil) 744 assert.Equal(t, hasSubDir, true) 745 746 // clean the kcl1 747 err = os.RemoveAll(kcl1Path) 748 assert.Equal(t, err, nil) 749 750 createKclPkg1() 751 // package the kcl1 into tar in non-vendor mode. 752 tarPath, err = kpmcli.PackagePkg(&kclPkg1, false) 753 assert.Equal(t, err, nil) 754 hasSubDir, err = hasSubdirInTar(tarPath, "vendor") 755 assert.Equal(t, err, nil) 756 assert.Equal(t, hasSubDir, false) 757 } 758 759 // check if the tar file contains the subdir 760 func hasSubdirInTar(tarPath, subdir string) (bool, error) { 761 f, err := os.Open(tarPath) 762 if err != nil { 763 return false, err 764 } 765 defer f.Close() 766 767 tr := tar.NewReader(f) 768 for { 769 hdr, err := tr.Next() 770 if err == io.EOF { 771 break 772 } 773 if hdr.Typeflag == tar.TypeDir && filepath.Base(hdr.Name) == subdir { 774 return true, nil 775 } 776 } 777 778 return false, nil 779 } 780 781 func TestNewKpmClient(t *testing.T) { 782 kpmcli, err := NewKpmClient() 783 assert.Equal(t, err, nil) 784 kpmhome, err := env.GetAbsPkgPath() 785 assert.Equal(t, err, nil) 786 assert.Equal(t, kpmcli.homePath, kpmhome) 787 assert.Equal(t, kpmcli.GetSettings().KpmConfFile, filepath.Join(kpmhome, ".kpm", "config", "kpm.json")) 788 assert.Equal(t, kpmcli.GetSettings().CredentialsFile, filepath.Join(kpmhome, ".kpm", "config", "config.json")) 789 assert.Equal(t, kpmcli.GetSettings().Conf.DefaultOciRepo, "kcl-lang") 790 assert.Equal(t, kpmcli.GetSettings().Conf.DefaultOciRegistry, "ghcr.io") 791 assert.Equal(t, kpmcli.GetSettings().Conf.DefaultOciPlainHttp, false) 792 } 793 794 func TestParseOciOptionFromString(t *testing.T) { 795 kpmcli, err := NewKpmClient() 796 assert.Equal(t, err, nil) 797 oci_ref_with_tag := "test_oci_repo:test_oci_tag" 798 ociOption, err := kpmcli.ParseOciOptionFromString(oci_ref_with_tag, "test_tag") 799 assert.Equal(t, err, nil) 800 assert.Equal(t, ociOption.PkgName, "") 801 assert.Equal(t, ociOption.Reg, "ghcr.io") 802 assert.Equal(t, ociOption.Repo, "kcl-lang/test_oci_repo") 803 assert.Equal(t, ociOption.Tag, "test_oci_tag") 804 805 oci_ref_without_tag := "test_oci_repo:test_oci_tag" 806 ociOption, err = kpmcli.ParseOciOptionFromString(oci_ref_without_tag, "test_tag") 807 assert.Equal(t, err, nil) 808 assert.Equal(t, ociOption.PkgName, "") 809 assert.Equal(t, ociOption.Reg, "ghcr.io") 810 assert.Equal(t, ociOption.Repo, "kcl-lang/test_oci_repo") 811 assert.Equal(t, ociOption.Tag, "test_oci_tag") 812 813 oci_url_with_tag := "oci://test_reg/test_oci_repo" 814 ociOption, err = kpmcli.ParseOciOptionFromString(oci_url_with_tag, "test_tag") 815 assert.Equal(t, err, nil) 816 assert.Equal(t, ociOption.PkgName, "") 817 assert.Equal(t, ociOption.Reg, "test_reg") 818 assert.Equal(t, ociOption.Repo, "/test_oci_repo") 819 assert.Equal(t, ociOption.Tag, "test_tag") 820 } 821 822 func TestGetReleasesFromSource(t *testing.T) { 823 sortVersions := func(versions []string) ([]string, error) { 824 var vers []*version.Version 825 for _, raw := range versions { 826 v, err := version.NewVersion(raw) 827 if err != nil { 828 return nil, err 829 } 830 vers = append(vers, v) 831 } 832 sort.Slice(vers, func(i, j int) bool { 833 return vers[i].LessThan(vers[j]) 834 }) 835 var res []string 836 for _, v := range vers { 837 res = append(res, v.Original()) 838 } 839 return res, nil 840 } 841 842 releases, err := GetReleasesFromSource(pkg.GIT, "https://github.com/kcl-lang/kpm") 843 assert.Equal(t, err, nil) 844 length := len(releases) 845 assert.True(t, length >= 5) 846 releasesVersions, err := sortVersions(releases) 847 assert.Equal(t, err, nil) 848 assert.Equal(t, releasesVersions[:5], []string{"v0.1.0", "v0.2.0", "v0.2.1", "v0.2.2", "v0.2.3"}) 849 850 releases, err = GetReleasesFromSource(pkg.OCI, "oci://ghcr.io/kcl-lang/k8s") 851 assert.Equal(t, err, nil) 852 length = len(releases) 853 assert.True(t, length >= 5) 854 releasesVersions, err = sortVersions(releases) 855 assert.Equal(t, err, nil) 856 assert.Equal(t, releasesVersions[:5], []string{"1.14", "1.15", "1.16", "1.17", "1.18"}) 857 } 858 859 func TestUpdateWithKclMod(t *testing.T) { 860 kpmcli, err := NewKpmClient() 861 assert.Equal(t, err, nil) 862 863 testDir := getTestDir("test_update") 864 src_testDir := filepath.Join(testDir, "test_update_kcl_mod") 865 dest_testDir := filepath.Join(testDir, "test_update_kcl_mod_tmp") 866 err = copy.Copy(src_testDir, dest_testDir) 867 assert.Equal(t, err, nil) 868 869 kclPkg, err := pkg.LoadKclPkg(dest_testDir) 870 assert.Equal(t, err, nil) 871 err = kpmcli.UpdateDeps(kclPkg) 872 assert.Equal(t, err, nil) 873 got_lock_file := filepath.Join(dest_testDir, "kcl.mod.lock") 874 got_content, err := os.ReadFile(got_lock_file) 875 assert.Equal(t, err, nil) 876 877 expected_path := filepath.Join(dest_testDir, "expected") 878 expected_content, err := os.ReadFile(expected_path) 879 880 assert.Equal(t, err, nil) 881 expect := strings.ReplaceAll(string(expected_content), "\r\n", "\n") 882 assert.Equal(t, string(got_content), expect) 883 884 defer func() { 885 err := os.RemoveAll(dest_testDir) 886 assert.Equal(t, err, nil) 887 }() 888 } 889 890 func TestUpdateWithKclModlock(t *testing.T) { 891 kpmcli, err := NewKpmClient() 892 assert.Equal(t, err, nil) 893 894 testDir := getTestDir("test_update") 895 src_testDir := filepath.Join(testDir, "test_update_kcl_mod_lock") 896 dest_testDir := filepath.Join(testDir, "test_update_kcl_mod_lock_tmp") 897 err = copy.Copy(src_testDir, dest_testDir) 898 assert.Equal(t, err, nil) 899 900 kclPkg, err := pkg.LoadKclPkg(dest_testDir) 901 assert.Equal(t, err, nil) 902 err = kpmcli.UpdateDeps(kclPkg) 903 assert.Equal(t, err, nil) 904 got_lock_file := filepath.Join(dest_testDir, "kcl.mod.lock") 905 got_content, err := os.ReadFile(got_lock_file) 906 assert.Equal(t, err, nil) 907 908 expected_path := filepath.Join(dest_testDir, "expected") 909 expected_content, err := os.ReadFile(expected_path) 910 911 assert.Equal(t, err, nil) 912 assert.Equal(t, string(got_content), string(expected_content)) 913 914 defer func() { 915 err := os.RemoveAll(dest_testDir) 916 assert.Equal(t, err, nil) 917 }() 918 } 919 920 func TestMetadataOffline(t *testing.T) { 921 kpmcli, err := NewKpmClient() 922 assert.Equal(t, err, nil) 923 924 testDir := getTestDir("test_metadata_offline") 925 kclMod := filepath.Join(testDir, "kcl.mod") 926 uglyKclMod := filepath.Join(testDir, "ugly.kcl.mod") 927 BeautifulKclMod := filepath.Join(testDir, "beautiful.kcl.mod") 928 929 uglyContent, err := os.ReadFile(uglyKclMod) 930 assert.Equal(t, err, nil) 931 err = copy.Copy(uglyKclMod, kclMod) 932 assert.Equal(t, err, nil) 933 defer func() { 934 err := os.Remove(kclMod) 935 assert.Equal(t, err, nil) 936 }() 937 938 beautifulContent, err := os.ReadFile(BeautifulKclMod) 939 assert.Equal(t, err, nil) 940 kclPkg, err := pkg.LoadKclPkg(testDir) 941 assert.Equal(t, err, nil) 942 943 res, err := kpmcli.ResolveDepsMetadataInJsonStr(kclPkg, false) 944 assert.Equal(t, err, nil) 945 assert.Equal(t, res, "{\"packages\":{}}") 946 content_after_metadata, err := os.ReadFile(kclMod) 947 assert.Equal(t, err, nil) 948 assert.Equal(t, string(content_after_metadata), string(uglyContent)) 949 950 res, err = kpmcli.ResolveDepsMetadataInJsonStr(kclPkg, true) 951 assert.Equal(t, err, nil) 952 assert.Equal(t, res, "{\"packages\":{}}") 953 content_after_metadata, err = os.ReadFile(kclMod) 954 assert.Equal(t, err, nil) 955 assert.Equal(t, utils.RmNewline(string(content_after_metadata)), utils.RmNewline(string(beautifulContent))) 956 } 957 958 func TestAddWithNoSumCheck(t *testing.T) { 959 pkgPath := getTestDir("test_add_no_sum_check") 960 err := copy.Copy(filepath.Join(pkgPath, "kcl.mod.bak"), filepath.Join(pkgPath, "kcl.mod")) 961 assert.Equal(t, err, nil) 962 963 kpmcli, err := NewKpmClient() 964 assert.Equal(t, err, nil) 965 kclPkg, err := kpmcli.LoadPkgFromPath(pkgPath) 966 assert.Equal(t, err, nil) 967 968 opts := opt.AddOptions{ 969 LocalPath: pkgPath, 970 RegistryOpts: opt.RegistryOptions{ 971 Oci: &opt.OciOptions{ 972 Reg: "ghcr.io", 973 Repo: "kcl-lang", 974 PkgName: "helloworld", 975 Tag: "0.1.0", 976 }, 977 }, 978 NoSumCheck: true, 979 } 980 981 _, err = kpmcli.AddDepWithOpts(kclPkg, &opts) 982 assert.Equal(t, err, nil) 983 assert.Equal(t, utils.DirExists(filepath.Join(pkgPath, "kcl.mod.lock")), false) 984 985 opts.NoSumCheck = false 986 _, err = kpmcli.AddDepWithOpts(kclPkg, &opts) 987 assert.Equal(t, err, nil) 988 assert.Equal(t, utils.DirExists(filepath.Join(pkgPath, "kcl.mod.lock")), true) 989 defer func() { 990 _ = os.Remove(filepath.Join(pkgPath, "kcl.mod.lock")) 991 _ = os.Remove(filepath.Join(pkgPath, "kcl.mod")) 992 }() 993 } 994 995 func TestRunWithNoSumCheck(t *testing.T) { 996 pkgPath := getTestDir("test_run_no_sum_check") 997 998 kpmcli, err := NewKpmClient() 999 assert.Equal(t, err, nil) 1000 1001 opts := opt.DefaultCompileOptions() 1002 opts.SetNoSumCheck(true) 1003 opts.SetPkgPath(pkgPath) 1004 1005 _, err = kpmcli.CompileWithOpts(opts) 1006 assert.Equal(t, err, nil) 1007 assert.Equal(t, utils.DirExists(filepath.Join(pkgPath, "kcl.mod.lock")), false) 1008 1009 opts = opt.DefaultCompileOptions() 1010 opts.SetPkgPath(pkgPath) 1011 opts.SetNoSumCheck(false) 1012 _, err = kpmcli.CompileWithOpts(opts) 1013 assert.Equal(t, err, nil) 1014 assert.Equal(t, utils.DirExists(filepath.Join(pkgPath, "kcl.mod.lock")), true) 1015 1016 defer func() { 1017 _ = os.Remove(filepath.Join(pkgPath, "kcl.mod.lock")) 1018 }() 1019 } 1020 1021 func TestRunGit(t *testing.T) { 1022 kpmcli, err := NewKpmClient() 1023 assert.Equal(t, err, nil) 1024 1025 testPath := getTestDir("test_run_git") 1026 1027 opts := opt.DefaultCompileOptions() 1028 gitOpts := git.NewCloneOptions("https://github.com/KusionStack/catalog", "", "0.1.2", "", filepath.Join(testPath, "catalog"), nil) 1029 defer func() { 1030 _ = os.RemoveAll(filepath.Join(testPath, "catalog")) 1031 }() 1032 1033 testCases := []struct { 1034 entryPath string 1035 expectFile string 1036 }{ 1037 {"models/samples/hellocollaset/prod/main.k", "expect1.json"}, 1038 {"models/samples/pgadmin/base/base.k", "expect2.json"}, 1039 {"models/samples/wordpress/prod/main.k", "expect3.json"}, 1040 } 1041 1042 for _, tc := range testCases { 1043 opts.SetEntries([]string{tc.entryPath}) 1044 result, err := kpmcli.CompileGitPkg(gitOpts, opts) 1045 assert.Equal(t, err, nil) 1046 1047 fileBytes, err := os.ReadFile(filepath.Join(testPath, tc.expectFile)) 1048 assert.Equal(t, err, nil) 1049 1050 var expectObj map[string]interface{} 1051 err = json.Unmarshal(fileBytes, &expectObj) 1052 assert.Equal(t, err, nil) 1053 1054 var gotObj map[string]interface{} 1055 err = json.Unmarshal([]byte(result.GetRawJsonResult()), &gotObj) 1056 assert.Equal(t, err, nil) 1057 1058 assert.Equal(t, gotObj, expectObj) 1059 } 1060 } 1061 1062 func TestUpdateWithNoSumCheck(t *testing.T) { 1063 pkgPath := getTestDir("test_update_no_sum_check") 1064 kpmcli, err := NewKpmClient() 1065 assert.Equal(t, err, nil) 1066 1067 var buf bytes.Buffer 1068 kpmcli.SetLogWriter(&buf) 1069 1070 kpmcli.SetNoSumCheck(true) 1071 kclPkg, err := kpmcli.LoadPkgFromPath(pkgPath) 1072 assert.Equal(t, err, nil) 1073 1074 err = kpmcli.UpdateDeps(kclPkg) 1075 assert.Equal(t, err, nil) 1076 assert.Equal(t, utils.DirExists(filepath.Join(pkgPath, "kcl.mod.lock")), false) 1077 assert.Equal(t, buf.String(), "") 1078 1079 kpmcli.SetNoSumCheck(false) 1080 kclPkg, err = kpmcli.LoadPkgFromPath(pkgPath) 1081 assert.Equal(t, err, nil) 1082 1083 err = kpmcli.UpdateDeps(kclPkg) 1084 assert.Equal(t, err, nil) 1085 assert.Equal(t, utils.DirExists(filepath.Join(pkgPath, "kcl.mod.lock")), true) 1086 assert.Equal(t, buf.String(), "adding 'helloworld' with version '0.1.1'\ndownloading 'kcl-lang/helloworld:0.1.1' from 'ghcr.io/kcl-lang/helloworld:0.1.1'\n") 1087 1088 defer func() { 1089 _ = os.Remove(filepath.Join(pkgPath, "kcl.mod.lock")) 1090 }() 1091 } 1092 1093 func TestAddWithDiffVersionNoSumCheck(t *testing.T) { 1094 pkgPath := getTestDir("test_add_diff_version") 1095 1096 pkgWithSumCheckPath := filepath.Join(pkgPath, "no_sum_check") 1097 pkgWithSumCheckPathModBak := filepath.Join(pkgWithSumCheckPath, "kcl.mod.bak") 1098 pkgWithSumCheckPathMod := filepath.Join(pkgWithSumCheckPath, "kcl.mod") 1099 pkgWithSumCheckPathModExpect := filepath.Join(pkgWithSumCheckPath, "kcl.mod.expect") 1100 pkgWithSumCheckPathModLock := filepath.Join(pkgWithSumCheckPath, "kcl.mod.lock") 1101 1102 err := copy.Copy(pkgWithSumCheckPathModBak, pkgWithSumCheckPathMod) 1103 assert.Equal(t, err, nil) 1104 1105 kpmcli, err := NewKpmClient() 1106 assert.Equal(t, err, nil) 1107 kclPkg, err := kpmcli.LoadPkgFromPath(pkgWithSumCheckPath) 1108 assert.Equal(t, err, nil) 1109 1110 opts := opt.AddOptions{ 1111 LocalPath: pkgPath, 1112 RegistryOpts: opt.RegistryOptions{ 1113 Oci: &opt.OciOptions{ 1114 Reg: "ghcr.io", 1115 Repo: "kcl-lang", 1116 PkgName: "helloworld", 1117 Tag: "0.1.1", 1118 }, 1119 }, 1120 NoSumCheck: true, 1121 } 1122 1123 _, err = kpmcli.AddDepWithOpts(kclPkg, &opts) 1124 assert.Equal(t, err, nil) 1125 assert.Equal(t, utils.DirExists(pkgWithSumCheckPathModLock), false) 1126 1127 modContent, err := os.ReadFile(pkgWithSumCheckPathMod) 1128 modContentStr := strings.ReplaceAll(string(modContent), "\r\n", "") 1129 modContentStr = strings.ReplaceAll(string(modContentStr), "\n", "") 1130 assert.Equal(t, err, nil) 1131 modExpectContent, err := os.ReadFile(pkgWithSumCheckPathModExpect) 1132 modExpectContentStr := strings.ReplaceAll(string(modExpectContent), "\r\n", "") 1133 modExpectContentStr = strings.ReplaceAll(modExpectContentStr, "\n", "") 1134 assert.Equal(t, err, nil) 1135 assert.Equal(t, modContentStr, modExpectContentStr) 1136 1137 opts.NoSumCheck = false 1138 _, err = kpmcli.AddDepWithOpts(kclPkg, &opts) 1139 assert.Equal(t, err, nil) 1140 assert.Equal(t, utils.DirExists(pkgWithSumCheckPathModLock), true) 1141 modContent, err = os.ReadFile(pkgWithSumCheckPathMod) 1142 modContentStr = strings.ReplaceAll(string(modContent), "\r\n", "") 1143 modContentStr = strings.ReplaceAll(modContentStr, "\n", "") 1144 assert.Equal(t, err, nil) 1145 assert.Equal(t, modContentStr, modExpectContentStr) 1146 1147 defer func() { 1148 _ = os.Remove(pkgWithSumCheckPathMod) 1149 _ = os.Remove(pkgWithSumCheckPathModLock) 1150 }() 1151 } 1152 1153 func TestAddWithDiffVersionWithSumCheck(t *testing.T) { 1154 pkgPath := getTestDir("test_add_diff_version") 1155 1156 pkgWithSumCheckPath := filepath.Join(pkgPath, "with_sum_check") 1157 pkgWithSumCheckPathModBak := filepath.Join(pkgWithSumCheckPath, "kcl.mod.bak") 1158 pkgWithSumCheckPathMod := filepath.Join(pkgWithSumCheckPath, "kcl.mod") 1159 pkgWithSumCheckPathModExpect := filepath.Join(pkgWithSumCheckPath, "kcl.mod.expect") 1160 pkgWithSumCheckPathModLock := filepath.Join(pkgWithSumCheckPath, "kcl.mod.lock") 1161 pkgWithSumCheckPathModLockBak := filepath.Join(pkgWithSumCheckPath, "kcl.mod.lock.bak") 1162 pkgWithSumCheckPathModLockExpect := filepath.Join(pkgWithSumCheckPath, "kcl.mod.lock.expect") 1163 1164 err := copy.Copy(pkgWithSumCheckPathModBak, pkgWithSumCheckPathMod) 1165 assert.Equal(t, err, nil) 1166 err = copy.Copy(pkgWithSumCheckPathModLockBak, pkgWithSumCheckPathModLock) 1167 assert.Equal(t, err, nil) 1168 1169 kpmcli, err := NewKpmClient() 1170 assert.Equal(t, err, nil) 1171 kclPkg, err := kpmcli.LoadPkgFromPath(pkgWithSumCheckPath) 1172 assert.Equal(t, err, nil) 1173 1174 opts := opt.AddOptions{ 1175 LocalPath: pkgPath, 1176 RegistryOpts: opt.RegistryOptions{ 1177 Oci: &opt.OciOptions{ 1178 Reg: "ghcr.io", 1179 Repo: "kcl-lang", 1180 PkgName: "helloworld", 1181 Tag: "0.1.1", 1182 }, 1183 }, 1184 } 1185 1186 _, err = kpmcli.AddDepWithOpts(kclPkg, &opts) 1187 assert.Equal(t, err, nil) 1188 1189 modContent, err := os.ReadFile(pkgWithSumCheckPathMod) 1190 modContentStr := strings.ReplaceAll(string(modContent), "\r\n", "") 1191 modContentStr = strings.ReplaceAll(modContentStr, "\n", "") 1192 assert.Equal(t, err, nil) 1193 1194 modExpectContent, err := os.ReadFile(pkgWithSumCheckPathModExpect) 1195 modExpectContentStr := strings.ReplaceAll(string(modExpectContent), "\r\n", "") 1196 modExpectContentStr = strings.ReplaceAll(modExpectContentStr, "\n", "") 1197 1198 assert.Equal(t, err, nil) 1199 assert.Equal(t, modContentStr, modExpectContentStr) 1200 1201 modLockContent, err := os.ReadFile(pkgWithSumCheckPathModLock) 1202 modLockContentStr := strings.ReplaceAll(string(modLockContent), "\r\n", "") 1203 modLockContentStr = strings.ReplaceAll(modLockContentStr, "\n", "") 1204 assert.Equal(t, err, nil) 1205 modLockExpectContent, err := os.ReadFile(pkgWithSumCheckPathModLockExpect) 1206 modLockExpectContentStr := strings.ReplaceAll(string(modLockExpectContent), "\r\n", "") 1207 modLockExpectContentStr = strings.ReplaceAll(modLockExpectContentStr, "\n", "") 1208 assert.Equal(t, err, nil) 1209 assert.Equal(t, modLockContentStr, modLockExpectContentStr) 1210 1211 defer func() { 1212 _ = os.Remove(pkgWithSumCheckPathMod) 1213 _ = os.Remove(pkgWithSumCheckPathModLock) 1214 }() 1215 } 1216 1217 func TestAddWithGitCommit(t *testing.T) { 1218 pkgPath := getTestDir("add_with_git_commit") 1219 1220 testPkgPath := "" 1221 if runtime.GOOS == "windows" { 1222 testPkgPath = filepath.Join(pkgPath, "test_pkg_win") 1223 } else { 1224 testPkgPath = filepath.Join(pkgPath, "test_pkg") 1225 } 1226 1227 testPkgPathModBak := filepath.Join(testPkgPath, "kcl.mod.bak") 1228 testPkgPathMod := filepath.Join(testPkgPath, "kcl.mod") 1229 testPkgPathModExpect := filepath.Join(testPkgPath, "kcl.mod.expect") 1230 testPkgPathModLock := filepath.Join(testPkgPath, "kcl.mod.lock") 1231 testPkgPathModLockBak := filepath.Join(testPkgPath, "kcl.mod.lock.bak") 1232 testPkgPathModLockExpect := filepath.Join(testPkgPath, "kcl.mod.lock.expect") 1233 1234 err := copy.Copy(testPkgPathModBak, testPkgPathMod) 1235 assert.Equal(t, err, nil) 1236 err = copy.Copy(testPkgPathModLockBak, testPkgPathModLock) 1237 assert.Equal(t, err, nil) 1238 1239 kpmcli, err := NewKpmClient() 1240 assert.Equal(t, err, nil) 1241 kclPkg, err := kpmcli.LoadPkgFromPath(testPkgPath) 1242 assert.Equal(t, err, nil) 1243 1244 opts := opt.AddOptions{ 1245 LocalPath: testPkgPath, 1246 RegistryOpts: opt.RegistryOptions{ 1247 Git: &opt.GitOptions{ 1248 Url: "https://github.com/KusionStack/catalog.git", 1249 Commit: "a29e3db", 1250 }, 1251 }, 1252 } 1253 kpmcli.SetLogWriter(nil) 1254 _, err = kpmcli.AddDepWithOpts(kclPkg, &opts) 1255 1256 assert.Equal(t, err, nil) 1257 1258 modContent, err := os.ReadFile(testPkgPathMod) 1259 modContentStr := strings.ReplaceAll(string(modContent), "\r\n", "") 1260 modContentStr = strings.ReplaceAll(modContentStr, "\n", "") 1261 assert.Equal(t, err, nil) 1262 1263 modExpectContent, err := os.ReadFile(testPkgPathModExpect) 1264 modExpectContentStr := strings.ReplaceAll(string(modExpectContent), "\r\n", "") 1265 modExpectContentStr = strings.ReplaceAll(modExpectContentStr, "\n", "") 1266 1267 assert.Equal(t, err, nil) 1268 assert.Equal(t, modContentStr, modExpectContentStr) 1269 1270 modLockContent, err := os.ReadFile(testPkgPathModLock) 1271 modLockContentStr := strings.ReplaceAll(string(modLockContent), "\r\n", "") 1272 modLockContentStr = strings.ReplaceAll(modLockContentStr, "\n", "") 1273 assert.Equal(t, err, nil) 1274 modLockExpectContent, err := os.ReadFile(testPkgPathModLockExpect) 1275 modLockExpectContentStr := strings.ReplaceAll(string(modLockExpectContent), "\r\n", "") 1276 modLockExpectContentStr = strings.ReplaceAll(modLockExpectContentStr, "\n", "") 1277 assert.Equal(t, err, nil) 1278 assert.Equal(t, modLockContentStr, modLockExpectContentStr) 1279 1280 defer func() { 1281 _ = os.Remove(testPkgPathMod) 1282 _ = os.Remove(testPkgPathModLock) 1283 }() 1284 } 1285 1286 func TestLoadPkgFormOci(t *testing.T) { 1287 type testCase struct { 1288 Reg string 1289 Repo string 1290 Tag string 1291 Name string 1292 } 1293 1294 testCases := []testCase{ 1295 { 1296 Reg: "ghcr.io", 1297 Repo: "kusionstack/opsrule", 1298 Tag: "0.0.9", 1299 Name: "opsrule", 1300 }, 1301 { 1302 Reg: "ghcr.io", 1303 Repo: "kcl-lang/helloworld", 1304 Tag: "0.1.1", 1305 Name: "helloworld", 1306 }, 1307 } 1308 1309 cli, err := NewKpmClient() 1310 assert.Equal(t, err, nil) 1311 pkgPath := getTestDir("test_load_pkg_from_oci") 1312 1313 for _, tc := range testCases { 1314 localpath := filepath.Join(pkgPath, tc.Name) 1315 1316 err = os.MkdirAll(localpath, 0755) 1317 assert.Equal(t, err, nil) 1318 defer func() { 1319 err := os.RemoveAll(localpath) 1320 assert.Equal(t, err, nil) 1321 }() 1322 1323 kclpkg, err := cli.DownloadPkgFromOci(&pkg.Oci{ 1324 Reg: tc.Reg, 1325 Repo: tc.Repo, 1326 Tag: tc.Tag, 1327 }, localpath) 1328 assert.Equal(t, err, nil) 1329 assert.Equal(t, kclpkg.GetPkgName(), tc.Name) 1330 } 1331 } 1332 1333 func TestAddWithLocalPath(t *testing.T) { 1334 1335 testpath := getTestDir("add_with_local_path") 1336 1337 initpath := filepath.Join(testpath, "init") 1338 tmppath := filepath.Join(testpath, "tmp") 1339 expectpath := filepath.Join(testpath, "expect") 1340 1341 defer func() { 1342 err := os.RemoveAll(tmppath) 1343 assert.Equal(t, err, nil) 1344 }() 1345 1346 err := copy.Copy(initpath, tmppath) 1347 assert.Equal(t, err, nil) 1348 1349 kpmcli, err := NewKpmClient() 1350 assert.Equal(t, err, nil) 1351 kpmcli.SetLogWriter(nil) 1352 1353 tmpPkgPath := filepath.Join(tmppath, "pkg") 1354 opts := opt.AddOptions{ 1355 LocalPath: tmpPkgPath, 1356 RegistryOpts: opt.RegistryOptions{ 1357 Oci: &opt.OciOptions{ 1358 Reg: "ghcr.io", 1359 Repo: "kcl-lang", 1360 PkgName: "helloworld", 1361 Tag: "0.1.1", 1362 }, 1363 }, 1364 } 1365 1366 kclPkg, err := kpmcli.LoadPkgFromPath(tmpPkgPath) 1367 assert.Equal(t, err, nil) 1368 1369 _, err = kpmcli.AddDepWithOpts(kclPkg, &opts) 1370 assert.Equal(t, err, nil) 1371 1372 gotpkg, err := kpmcli.LoadPkgFromPath(tmpPkgPath) 1373 assert.Equal(t, err, nil) 1374 expectpath = filepath.Join(expectpath, "pkg") 1375 expectpkg, err := kpmcli.LoadPkgFromPath(expectpath) 1376 assert.Equal(t, err, nil) 1377 1378 assert.Equal(t, len(gotpkg.Dependencies.Deps), len(expectpkg.Dependencies.Deps)) 1379 assert.Equal(t, gotpkg.Dependencies.Deps["dep_pkg"].FullName, expectpkg.Dependencies.Deps["dep_pkg"].FullName) 1380 assert.Equal(t, gotpkg.Dependencies.Deps["dep_pkg"].Version, expectpkg.Dependencies.Deps["dep_pkg"].Version) 1381 assert.Equal(t, gotpkg.Dependencies.Deps["dep_pkg"].LocalFullPath, filepath.Join(tmppath, "dep_pkg")) 1382 assert.Equal(t, gotpkg.Dependencies.Deps["dep_pkg"].Source.Local.Path, "../dep_pkg") 1383 } 1384 1385 func TestRunOciWithSettingsFile(t *testing.T) { 1386 kpmcli, err := NewKpmClient() 1387 assert.Equal(t, err, nil) 1388 kpmcli.SetLogWriter(nil) 1389 opts := opt.DefaultCompileOptions() 1390 opts.SetEntries([]string{}) 1391 opts.Merge(kcl.WithSettings(filepath.Join(".", "test_data", "test_run_oci_with_settings", "kcl.yaml"))) 1392 opts.SetHasSettingsYaml(true) 1393 _, err = kpmcli.CompileOciPkg("oci://ghcr.io/kcl-lang/helloworld", "", opts) 1394 assert.Equal(t, err, nil) 1395 } 1396 1397 func TestRunGitWithLocalDep(t *testing.T) { 1398 kpmcli, err := NewKpmClient() 1399 assert.Equal(t, err, nil) 1400 1401 testPath := getTestDir("test_run_git_with_local_dep") 1402 defer func() { 1403 _ = os.RemoveAll(filepath.Join(testPath, "catalog")) 1404 }() 1405 1406 testCases := []struct { 1407 ref string 1408 expectFile string 1409 }{ 1410 {"8308200", "expect1.yaml"}, 1411 {"0b3f5ab", "expect2.yaml"}, 1412 } 1413 1414 for _, tc := range testCases { 1415 1416 expectPath := filepath.Join(testPath, tc.expectFile) 1417 opts := opt.DefaultCompileOptions() 1418 gitOpts := git.NewCloneOptions("https://github.com/kcl-lang/flask-demo-kcl-manifests.git", tc.ref, "", "", "", nil) 1419 1420 result, err := kpmcli.CompileGitPkg(gitOpts, opts) 1421 assert.Equal(t, err, nil) 1422 1423 fileBytes, err := os.ReadFile(expectPath) 1424 assert.Equal(t, err, nil) 1425 1426 var expectObj map[string]interface{} 1427 err = yaml.Unmarshal(fileBytes, &expectObj) 1428 assert.Equal(t, err, nil) 1429 1430 var gotObj map[string]interface{} 1431 err = yaml.Unmarshal([]byte(result.GetRawJsonResult()), &gotObj) 1432 assert.Equal(t, err, nil) 1433 1434 assert.Equal(t, gotObj, expectObj) 1435 } 1436 } 1437 1438 func TestLoadOciUrlDiffSetting(t *testing.T) { 1439 kpmcli, err := NewKpmClient() 1440 assert.Equal(t, err, nil) 1441 1442 testPath := getTestDir("diffsettings") 1443 1444 pkg, err := kpmcli.LoadPkgFromPath(testPath) 1445 assert.Equal(t, err, nil) 1446 assert.Equal(t, len(pkg.ModFile.Deps), 1) 1447 assert.Equal(t, pkg.ModFile.Deps["oci_pkg"].Oci.Reg, "docker.io") 1448 assert.Equal(t, pkg.ModFile.Deps["oci_pkg"].Oci.Repo, "test/oci_pkg") 1449 assert.Equal(t, pkg.ModFile.Deps["oci_pkg"].Oci.Tag, "0.0.1") 1450 assert.Equal(t, err, nil) 1451 } 1452 1453 func TestOciDownloader(t *testing.T) { 1454 // make test case running in order to test the log output 1455 testRunWithOciDownloader(t) 1456 testAddWithOciDownloader(t) 1457 } 1458 1459 func testAddWithOciDownloader(t *testing.T) { 1460 kpmCli, err := NewKpmClient() 1461 path := getTestDir("test_oci_downloader") 1462 assert.Equal(t, err, nil) 1463 1464 kpmCli.DepDownloader = downloader.NewOciDownloader("linux/amd64") 1465 kpkg, err := kpmCli.LoadPkgFromPath(filepath.Join(path, "add_dep", "pkg")) 1466 assert.Equal(t, err, nil) 1467 dep := pkg.Dependency{ 1468 Name: "helloworld", 1469 FullName: "helloworld_0.0.3", 1470 Source: pkg.Source{ 1471 Oci: &pkg.Oci{ 1472 Reg: "ghcr.io", 1473 Repo: "zong-zhe/helloworld", 1474 Tag: "0.0.3", 1475 }, 1476 }, 1477 } 1478 kpkg.HomePath = filepath.Join(path, "add_dep", "pkg") 1479 err = kpmCli.AddDepToPkg(kpkg, &dep) 1480 assert.Equal(t, err, nil) 1481 kpkg.NoSumCheck = false 1482 err = kpkg.UpdateModAndLockFile() 1483 assert.Equal(t, err, nil) 1484 1485 expectmod := filepath.Join(path, "add_dep", "pkg", "except") 1486 expectmodContent, err := os.ReadFile(expectmod) 1487 assert.Equal(t, err, nil) 1488 gotContent, err := os.ReadFile(filepath.Join(path, "add_dep", "pkg", "kcl.mod")) 1489 assert.Equal(t, err, nil) 1490 assert.Equal(t, utils.RmNewline(string(expectmodContent)), utils.RmNewline(string(gotContent))) 1491 } 1492 1493 func testRunWithOciDownloader(t *testing.T) { 1494 kpmCli, err := NewKpmClient() 1495 path := getTestDir("test_oci_downloader") 1496 assert.Equal(t, err, nil) 1497 1498 kpmCli.DepDownloader = downloader.NewOciDownloader("linux/amd64") 1499 1500 var buf bytes.Buffer 1501 writer := io.MultiWriter(&buf, os.Stdout) 1502 1503 res, err := kpmCli.RunWithOpts( 1504 opt.WithEntries([]string{filepath.Join(path, "run_pkg", "pkg", "main.k")}), 1505 opt.WithKclOption(kcl.WithWorkDir(filepath.Join(path, "run_pkg", "pkg"))), 1506 opt.WithNoSumCheck(true), 1507 opt.WithLogWriter(writer), 1508 ) 1509 assert.Equal(t, err, nil) 1510 assert.Equal(t, buf.String(), "downloading 'zong-zhe/helloworld:0.0.3' from 'ghcr.io/zong-zhe/helloworld:0.0.3'\n") 1511 assert.Equal(t, res.GetRawYamlResult(), "The_first_kcl_program: Hello World!") 1512 }