Repository: kcl-lang/kcl (language: rust)

Issue:
bug: builtin `modpath()` returns a wrong path
## Bug Report

Please answer these questions before submitting your issue. Thanks!

### 1. Minimal reproduce step (Required)

1. create a init kcl module

```
kcl mod init demo
```

2. change the `main.k` in demo

The `main.k`

```
import file

a = file.modpath()
```

3. run the demo

```
kcl run demo
```

<!-- a step by step guide for reproducing the bug. -->

### 2. What did you expect to see? (Required)

```
a: '<the path of the demo>'
```

### 3. What did you see instead (Required)

The result is empty

```
a: ''
```

### 4. What is your KCL components version? (Required)

The main branch

<!-- Paste the output of KCL component version -->



Discussion / hints:

Fix patch:
diff --git a/kclvm/parser/src/entry.rs b/kclvm/parser/src/entry.rs
index 1fa951624..def1f2039 100644
--- a/kclvm/parser/src/entry.rs
+++ b/kclvm/parser/src/entry.rs
@@ -355,27 +355,26 @@ pub fn get_compile_entries_from_paths(
         result.push_entry(entry);
     }
 
-    let pkg_root = if result
+    let main_pkg_paths_count = result
         .get_unique_normal_paths_by_name(kclvm_ast::MAIN_PKG)
-        .len()
-        == 1
-        && opts.work_dir.is_empty()
-    {
+        .len();
+
+    let pkg_root = if main_pkg_paths_count == 1 {
         // If the 'kcl.mod' can be found only once, the package root path will be the path of the 'kcl.mod'.
         result
             .get_unique_normal_paths_by_name(kclvm_ast::MAIN_PKG)
             .get(0)
             .unwrap()
             .to_string()
-    } else if !opts.work_dir.is_empty() {
+    } else if main_pkg_paths_count > 1 && !opts.work_dir.is_empty() {
         // If the 'kcl.mod' can be found more than once, the package root path will be the 'work_dir'.
         if let Some(root_work_dir) = get_pkg_root(&opts.work_dir) {
             root_work_dir
         } else {
-            "".to_string()
+            opts.work_dir.to_string()
         }
     } else {
-        "".to_string()
+        opts.work_dir.to_string()
     };
     result.root_path = pkg_root.clone();
     // Replace the '${KCL_MOD}' of all the paths with package name '__main__'.


Test patch:
diff --git a/kclvm/runner/src/test_issues/github.com/kcl-lang/kcl/1799/main.k b/kclvm/runner/src/test_issues/github.com/kcl-lang/kcl/1799/main.k
new file mode 100644
index 000000000..f0ed83afc
--- /dev/null
+++ b/kclvm/runner/src/test_issues/github.com/kcl-lang/kcl/1799/main.k
@@ -0,0 +1,3 @@
+import file
+
+a = file.modpath()
diff --git a/kclvm/runner/src/tests.rs b/kclvm/runner/src/tests.rs
index 8e0f172e2..d04f55d6d 100644
--- a/kclvm/runner/src/tests.rs
+++ b/kclvm/runner/src/tests.rs
@@ -21,6 +21,7 @@ use kclvm_parser::load_program;
 use kclvm_parser::ParseSession;
 #[cfg(feature = "llvm")]
 use kclvm_sema::resolver::resolve_program;
+use kclvm_utils::path::PathPrefix;
 use serde_json::Value;
 #[cfg(feature = "llvm")]
 use std::fs::create_dir_all;
@@ -711,3 +712,26 @@ fn test_compile_with_symbolic_link() {
         "{\"The_first_kcl_program\": \"Hello World!\", \"b\": 1}"
     );
 }
+
+#[test]
+fn test_kcl_issue_1799() {
+    let main_test_path = PathBuf::from("./src/test_issues/github.com/kcl-lang/kcl/1799/main.k");
+    let mut args = ExecProgramArgs::default();
+    args.k_filename_list
+        .push(main_test_path.display().to_string());
+    args.work_dir = Some(".".to_string());
+    let res = exec_program(Arc::new(ParseSession::default()), &args);
+    assert!(res.is_ok());
+    assert_eq!(
+        res.as_ref().unwrap().yaml_result,
+        format!(
+            "a: {}",
+            main_test_path
+                .parent()
+                .unwrap()
+                .canonicalize()
+                .unwrap()
+                .adjust_canonicalization()
+        )
+    );
+}