Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support find kcl files from 'workdir'. #689

Merged
merged 4 commits into from
Aug 31, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ubuntu_test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ jobs:
uses: coverallsapp/github-action@master
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
path-to-lcov: ./kclvm/.kclvm/lcov.info
path-to-lcov: ./kclvm/.kclvm_cov/lcov.info

- uses: actions/upload-artifact@v3
with:
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ lark_parser.pickle

# KCLVM cache and temp output
.kclvm
.kclvm_cov
*.dylib
*.so
*.dll
Expand Down
5 changes: 5 additions & 0 deletions kclvm/cmd/src/test_data/instances/test_inst_11/kcl.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[package]
name = "test_inst_11"
edition = "0.0.1"
version = "0.0.1"

3 changes: 3 additions & 0 deletions kclvm/cmd/src/test_data/instances/test_inst_11/model/main.k
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
schema K11:
msg: str

5 changes: 5 additions & 0 deletions kclvm/cmd/src/test_data/instances/test_inst_11/sub/main.k
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import model as m

k11_inst: m.K11 {
msg: "k11_in_sub"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
k11_inst:
msg: k11_in_main
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[package]
name = "test_inst_111"
edition = "0.0.1"
version = "0.0.1"

Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
kcl_cli_configs:
file:
- ../sub/main.k
- ./main.k
package_maps:
test_inst_11: ./src/test_data/instances/test_inst_11
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import test_inst_11.model as m

k11_inst: m.K11 {
msg= "k11_in_main"
}
19 changes: 1 addition & 18 deletions kclvm/cmd/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,6 @@ fn test_run_command() {
test_kcl_path_is_sym_link();
test_compile_two_kcl_mod();
test_main_pkg_not_found();
test_conflict_mod_file();
test_instances_with_yaml();
test_plugin_not_found();
}
Expand Down Expand Up @@ -472,6 +471,7 @@ fn test_instances_with_yaml() {
"test_inst_8",
"test_inst_9",
"test_inst_10",
"test_inst_11/test_inst_111",
];

for case in &test_cases {
Expand Down Expand Up @@ -527,23 +527,6 @@ fn test_main_pkg_not_found() {
}
}

fn test_conflict_mod_file() {
let test_case_path = PathBuf::from("./src/test_data/multimod");

let matches = app().arg_required_else_help(true).get_matches_from(&[
ROOT_CMD,
"run",
&test_case_path.join("kcl1").display().to_string(),
&test_case_path.join("kcl2").display().to_string(),
]);
let settings = must_build_settings(matches.subcommand_matches("run").unwrap());
let sess = Arc::new(ParseSession::default());
match exec_program(sess.clone(), &settings.try_into().unwrap()) {
Ok(_) => panic!("unreachable code."),
Err(msg) => assert!(msg.contains("conflict kcl.mod file paths")),
}
}

fn test_plugin_not_found() {
let test_case_path = PathBuf::from("./src/test_data/plugin/plugin_not_found");
let matches = app().arg_required_else_help(true).get_matches_from(&[
Expand Down
12 changes: 6 additions & 6 deletions kclvm/config/src/modfile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ pub struct KCLModFileExpectedSection {
pub global_version: Option<String>,
}

pub fn get_pkg_root_from_paths(file_paths: &[String]) -> Result<String, String> {
pub fn get_pkg_root_from_paths(file_paths: &[String], work_dir: String) -> Result<String, String> {
if file_paths.is_empty() {
return Err("No input KCL files or paths".to_string());
}
Expand All @@ -107,9 +107,9 @@ pub fn get_pkg_root_from_paths(file_paths: &[String]) -> Result<String, String>
}
if m.len() == 1 {
return Ok(last_root);
} else {
return Ok(work_dir);
Peefy marked this conversation as resolved.
Show resolved Hide resolved
}

Err(format!("conflict kcl.mod file paths: {:?}", m))
Peefy marked this conversation as resolved.
Show resolved Hide resolved
}

pub fn get_pkg_root(k_file_path: &str) -> Option<String> {
Expand Down Expand Up @@ -162,17 +162,17 @@ mod modfile_test {
#[test]
fn test_get_pkg_root_from_paths() {
assert_eq!(
get_pkg_root_from_paths(&[]),
get_pkg_root_from_paths(&[], "".to_string()),
Err("No input KCL files or paths".to_string())
);
assert_eq!(
get_pkg_root_from_paths(&["wrong_path".to_string()]),
get_pkg_root_from_paths(&["wrong_path".to_string()], "".to_string()),
Ok("".to_string())
);
let expected_root = std::path::Path::new(TEST_ROOT).canonicalize().unwrap();
let expected = expected_root.adjust_canonicalization();
assert_eq!(
get_pkg_root_from_paths(&[SETTINGS_FILE.to_string()]),
get_pkg_root_from_paths(&[SETTINGS_FILE.to_string()], "".to_string()),
Ok(expected.to_string())
);
}
Expand Down
2 changes: 1 addition & 1 deletion kclvm/driver/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ pub fn canonicalize_input_files(
}

// Get the root path of the project
let pkgroot = kclvm_config::modfile::get_pkg_root_from_paths(&kcl_paths)?;
let pkgroot = kclvm_config::modfile::get_pkg_root_from_paths(&kcl_paths, work_dir)?;

// The second traversal replaces ${KCL_MOD} with the project root path
kcl_paths = kcl_paths
Expand Down
5 changes: 3 additions & 2 deletions kclvm/makefile
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,9 @@ codecov:
codecov-lcov:
rustup component add llvm-tools-preview
cargo install cargo-llvm-cov
mkdir $(PWD)/.kclvm
cargo llvm-cov --lcov --output-path $(PWD)/.kclvm/lcov.info --workspace --ignore-filename-regex gpyrpc.rs -- --nocapture
rm -rf $(PWD)/.kclvm_cov
mkdir $(PWD)/.kclvm_cov
cargo llvm-cov --lcov --output-path $(PWD)/.kclvm_cov/lcov.info --workspace --ignore-filename-regex gpyrpc.rs -- --nocapture

# Test runtime libaries using python functions
test-runtime: install-kclvm-py install-pytest
Expand Down
76 changes: 36 additions & 40 deletions kclvm/parser/src/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ impl Entry {
/// // [`package_maps`] is a map to show the real path of the mod relative path [`kcl2`].
/// let mut opts = LoadProgramOptions::default();
/// opts.package_maps.insert("kcl2".to_string(), testpath.join("kcl2").to_str().unwrap().to_string());
///
/// opts.work_dir = kcl1_path.display().to_string();
/// // [`get_compile_entries_from_paths`] will return the map of package name to package root real path.
/// let entries = get_compile_entries_from_paths(
/// &[
Expand Down Expand Up @@ -345,50 +345,46 @@ pub fn get_compile_entries_from_paths(
result.push_entry(entry);
}

// The main 'kcl.mod' path can be found only once.
// Replace all the '${KCL_MOD}' with the real path of main 'kcl.mod'.
if result
let pkg_root = if result
.get_unique_normal_paths_by_name(kclvm_ast::MAIN_PKG)
.len()
== 1
{
// If the [`ModRelativePath`] with preffix '${KCL_MOD}'.
// Replace the '${KCL_MOD}' by the root path of package '__main__'.

// Calculate the root path of package '__main__'.
let pkg_root;
let main_entry = result
.get_nth_entry_by_name(0, kclvm_ast::MAIN_PKG)
.ok_or_else(|| format!("program entry not found in {:?}", file_paths))?;
pkg_root = main_entry.path().to_string();

// Replace the '${KCL_MOD}' of all the paths with package name '__main__'.
result.apply_to_all_entries(|entry| {
let path = ModRelativePath::from(entry.path().to_string());
if entry.name() == kclvm_ast::MAIN_PKG
&& path.is_relative_path().map_err(|err| err.to_string())?
{
entry.set_path(pkg_root.to_string());
entry.extend_k_files(get_main_files_from_pkg_path(
&path
.canonicalize_by_root_path(&pkg_root)
.map_err(|err| err.to_string())?,
&pkg_root,
&kclvm_ast::MAIN_PKG.to_string(),
opts,
)?);
}
return Ok(());
})?;
return Ok(result);
}
// 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 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()
}
};

// Replace the '${KCL_MOD}' of all the paths with package name '__main__'.
result.apply_to_all_entries(|entry| {
let path = ModRelativePath::from(entry.path().to_string());
if entry.name() == kclvm_ast::MAIN_PKG
&& path.is_relative_path().map_err(|err| err.to_string())?
{
entry.set_path(pkg_root.to_string());
entry.extend_k_files(get_main_files_from_pkg_path(
&path
.canonicalize_by_root_path(&pkg_root)
.map_err(|err| err.to_string())?,
&pkg_root,
&kclvm_ast::MAIN_PKG.to_string(),
opts,
)?);
}
return Ok(());
})?;

// If there are more than one main 'kcl.mod' files, return error.
// the root path of package '__main__' can only one.
Err(format!(
"conflict kcl.mod file paths: {:?}",
result.get_unique_normal_paths_by_name(kclvm_ast::MAIN_PKG)
))
return Ok(result);
}

/// Get files in the main package with the package root.
Expand Down
33 changes: 29 additions & 4 deletions kclvm/parser/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use compiler_base_macros::bug;
use compiler_base_session::Session;
use compiler_base_span::span::new_byte_pos;
use kclvm_ast::ast;
use kclvm_config::modfile::get_pkg_root;
use kclvm_config::modfile::{get_vendor_home, KCL_FILE_EXTENSION, KCL_FILE_SUFFIX, KCL_MOD_FILE};
use kclvm_error::diagnostic::Range;
use kclvm_error::{ErrorKind, Message, Style};
Expand All @@ -27,6 +28,7 @@ use kclvm_utils::pkgpath::rm_external_pkg_name;
use lexer::parse_token_streams;
use parser::Parser;
use std::collections::HashMap;
use std::env;
use std::path::PathBuf;
use std::sync::Arc;

Expand Down Expand Up @@ -314,9 +316,32 @@ impl Loader {
let compile_entries = get_compile_entries_from_paths(&self.paths, &self.opts)?;
let mut pkgs = HashMap::new();

let main_program_root = compile_entries
.contains_pkg_name(&kclvm_ast::MAIN_PKG.to_string())
.ok_or(format!("main package not found in {:?}", &self.paths))?;
// Calculate the root path.
let workdir = if compile_entries
.get_unique_paths_by_name(kclvm_ast::MAIN_PKG)
.len()
== 1
{
// If only one 'kcl.mod' found, use it as the root path.
compile_entries
.contains_pkg_name(&kclvm_ast::MAIN_PKG.to_string())
.ok_or(format!("main package not found in {:?}", &self.paths))?
.path()
.to_string()
} else {
// If more than one 'kcl.mod' or no 'kcl.mod' found,
// It will find 'kcl.mod' start from the 'workdir',
// If not found, the 'workdir' will be considered as the root path.
let opt_work_dir = self.opts.work_dir.to_string();
get_pkg_root(&opt_work_dir)
.unwrap_or(
env::current_dir()
.map_err(|err| err.to_string())?
.display()
.to_string(),
)
.to_string()
};

debug_assert_eq!(compile_entries.len(), self.paths.len());

Expand Down Expand Up @@ -349,7 +374,7 @@ impl Loader {
// Insert the complete ast to replace the empty list.
pkgs.insert(kclvm_ast::MAIN_PKG.to_string(), pkg_files);
Ok(ast::Program {
root: main_program_root.path().to_string(),
root: workdir,
main: kclvm_ast::MAIN_PKG.to_string(),
pkgs,
})
Expand Down
1 change: 1 addition & 0 deletions kclvm/parser/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,7 @@ fn test_get_compile_entries_from_paths() {
"kcl2".to_string(),
testpath.join("kcl2").to_str().unwrap().to_string(),
);
opts.work_dir = kcl1_path.display().to_string();

// [`get_compile_entries_from_paths`] will return the map of package name to package root real path.
let entries = get_compile_entries_from_paths(
Expand Down
24 changes: 21 additions & 3 deletions kclvm/sema/src/resolver/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ use crate::ty::{Type, TypeKind};
use kclvm_ast::ast;
use kclvm_ast::pos::ContainsPos;
use kclvm_error::*;
use kclvm_parser::LoadProgramOptions;
use kclvm_parser::ParseSession;
use kclvm_parser::{load_program, parse_program};
use std::path::Path;
use std::path::PathBuf;
use std::rc::Rc;
use std::sync::Arc;

Expand Down Expand Up @@ -255,8 +257,18 @@ fn test_resolve_program_module_optional_select_fail() {
#[test]
fn test_lint() {
let sess = Arc::new(ParseSession::default());
let mut program =
load_program(sess.clone(), &["./src/resolver/test_data/lint.k"], None).unwrap();
let mut opts = LoadProgramOptions::default();
opts.work_dir = PathBuf::from("./src/resolver/test_data/")
.canonicalize()
.unwrap()
.display()
.to_string();
let mut program = load_program(
sess.clone(),
&["./src/resolver/test_data/lint.k"],
Some(opts),
)
.unwrap();
pre_process_program(&mut program);
let mut resolver = Resolver::new(&program, Options::default());
resolver.resolve_import();
Expand Down Expand Up @@ -391,10 +403,16 @@ See also: kusion_models/core/v1/metadata.k."
#[test]
fn test_pkg_scope() {
let sess = Arc::new(ParseSession::default());
let mut opt = LoadProgramOptions::default();
opt.work_dir = PathBuf::from("./src/resolver/test_data/")
.canonicalize()
.unwrap()
.display()
.to_string();
let mut program = load_program(
sess.clone(),
&["./src/resolver/test_data/pkg_scope.k"],
None,
Some(opt),
)
.unwrap();
let scope = resolve_program(&mut program);
Expand Down
2 changes: 1 addition & 1 deletion kclvm/tools/src/LSP/src/request.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use anyhow::Ok;
use crossbeam_channel::Sender;

use lsp_types::TextEdit;
use ra_ap_vfs::VfsPath;
use std::time::Instant;
Expand Down
Loading
Loading