chore: add api_nu_plugin_kcl
This commit is contained in:
parent
4acf51fbdc
commit
7aafe5523f
2
api_nu_plugin_kcl/.gitignore
vendored
Normal file
2
api_nu_plugin_kcl/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
/target
|
||||||
|
.DS_Store
|
6457
api_nu_plugin_kcl/Cargo.lock
generated
Normal file
6457
api_nu_plugin_kcl/Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
27
api_nu_plugin_kcl/Cargo.toml
Normal file
27
api_nu_plugin_kcl/Cargo.toml
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
[package]
|
||||||
|
|
||||||
|
name = "nu_plugin_kcl"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Jesús Pérez <jpl@jesusperez.com>"]
|
||||||
|
edition = "2024"
|
||||||
|
description = "a nushell plugin called kcl"
|
||||||
|
repository = "https://github.com/jesusperez/nu_plugin_kcl"
|
||||||
|
license = "MIT"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
# for local development, you can use a path dependency
|
||||||
|
nu-plugin = { path = "../nushell/crates/nu-plugin" }
|
||||||
|
nu-protocol = { path = "../nushell/crates/nu-protocol", features = ["plugin"] }
|
||||||
|
#nu-plugin = "0.104.0"
|
||||||
|
#nu-protocol = { version = "0.104.0", features = ["plugin"] }
|
||||||
|
kcl-lang = { git = "https://github.com/kcl-lang/lib" }
|
||||||
|
anyhow = "1.0"
|
||||||
|
toml = "0.8"
|
||||||
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
|
tempfile = "3"
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
nu-plugin-test-support = { path = "../nushell/crates/nu-plugin-test-support" }
|
||||||
|
#nu-plugin-test-support = { version = "0.104.0" }
|
21
api_nu_plugin_kcl/LICENSE
Normal file
21
api_nu_plugin_kcl/LICENSE
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2019 - 2022 The Nushell Project Developers
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
23
api_nu_plugin_kcl/README.md
Normal file
23
api_nu_plugin_kcl/README.md
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# nu_plugin_kcl
|
||||||
|
|
||||||
|
This is a [Nushell](https://nushell.sh/) plugin called "kcl".
|
||||||
|
|
||||||
|
## Installing
|
||||||
|
|
||||||
|
```nushell
|
||||||
|
> cargo install --path .
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
FIXME: This reflects the demo functionality generated with the template. Update this documentation
|
||||||
|
once you have implemented the actual plugin functionality.
|
||||||
|
|
||||||
|
```nushell
|
||||||
|
> plugin add ~/.cargo/bin/nu_plugin_kcl
|
||||||
|
> plugin use kcl
|
||||||
|
> kcl-exec Ellie
|
||||||
|
Hello, Ellie. How are you today?
|
||||||
|
> kcl-exec --shout Ellie
|
||||||
|
HELLO, ELLIE. HOW ARE YOU TODAY?
|
||||||
|
```
|
433
api_nu_plugin_kcl/src/main.rs
Normal file
433
api_nu_plugin_kcl/src/main.rs
Normal file
@ -0,0 +1,433 @@
|
|||||||
|
use kcl_lang::{API, ExecProgramArgs, ExternalPkg};
|
||||||
|
use nu_plugin::{EngineInterface, EvaluatedCall, SimplePluginCommand};
|
||||||
|
use nu_plugin::{MsgPackSerializer, Plugin, PluginCommand, serve_plugin};
|
||||||
|
use nu_protocol::IntoPipelineData;
|
||||||
|
use nu_protocol::{
|
||||||
|
Category, Example, LabeledError, PipelineData, Signature, SyntaxShape, Type, Value,
|
||||||
|
};
|
||||||
|
use serde::Deserialize;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
|
/// Nushell plugin for executing KCL files and inline KCL code.
|
||||||
|
///
|
||||||
|
/// This plugin integrates [KCL](https://kcl-lang.io/) (Kusion Configuration Language) with [Nushell](https://www.nushell.sh/), allowing you to execute KCL files or inline KCL code directly from your Nushell pipeline.
|
||||||
|
///
|
||||||
|
/// # Provided Commands
|
||||||
|
///
|
||||||
|
/// - `kcl-exec`: Execute one or more KCL files and return the result as YAML. Accepts an array of file paths and an optional `--work_dir` flag to specify the working directory.
|
||||||
|
/// - `kcl-run`: Execute inline KCL code from the pipeline and return the result as YAML.
|
||||||
|
///
|
||||||
|
/// # Usage
|
||||||
|
///
|
||||||
|
/// ## kcl-exec
|
||||||
|
///
|
||||||
|
/// Run multiple KCL files in the current directory:
|
||||||
|
///
|
||||||
|
/// ```shell
|
||||||
|
/// kcl-exec [settings.k defs/aws_defaults.k]
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// Run multiple KCL files from any directory, specifying the project root:
|
||||||
|
///
|
||||||
|
/// ```shell
|
||||||
|
/// kcl-exec [settings.k defs/aws_defaults.k] --work_dir /path/to/project
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// Run a single KCL file:
|
||||||
|
///
|
||||||
|
/// ```shell
|
||||||
|
/// kcl-exec [settings.k] --work_dir /path/to/project
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// ## kcl-run
|
||||||
|
///
|
||||||
|
/// Run inline KCL code:
|
||||||
|
///
|
||||||
|
/// ```shell
|
||||||
|
/// 'a = 1' | kcl-run
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// Run a KCL file from the pipeline:
|
||||||
|
///
|
||||||
|
/// ```shell
|
||||||
|
/// open settings.k | kcl-run
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// # Limitations
|
||||||
|
///
|
||||||
|
/// - The `kcl-exec` command requires the specified files to exist and be accessible.
|
||||||
|
/// - The `kcl-run` command expects a string of KCL code from the pipeline input.
|
||||||
|
/// - Example-based tests that require actual files or pipeline input may not run in all test environments.
|
||||||
|
///
|
||||||
|
/// # Resources
|
||||||
|
///
|
||||||
|
/// - [KCL Language Documentation](https://kcl-lang.io/docs/)
|
||||||
|
/// - [Nushell Plugin Development](https://www.nushell.sh/book/plugins.html)
|
||||||
|
pub struct KclPlugin;
|
||||||
|
|
||||||
|
impl Plugin for KclPlugin {
|
||||||
|
fn version(&self) -> String {
|
||||||
|
// This automatically uses the version of your package from Cargo.toml as the plugin version
|
||||||
|
// sent to Nushell
|
||||||
|
env!("CARGO_PKG_VERSION").into()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn commands(&self) -> Vec<Box<dyn PluginCommand<Plugin = Self>>> {
|
||||||
|
vec![
|
||||||
|
// Commands should be added here
|
||||||
|
Box::new(KclExec),
|
||||||
|
Box::new(KclValidate),
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Command to execute KCL files from a file path.
|
||||||
|
///
|
||||||
|
/// This command takes a path to a KCL file and executes it, returning the result as YAML.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```shell
|
||||||
|
/// kcl-exec ./src/myfile.k
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
///
|
||||||
|
/// - `file`: Path to the KCL file to execute (required).
|
||||||
|
/// - `work_dir`: Optional working directory for KCL execution.
|
||||||
|
///
|
||||||
|
/// # Limitations
|
||||||
|
///
|
||||||
|
/// The file must exist and be readable by the plugin process.
|
||||||
|
/// - If `--work_dir` is not provided, the plugin will automatically search for `kcl.mod` upwards from the first file in the files array and use its directory as the working directory.
|
||||||
|
pub struct KclExec;
|
||||||
|
|
||||||
|
impl SimplePluginCommand for KclExec {
|
||||||
|
type Plugin = KclPlugin;
|
||||||
|
|
||||||
|
fn name(&self) -> &str {
|
||||||
|
"kcl-exec"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn signature(&self) -> Signature {
|
||||||
|
Signature::build(PluginCommand::name(self))
|
||||||
|
.input_output_type(Type::Any, Type::String)
|
||||||
|
.required(
|
||||||
|
"files",
|
||||||
|
SyntaxShape::List(Box::new(SyntaxShape::Filepath)),
|
||||||
|
"KCL files to execute (array)",
|
||||||
|
)
|
||||||
|
.named(
|
||||||
|
"work_dir",
|
||||||
|
SyntaxShape::Directory,
|
||||||
|
"Work directory",
|
||||||
|
Some('w'),
|
||||||
|
)
|
||||||
|
.category(Category::Experimental)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn description(&self) -> &str {
|
||||||
|
"Exec KCL files and return result in YAML"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn examples(&self) -> Vec<Example> {
|
||||||
|
let examples: Vec<Example> = vec![Example {
|
||||||
|
example: "kcl-exec [settings.k defs/aws_defaults.k] --work_dir .",
|
||||||
|
description: "Execute multiple KCL files in the current directory",
|
||||||
|
result: None,
|
||||||
|
}];
|
||||||
|
examples
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run(
|
||||||
|
&self,
|
||||||
|
_plugin: &KclPlugin,
|
||||||
|
_engine: &EngineInterface,
|
||||||
|
call: &EvaluatedCall,
|
||||||
|
_input: &Value,
|
||||||
|
) -> Result<Value, LabeledError> {
|
||||||
|
let files: Vec<String> = call.req(0)?;
|
||||||
|
let work_dir: Option<String> = call.get_flag("work_dir")?;
|
||||||
|
match exec_kcl_file(&files, work_dir.as_deref()) {
|
||||||
|
Ok(yaml) => Ok(Value::string(yaml, call.head)),
|
||||||
|
Err(e) => Err(LabeledError::new("KCL code execution error").with_label(e, call.head)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Command to execute inline KCL code from the Nushell pipeline.
|
||||||
|
///
|
||||||
|
/// This command takes a string of KCL code from the pipeline and executes it, returning the result as YAML.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```shell
|
||||||
|
/// open myfile.k | kcl-run
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
///
|
||||||
|
/// - `filename`: Optional virtual filename for the KCL code (default: `main.k`).
|
||||||
|
///
|
||||||
|
/// # Limitations
|
||||||
|
///
|
||||||
|
/// The input must be a string containing valid KCL code.
|
||||||
|
struct KclValidate;
|
||||||
|
|
||||||
|
impl PluginCommand for KclValidate {
|
||||||
|
type Plugin = KclPlugin;
|
||||||
|
|
||||||
|
fn name(&self) -> &str {
|
||||||
|
"kcl-run"
|
||||||
|
}
|
||||||
|
fn description(&self) -> &str {
|
||||||
|
"Exec KCL inline code from pipeline"
|
||||||
|
}
|
||||||
|
fn signature(&self) -> Signature {
|
||||||
|
Signature::build(PluginCommand::name(self))
|
||||||
|
.input_output_type(Type::String, Type::String)
|
||||||
|
.optional(
|
||||||
|
"filename",
|
||||||
|
SyntaxShape::String,
|
||||||
|
"Nombre virtual del archivo",
|
||||||
|
)
|
||||||
|
.category(Category::Experimental)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run(
|
||||||
|
&self,
|
||||||
|
_plugin: &KclPlugin,
|
||||||
|
_engine: &EngineInterface,
|
||||||
|
call: &EvaluatedCall,
|
||||||
|
input: PipelineData,
|
||||||
|
) -> Result<PipelineData, LabeledError> {
|
||||||
|
let filename = call
|
||||||
|
.opt::<String>(0)?
|
||||||
|
.unwrap_or_else(|| "main.k".to_string());
|
||||||
|
let value = input.into_value(call.head);
|
||||||
|
let code = match value {
|
||||||
|
Ok(Value::String { val, .. }) => val,
|
||||||
|
Ok(_) => {
|
||||||
|
return Err(LabeledError::new("KCL code expected as string")
|
||||||
|
.with_label("Use a string as KCL code", call.head));
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
return Err(LabeledError::new("Failed to extract input value")
|
||||||
|
.with_label(e.to_string(), call.head));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
match exec_kcl_inline(&code, &filename) {
|
||||||
|
Ok(yaml) => Ok(Value::string(yaml, call.head).into_pipeline_data()),
|
||||||
|
Err(e) => Err(LabeledError::new("KCL code execution error").with_label(e, call.head)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn examples(&self) -> Vec<Example> {
|
||||||
|
vec![Example {
|
||||||
|
example: "'a = 1' | kcl-run",
|
||||||
|
description: "Run inline KCL code from the pipeline",
|
||||||
|
result: None,
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
serve_plugin(&KclPlugin, MsgPackSerializer);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn exec_kcl_file(file_paths: &[String], work_dir: Option<&str>) -> Result<String, String> {
|
||||||
|
let work_dir = match work_dir {
|
||||||
|
Some(dir) => dir.to_string(),
|
||||||
|
None => {
|
||||||
|
// Try to find kcl.mod upwards from the first file
|
||||||
|
if let Some(first_file) = file_paths.get(0) {
|
||||||
|
match find_kcl_mod_dir(first_file) {
|
||||||
|
Some(dir) => dir,
|
||||||
|
None => return Err("No kcl.mod found in parent directories of the first file, and --work_dir not provided".to_string()),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return Err("No files provided to execute".to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let external_pkgs = resolve_dependencies_toml(&work_dir)?;
|
||||||
|
// Debug: mostrar dependencias resueltas
|
||||||
|
for pkg in &external_pkgs {
|
||||||
|
println!("Dependencies: {} -> {}", pkg.pkg_name, pkg.pkg_path);
|
||||||
|
println!("Existe: {}", Path::new(&pkg.pkg_path).exists());
|
||||||
|
}
|
||||||
|
let api = API::default();
|
||||||
|
let args = ExecProgramArgs {
|
||||||
|
k_filename_list: file_paths.to_vec(),
|
||||||
|
work_dir,
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
match api.exec_program(&args) {
|
||||||
|
Ok(result) => Ok(result.yaml_result),
|
||||||
|
Err(e) => Err(e.to_string()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Search upwards from the given file for a kcl.mod file and return its directory as a String.
|
||||||
|
fn find_kcl_mod_dir<P: AsRef<Path>>(start_file: P) -> Option<String> {
|
||||||
|
let mut dir = PathBuf::from(start_file.as_ref()).parent()?.to_path_buf();
|
||||||
|
loop {
|
||||||
|
let kcl_mod = dir.join("kcl.mod");
|
||||||
|
if kcl_mod.exists() {
|
||||||
|
return Some(dir.to_string_lossy().to_string());
|
||||||
|
}
|
||||||
|
if !dir.pop() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
fn exec_kcl_inline(code: &str, filename: &str) -> Result<String, String> {
|
||||||
|
let api = API::default();
|
||||||
|
let args = ExecProgramArgs {
|
||||||
|
k_filename_list: vec![filename.to_string()],
|
||||||
|
k_code_list: vec![code.to_string()],
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
match api.exec_program(&args) {
|
||||||
|
Ok(result) => Ok(result.yaml_result),
|
||||||
|
Err(e) => Err(e.to_string()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
struct KclMod {
|
||||||
|
package: Package,
|
||||||
|
dependencies: Option<HashMap<String, Dependency>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
struct Package {
|
||||||
|
name: String,
|
||||||
|
edition: String,
|
||||||
|
version: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
struct Dependency {
|
||||||
|
path: Option<String>,
|
||||||
|
version: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn resolve_dependencies_toml(work_dir: &str) -> Result<Vec<ExternalPkg>, String> {
|
||||||
|
let kcl_mod_path = Path::new(work_dir).join("kcl.mod");
|
||||||
|
|
||||||
|
if !kcl_mod_path.exists() {
|
||||||
|
return Ok(vec![]);
|
||||||
|
}
|
||||||
|
|
||||||
|
let content = std::fs::read_to_string(&kcl_mod_path)
|
||||||
|
.map_err(|e| format!("Error reading kcl.mod: {}", e))?;
|
||||||
|
|
||||||
|
let kcl_mod: KclMod =
|
||||||
|
toml::from_str(&content).map_err(|e| format!("Error parsing kcl.mod: {}", e))?;
|
||||||
|
|
||||||
|
let mut external_pkgs = Vec::new();
|
||||||
|
|
||||||
|
if let Some(dependencies) = kcl_mod.dependencies {
|
||||||
|
for (pkg_name, dep) in dependencies {
|
||||||
|
if let Some(relative_path) = dep.path {
|
||||||
|
let absolute_path = Path::new(work_dir)
|
||||||
|
.join(relative_path)
|
||||||
|
.canonicalize()
|
||||||
|
.map_err(|e| format!("Error resolving path for {}: {}", pkg_name, e))?
|
||||||
|
.to_string_lossy()
|
||||||
|
.to_string();
|
||||||
|
|
||||||
|
external_pkgs.push(ExternalPkg {
|
||||||
|
pkg_name,
|
||||||
|
pkg_path: absolute_path,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dbg!(&external_pkgs);
|
||||||
|
|
||||||
|
Ok(external_pkgs)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Test all examples for the `kcl-exec` command.
|
||||||
|
///
|
||||||
|
/// This test runs the examples provided in the `examples` method of `KclExec`.
|
||||||
|
/// Note: Examples that require actual files may not pass unless the files exist.
|
||||||
|
#[test]
|
||||||
|
fn test_examples() -> Result<(), nu_protocol::ShellError> {
|
||||||
|
use nu_plugin_test_support::PluginTest;
|
||||||
|
|
||||||
|
PluginTest::new("kcl", KclPlugin.into())?.test_command_examples(&KclExec)
|
||||||
|
}
|
||||||
|
/// Test all examples for the `kcl-run` command.
|
||||||
|
///
|
||||||
|
/// This test runs the examples provided in the `examples` method of `KclValidate`.
|
||||||
|
/// Note: Examples that require pipeline input may not be fully testable in all environments.
|
||||||
|
#[test]
|
||||||
|
fn test_kcl_validate_examples() -> Result<(), nu_protocol::ShellError> {
|
||||||
|
use nu_plugin_test_support::PluginTest;
|
||||||
|
|
||||||
|
PluginTest::new("kcl", KclPlugin.into())?.test_command_examples(&KclValidate)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Entry point for the KCL Nushell plugin.
|
||||||
|
///
|
||||||
|
/// This function starts the plugin and serves it to Nushell using message pack serialization.
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod unit_tests {
|
||||||
|
use super::*;
|
||||||
|
use std::fs;
|
||||||
|
use std::io::Write;
|
||||||
|
extern crate tempfile;
|
||||||
|
use tempfile::tempdir;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_exec_kcl_file_nonexistent() {
|
||||||
|
let result = exec_kcl_file(&vec!["/tmp/does_not_exist.k".to_string()], None);
|
||||||
|
assert!(result.is_err());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_exec_kcl_inline_invalid_code() {
|
||||||
|
let result = exec_kcl_inline("not valid kcl", "main.k");
|
||||||
|
assert!(result.is_err());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_resolve_dependencies_toml_success() {
|
||||||
|
let dir = tempdir().unwrap();
|
||||||
|
let dep_dir = dir.path().join("dep");
|
||||||
|
fs::create_dir_all(&dep_dir).unwrap();
|
||||||
|
let kcl_mod_content = r#"
|
||||||
|
[package]
|
||||||
|
name = "testpkg"
|
||||||
|
edition = "v0.9.0"
|
||||||
|
version = "0.1.0"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
foo = { path = "dep" , version = "0.1.0" }
|
||||||
|
"#;
|
||||||
|
let kcl_mod_path = dir.path().join("kcl.mod");
|
||||||
|
let mut file = fs::File::create(&kcl_mod_path).unwrap();
|
||||||
|
file.write_all(kcl_mod_content.as_bytes()).unwrap();
|
||||||
|
let pkgs = resolve_dependencies_toml(dir.path().to_str().unwrap()).unwrap();
|
||||||
|
assert_eq!(pkgs.len(), 1);
|
||||||
|
assert_eq!(pkgs[0].pkg_name, "foo");
|
||||||
|
assert!(pkgs[0].pkg_path.ends_with("dep"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_resolve_dependencies_toml_no_kcl_mod() {
|
||||||
|
let dir = tempdir().unwrap();
|
||||||
|
let pkgs = resolve_dependencies_toml(dir.path().to_str().unwrap()).unwrap();
|
||||||
|
assert!(pkgs.is_empty());
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user