Format a whole directory easily (#5816)

* recast a whole directory

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* move

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* fixes

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* fixes

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
This commit is contained in:
Jess Frazelle
2025-03-17 15:55:25 -07:00
committed by GitHub
parent 4dd669bd46
commit ff6186f4f0
22 changed files with 610 additions and 458 deletions

View File

@ -96,6 +96,8 @@ pub use modules::ModuleId;
pub use parsing::ast::{modify::modify_ast_for_sketch, types::FormatOptions};
pub use settings::types::{project::ProjectConfiguration, Configuration, UnitLength};
pub use source_range::SourceRange;
#[cfg(not(target_arch = "wasm32"))]
pub use unparser::recast_dir;
// Rather than make executor public and make lots of it pub(crate), just re-export into a new module.
// Ideally we wouldn't export these things at all, they should only be used for testing.

File diff suppressed because it is too large Load Diff

View File

@ -34,10 +34,10 @@ fn parse(dir_name: &str, dir_path: &Path) {
}
#[kcl_directory_test_macro::test_all_dirs("../public/kcl-samples")]
fn unparse(dir_name: &str, dir_path: &Path) {
// kcl-samples don't always use correct formatting. We don't ignore the
// test because we want to allow the just command to work. It's actually
// fine when no test runs.
async fn unparse(dir_name: &str, dir_path: &Path) {
// TODO: turn this on when we fix the comments recasting.
// let t = test(dir_name, dir_path.join("main.kcl").to_str().unwrap().to_owned());
// super::unparse_test(&t).await;
}
#[kcl_directory_test_macro::test_all_dirs("../public/kcl-samples")]

View File

@ -842,6 +842,103 @@ impl Type {
}
}
/// Collect all the kcl files in a directory, recursively.
#[cfg(not(target_arch = "wasm32"))]
#[async_recursion::async_recursion]
pub(crate) async fn walk_dir(dir: &std::path::PathBuf) -> Result<Vec<std::path::PathBuf>, anyhow::Error> {
// Make sure we actually have a directory.
if !dir.is_dir() {
anyhow::bail!("`{}` is not a directory", dir.display());
}
let mut entries = tokio::fs::read_dir(dir).await?;
let mut files = Vec::new();
while let Some(entry) = entries.next_entry().await? {
let path = entry.path();
if path.is_dir() {
files.extend(walk_dir(&path).await?);
} else if path.extension().is_some_and(|ext| ext == "kcl") {
files.push(path);
}
}
Ok(files)
}
/// Recast all the kcl files in a directory, recursively.
#[cfg(not(target_arch = "wasm32"))]
pub async fn recast_dir(dir: &std::path::Path, options: &crate::FormatOptions) -> Result<(), crate::KclError> {
let files = walk_dir(&dir.to_path_buf()).await.map_err(|err| {
crate::KclError::Internal(crate::errors::KclErrorDetails {
message: format!("Failed to walk directory `{}`: {:?}", dir.display(), err),
source_ranges: vec![crate::SourceRange::default()],
})
})?;
let futures = files
.into_iter()
.map(|file| {
let options = options.clone();
tokio::spawn(async move {
let contents = tokio::fs::read_to_string(&file).await.map_err(|err| {
crate::KclError::Internal(crate::errors::KclErrorDetails {
message: format!("Failed to read file `{}`: {:?}", file.display(), err),
source_ranges: vec![crate::SourceRange::default()],
})
})?;
let (program, ces) = crate::Program::parse(&contents)?;
for ce in &ces {
if ce.severity != crate::errors::Severity::Warning {
return Err(crate::KclError::Semantic(ce.clone().into()));
}
}
let Some(program) = program else {
return Err(crate::KclError::Internal(crate::errors::KclErrorDetails {
message: format!("Failed to parse file `{}`: {:?}", file.display(), ces),
source_ranges: vec![crate::SourceRange::default()],
}));
};
let recast = program.recast_with_options(&options);
tokio::fs::write(&file, recast).await.map_err(|err| {
crate::KclError::Internal(crate::errors::KclErrorDetails {
message: format!("Failed to write file `{}`: {:?}", file.display(), err),
source_ranges: vec![crate::SourceRange::default()],
})
})?;
Ok::<(), crate::KclError>(())
})
})
.collect::<Vec<_>>();
// Join all futures and await their completion
let results = futures::future::join_all(futures).await;
// Check if any of the futures failed.
let mut errors = Vec::new();
for result in results {
if let Err(err) = result.map_err(|err| {
crate::KclError::Internal(crate::errors::KclErrorDetails {
message: format!("Failed to recast file: {:?}", err),
source_ranges: vec![crate::SourceRange::default()],
})
})? {
errors.push(err);
}
}
if !errors.is_empty() {
return Err(crate::KclError::Internal(crate::errors::KclErrorDetails {
message: format!("Failed to recast files: {:?}", errors),
source_ranges: vec![crate::SourceRange::default()],
}));
}
Ok(())
}
#[cfg(test)]
mod tests {
use pretty_assertions::assert_eq;

View File

@ -80,8 +80,8 @@ description: Artifact commands assembly_mixed_units_cubes.kcl
{
"cmdId": "[uuid]",
"range": [
47,
66,
48,
67,
3
],
"command": {
@ -109,8 +109,8 @@ description: Artifact commands assembly_mixed_units_cubes.kcl
{
"cmdId": "[uuid]",
"range": [
76,
113,
77,
114,
3
],
"command": {
@ -129,8 +129,8 @@ description: Artifact commands assembly_mixed_units_cubes.kcl
{
"cmdId": "[uuid]",
"range": [
76,
113,
77,
114,
3
],
"command": {
@ -140,8 +140,8 @@ description: Artifact commands assembly_mixed_units_cubes.kcl
{
"cmdId": "[uuid]",
"range": [
76,
113,
77,
114,
3
],
"command": {
@ -157,8 +157,8 @@ description: Artifact commands assembly_mixed_units_cubes.kcl
{
"cmdId": "[uuid]",
"range": [
76,
113,
77,
114,
3
],
"command": {
@ -168,8 +168,8 @@ description: Artifact commands assembly_mixed_units_cubes.kcl
{
"cmdId": "[uuid]",
"range": [
119,
136,
120,
137,
3
],
"command": {
@ -189,8 +189,8 @@ description: Artifact commands assembly_mixed_units_cubes.kcl
{
"cmdId": "[uuid]",
"range": [
142,
160,
143,
161,
3
],
"command": {
@ -210,8 +210,8 @@ description: Artifact commands assembly_mixed_units_cubes.kcl
{
"cmdId": "[uuid]",
"range": [
166,
184,
167,
185,
3
],
"command": {
@ -231,8 +231,8 @@ description: Artifact commands assembly_mixed_units_cubes.kcl
{
"cmdId": "[uuid]",
"range": [
190,
246,
191,
247,
3
],
"command": {
@ -252,8 +252,8 @@ description: Artifact commands assembly_mixed_units_cubes.kcl
{
"cmdId": "[uuid]",
"range": [
252,
259,
253,
260,
3
],
"command": {
@ -264,8 +264,8 @@ description: Artifact commands assembly_mixed_units_cubes.kcl
{
"cmdId": "[uuid]",
"range": [
265,
287,
266,
288,
3
],
"command": {
@ -284,8 +284,8 @@ description: Artifact commands assembly_mixed_units_cubes.kcl
{
"cmdId": "[uuid]",
"range": [
265,
287,
266,
288,
3
],
"command": {
@ -298,8 +298,8 @@ description: Artifact commands assembly_mixed_units_cubes.kcl
{
"cmdId": "[uuid]",
"range": [
265,
287,
266,
288,
3
],
"command": {
@ -309,8 +309,8 @@ description: Artifact commands assembly_mixed_units_cubes.kcl
{
"cmdId": "[uuid]",
"range": [
265,
287,
266,
288,
3
],
"command": {
@ -321,8 +321,8 @@ description: Artifact commands assembly_mixed_units_cubes.kcl
{
"cmdId": "[uuid]",
"range": [
265,
287,
266,
288,
3
],
"command": {
@ -334,8 +334,8 @@ description: Artifact commands assembly_mixed_units_cubes.kcl
{
"cmdId": "[uuid]",
"range": [
265,
287,
266,
288,
3
],
"command": {
@ -348,8 +348,8 @@ description: Artifact commands assembly_mixed_units_cubes.kcl
{
"cmdId": "[uuid]",
"range": [
265,
287,
266,
288,
3
],
"command": {
@ -362,8 +362,8 @@ description: Artifact commands assembly_mixed_units_cubes.kcl
{
"cmdId": "[uuid]",
"range": [
265,
287,
266,
288,
3
],
"command": {
@ -376,8 +376,8 @@ description: Artifact commands assembly_mixed_units_cubes.kcl
{
"cmdId": "[uuid]",
"range": [
265,
287,
266,
288,
3
],
"command": {
@ -390,8 +390,8 @@ description: Artifact commands assembly_mixed_units_cubes.kcl
{
"cmdId": "[uuid]",
"range": [
265,
287,
266,
288,
3
],
"command": {
@ -404,8 +404,8 @@ description: Artifact commands assembly_mixed_units_cubes.kcl
{
"cmdId": "[uuid]",
"range": [
265,
287,
266,
288,
3
],
"command": {
@ -418,8 +418,8 @@ description: Artifact commands assembly_mixed_units_cubes.kcl
{
"cmdId": "[uuid]",
"range": [
265,
287,
266,
288,
3
],
"command": {
@ -432,8 +432,8 @@ description: Artifact commands assembly_mixed_units_cubes.kcl
{
"cmdId": "[uuid]",
"range": [
265,
287,
266,
288,
3
],
"command": {
@ -458,8 +458,8 @@ description: Artifact commands assembly_mixed_units_cubes.kcl
{
"cmdId": "[uuid]",
"range": [
47,
66,
48,
67,
4
],
"command": {
@ -487,8 +487,8 @@ description: Artifact commands assembly_mixed_units_cubes.kcl
{
"cmdId": "[uuid]",
"range": [
76,
111,
77,
112,
4
],
"command": {
@ -507,8 +507,8 @@ description: Artifact commands assembly_mixed_units_cubes.kcl
{
"cmdId": "[uuid]",
"range": [
76,
111,
77,
112,
4
],
"command": {
@ -518,8 +518,8 @@ description: Artifact commands assembly_mixed_units_cubes.kcl
{
"cmdId": "[uuid]",
"range": [
76,
111,
77,
112,
4
],
"command": {
@ -535,8 +535,8 @@ description: Artifact commands assembly_mixed_units_cubes.kcl
{
"cmdId": "[uuid]",
"range": [
76,
111,
77,
112,
4
],
"command": {
@ -546,8 +546,8 @@ description: Artifact commands assembly_mixed_units_cubes.kcl
{
"cmdId": "[uuid]",
"range": [
117,
134,
118,
135,
4
],
"command": {
@ -567,8 +567,8 @@ description: Artifact commands assembly_mixed_units_cubes.kcl
{
"cmdId": "[uuid]",
"range": [
140,
158,
141,
159,
4
],
"command": {
@ -588,8 +588,8 @@ description: Artifact commands assembly_mixed_units_cubes.kcl
{
"cmdId": "[uuid]",
"range": [
164,
182,
165,
183,
4
],
"command": {
@ -609,8 +609,8 @@ description: Artifact commands assembly_mixed_units_cubes.kcl
{
"cmdId": "[uuid]",
"range": [
188,
244,
189,
245,
4
],
"command": {
@ -630,8 +630,8 @@ description: Artifact commands assembly_mixed_units_cubes.kcl
{
"cmdId": "[uuid]",
"range": [
250,
257,
251,
258,
4
],
"command": {
@ -642,8 +642,8 @@ description: Artifact commands assembly_mixed_units_cubes.kcl
{
"cmdId": "[uuid]",
"range": [
263,
285,
264,
286,
4
],
"command": {
@ -662,8 +662,8 @@ description: Artifact commands assembly_mixed_units_cubes.kcl
{
"cmdId": "[uuid]",
"range": [
263,
285,
264,
286,
4
],
"command": {
@ -676,8 +676,8 @@ description: Artifact commands assembly_mixed_units_cubes.kcl
{
"cmdId": "[uuid]",
"range": [
263,
285,
264,
286,
4
],
"command": {
@ -687,8 +687,8 @@ description: Artifact commands assembly_mixed_units_cubes.kcl
{
"cmdId": "[uuid]",
"range": [
263,
285,
264,
286,
4
],
"command": {
@ -699,8 +699,8 @@ description: Artifact commands assembly_mixed_units_cubes.kcl
{
"cmdId": "[uuid]",
"range": [
263,
285,
264,
286,
4
],
"command": {
@ -712,8 +712,8 @@ description: Artifact commands assembly_mixed_units_cubes.kcl
{
"cmdId": "[uuid]",
"range": [
263,
285,
264,
286,
4
],
"command": {
@ -726,8 +726,8 @@ description: Artifact commands assembly_mixed_units_cubes.kcl
{
"cmdId": "[uuid]",
"range": [
263,
285,
264,
286,
4
],
"command": {
@ -740,8 +740,8 @@ description: Artifact commands assembly_mixed_units_cubes.kcl
{
"cmdId": "[uuid]",
"range": [
263,
285,
264,
286,
4
],
"command": {
@ -754,8 +754,8 @@ description: Artifact commands assembly_mixed_units_cubes.kcl
{
"cmdId": "[uuid]",
"range": [
263,
285,
264,
286,
4
],
"command": {
@ -768,8 +768,8 @@ description: Artifact commands assembly_mixed_units_cubes.kcl
{
"cmdId": "[uuid]",
"range": [
263,
285,
264,
286,
4
],
"command": {
@ -782,8 +782,8 @@ description: Artifact commands assembly_mixed_units_cubes.kcl
{
"cmdId": "[uuid]",
"range": [
263,
285,
264,
286,
4
],
"command": {
@ -796,8 +796,8 @@ description: Artifact commands assembly_mixed_units_cubes.kcl
{
"cmdId": "[uuid]",
"range": [
263,
285,
264,
286,
4
],
"command": {
@ -810,8 +810,8 @@ description: Artifact commands assembly_mixed_units_cubes.kcl
{
"cmdId": "[uuid]",
"range": [
263,
285,
264,
286,
4
],
"command": {

View File

@ -1,25 +1,25 @@
```mermaid
flowchart LR
subgraph path2 [Path]
2["Path<br>[76, 113, 3]"]
3["Segment<br>[119, 136, 3]"]
4["Segment<br>[142, 160, 3]"]
5["Segment<br>[166, 184, 3]"]
6["Segment<br>[190, 246, 3]"]
7["Segment<br>[252, 259, 3]"]
2["Path<br>[77, 114, 3]"]
3["Segment<br>[120, 137, 3]"]
4["Segment<br>[143, 161, 3]"]
5["Segment<br>[167, 185, 3]"]
6["Segment<br>[191, 247, 3]"]
7["Segment<br>[253, 260, 3]"]
8[Solid2d]
end
subgraph path25 [Path]
25["Path<br>[76, 111, 4]"]
26["Segment<br>[117, 134, 4]"]
27["Segment<br>[140, 158, 4]"]
28["Segment<br>[164, 182, 4]"]
29["Segment<br>[188, 244, 4]"]
30["Segment<br>[250, 257, 4]"]
25["Path<br>[77, 112, 4]"]
26["Segment<br>[118, 135, 4]"]
27["Segment<br>[141, 159, 4]"]
28["Segment<br>[165, 183, 4]"]
29["Segment<br>[189, 245, 4]"]
30["Segment<br>[251, 258, 4]"]
31[Solid2d]
end
1["Plane<br>[47, 66, 3]"]
9["Sweep Extrusion<br>[265, 287, 3]"]
1["Plane<br>[48, 67, 3]"]
9["Sweep Extrusion<br>[266, 288, 3]"]
10[Wall]
11[Wall]
12[Wall]
@ -34,8 +34,8 @@ flowchart LR
21["SweepEdge Adjacent"]
22["SweepEdge Opposite"]
23["SweepEdge Adjacent"]
24["Plane<br>[47, 66, 4]"]
32["Sweep Extrusion<br>[263, 285, 4]"]
24["Plane<br>[48, 67, 4]"]
32["Sweep Extrusion<br>[264, 286, 4]"]
33[Wall]
34[Wall]
35[Wall]

View File

@ -1,5 +1,6 @@
@settings(defaultLengthUnit = in)
sketch001 = startSketchOn('XY')
cubeIn = startProfileAt([-10, -10], sketch001)
|> xLine(length = 5)

View File

@ -1,5 +1,6 @@
@settings(defaultLengthUnit = mm)
sketch001 = startSketchOn('XY')
cubeMm = startProfileAt([10, 10], sketch001)
|> xLine(length = 5)

View File

@ -11,16 +11,16 @@ description: Operations executed assembly_mixed_units_cubes.kcl
"value": "XY"
},
"sourceRange": [
61,
65,
62,
66,
3
]
}
},
"name": "startSketchOn",
"sourceRange": [
47,
66,
48,
67,
3
],
"type": "StdLibCall",
@ -43,16 +43,16 @@ description: Operations executed assembly_mixed_units_cubes.kcl
}
},
"sourceRange": [
285,
286,
287,
3
]
}
},
"name": "extrude",
"sourceRange": [
265,
287,
266,
288,
3
],
"type": "StdLibCall",
@ -64,8 +64,8 @@ description: Operations executed assembly_mixed_units_cubes.kcl
}
},
"sourceRange": [
273,
274,
275,
3
]
}
@ -78,16 +78,16 @@ description: Operations executed assembly_mixed_units_cubes.kcl
"value": "XY"
},
"sourceRange": [
61,
65,
62,
66,
4
]
}
},
"name": "startSketchOn",
"sourceRange": [
47,
66,
48,
67,
4
],
"type": "StdLibCall",
@ -110,16 +110,16 @@ description: Operations executed assembly_mixed_units_cubes.kcl
}
},
"sourceRange": [
283,
284,
285,
4
]
}
},
"name": "extrude",
"sourceRange": [
263,
285,
264,
286,
4
],
"type": "StdLibCall",
@ -131,8 +131,8 @@ description: Operations executed assembly_mixed_units_cubes.kcl
}
},
"sourceRange": [
271,
272,
273,
4
]
}

View File

@ -80,8 +80,8 @@ description: Artifact commands assembly_non_default_units.kcl
{
"cmdId": "[uuid]",
"range": [
172,
191,
173,
192,
3
],
"command": {
@ -109,8 +109,8 @@ description: Artifact commands assembly_non_default_units.kcl
{
"cmdId": "[uuid]",
"range": [
197,
232,
198,
233,
3
],
"command": {
@ -129,8 +129,8 @@ description: Artifact commands assembly_non_default_units.kcl
{
"cmdId": "[uuid]",
"range": [
197,
232,
198,
233,
3
],
"command": {
@ -140,8 +140,8 @@ description: Artifact commands assembly_non_default_units.kcl
{
"cmdId": "[uuid]",
"range": [
197,
232,
198,
233,
3
],
"command": {
@ -157,8 +157,8 @@ description: Artifact commands assembly_non_default_units.kcl
{
"cmdId": "[uuid]",
"range": [
197,
232,
198,
233,
3
],
"command": {
@ -168,8 +168,8 @@ description: Artifact commands assembly_non_default_units.kcl
{
"cmdId": "[uuid]",
"range": [
197,
232,
198,
233,
3
],
"command": {
@ -197,8 +197,8 @@ description: Artifact commands assembly_non_default_units.kcl
{
"cmdId": "[uuid]",
"range": [
197,
232,
198,
233,
3
],
"command": {

View File

@ -1,8 +1,8 @@
```mermaid
flowchart LR
subgraph path2 [Path]
2["Path<br>[197, 232, 3]"]
3["Segment<br>[197, 232, 3]"]
2["Path<br>[198, 233, 3]"]
3["Segment<br>[198, 233, 3]"]
4[Solid2d]
end
subgraph path6 [Path]
@ -10,7 +10,7 @@ flowchart LR
7["Segment<br>[114, 149, 4]"]
8[Solid2d]
end
1["Plane<br>[172, 191, 3]"]
1["Plane<br>[173, 192, 3]"]
5["Plane<br>[89, 108, 4]"]
1 --- 2
2 --- 3

View File

@ -1,3 +1,4 @@
@settings(defaultLengthUnit = in)
export radius = 1

View File

@ -11,16 +11,16 @@ description: Operations executed assembly_non_default_units.kcl
"value": "XZ"
},
"sourceRange": [
186,
190,
187,
191,
3
]
}
},
"name": "startSketchOn",
"sourceRange": [
172,
191,
173,
192,
3
],
"type": "StdLibCall",

View File

@ -1,5 +1,6 @@
@settings(defaultLengthUnit = in)
// This is not used, but it triggers the problem.
import radius from "globals.kcl"

View File

@ -1,4 +1,6 @@
@settings(defaultLengthUnit = mm)
import three from "import_cycle3.kcl"
export fn two = () => { return three() - 1 }
export fn two() {
return three() - 1
}

View File

@ -1,4 +1,6 @@
@settings(defaultLengthUnit = in)
import one from "input.kcl"
export fn three = () => { return one() + one() + one() }
export fn three() {
return one() + one() + one()
}

View File

@ -1,5 +1,6 @@
@settings(defaultLengthUnit = mm)
export part001 = startSketchOn('XY')
|> startProfileAt([4, 12], %)
|> line(end = [2, 0])
@ -12,4 +13,6 @@ export part001 = startSketchOn('XY')
|> close()
|> revolve({ axis = 'y' }, %) // default angle is 360
export fn two = () => { return 5 }
export fn two() {
return 5
}

View File

@ -11,16 +11,16 @@ description: Operations executed import_function_not_sketch.kcl
"value": "XY"
},
"sourceRange": [
66,
70,
67,
71,
3
]
}
},
"name": "startSketchOn",
"sourceRange": [
52,
71,
53,
72,
3
],
"type": "StdLibCall",
@ -39,8 +39,8 @@ description: Operations executed import_function_not_sketch.kcl
}
},
"sourceRange": [
312,
326,
313,
327,
3
]
},
@ -52,16 +52,16 @@ description: Operations executed import_function_not_sketch.kcl
}
},
"sourceRange": [
328,
329,
330,
3
]
}
},
"name": "revolve",
"sourceRange": [
304,
330,
305,
331,
3
],
"type": "StdLibCall",

View File

@ -1,4 +1,6 @@
export fn foo = () => { return 0 }
export fn foo() {
return 0
}
// This interacts with the engine.
part001 = startSketchOn('XY')

View File

@ -1,5 +1,5 @@
---
source: kcl/src/simulation_tests.rs
source: kcl-lib/src/simulation_tests.rs
description: Operations executed import_side_effect.kcl
---
[
@ -11,16 +11,16 @@ description: Operations executed import_side_effect.kcl
"value": "XY"
},
"sourceRange": [
91,
95,
99,
3
]
}
},
"name": "startSketchOn",
"sourceRange": [
81,
100,
77,
96,
3
],
"type": "StdLibCall",

View File

@ -490,7 +490,7 @@ async fn execute_code_and_export(code: String, export_format: FileExportFormat)
.map_err(|err| pyo3::exceptions::PyException::new_err(err.to_string()))?
}
/// Format the kcl code.
/// Format the kcl code. This will return the formatted code.
#[pyfunction]
fn format(code: String) -> PyResult<String> {
let program = kcl_lib::Program::parse_no_errs(&code).map_err(|err| into_miette_for_parse("", &code, err))?;
@ -499,6 +499,19 @@ fn format(code: String) -> PyResult<String> {
Ok(recasted)
}
/// Format a whole directory of kcl code.
#[pyfunction]
async fn format_dir(dir: String) -> PyResult<()> {
tokio()
.spawn(async move {
kcl_lib::recast_dir(std::path::Path::new(&dir), &Default::default())
.await
.map_err(|err| pyo3::exceptions::PyException::new_err(err.to_string()))
})
.await
.map_err(|err| pyo3::exceptions::PyException::new_err(err.to_string()))?
}
/// Lint the kcl code.
#[pyfunction]
fn lint(code: String) -> PyResult<Vec<Discovered>> {
@ -528,6 +541,7 @@ fn kcl(m: &Bound<'_, PyModule>) -> PyResult<()> {
m.add_function(wrap_pyfunction!(execute_and_export, m)?)?;
m.add_function(wrap_pyfunction!(execute_code_and_export, m)?)?;
m.add_function(wrap_pyfunction!(format, m)?)?;
m.add_function(wrap_pyfunction!(format_dir, m)?)?;
m.add_function(wrap_pyfunction!(lint, m)?)?;
Ok(())
}

View File

@ -129,6 +129,9 @@ def test_kcl_format():
assert formatted_code is not None
assert len(formatted_code) > 0
@pytest.mark.asyncio
async def test_kcl_format_dir():
await kcl.format_dir(walkie_talkie_dir)
def test_kcl_lint():
# Read from a file.