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 parsing::ast::{modify::modify_ast_for_sketch, types::FormatOptions};
pub use settings::types::{project::ProjectConfiguration, Configuration, UnitLength}; pub use settings::types::{project::ProjectConfiguration, Configuration, UnitLength};
pub use source_range::SourceRange; 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. // 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. // 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")] #[kcl_directory_test_macro::test_all_dirs("../public/kcl-samples")]
fn unparse(dir_name: &str, dir_path: &Path) { async fn unparse(dir_name: &str, dir_path: &Path) {
// kcl-samples don't always use correct formatting. We don't ignore the // TODO: turn this on when we fix the comments recasting.
// test because we want to allow the just command to work. It's actually // let t = test(dir_name, dir_path.join("main.kcl").to_str().unwrap().to_owned());
// fine when no test runs. // super::unparse_test(&t).await;
} }
#[kcl_directory_test_macro::test_all_dirs("../public/kcl-samples")] #[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)] #[cfg(test)]
mod tests { mod tests {
use pretty_assertions::assert_eq; use pretty_assertions::assert_eq;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,4 +1,6 @@
@settings(defaultLengthUnit = mm) @settings(defaultLengthUnit = mm)
import three from "import_cycle3.kcl" 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) @settings(defaultLengthUnit = in)
import one from "input.kcl" 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) @settings(defaultLengthUnit = mm)
export part001 = startSketchOn('XY') export part001 = startSketchOn('XY')
|> startProfileAt([4, 12], %) |> startProfileAt([4, 12], %)
|> line(end = [2, 0]) |> line(end = [2, 0])
@ -12,4 +13,6 @@ export part001 = startSketchOn('XY')
|> close() |> close()
|> revolve({ axis = 'y' }, %) // default angle is 360 |> 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" "value": "XY"
}, },
"sourceRange": [ "sourceRange": [
66, 67,
70, 71,
3 3
] ]
} }
}, },
"name": "startSketchOn", "name": "startSketchOn",
"sourceRange": [ "sourceRange": [
52, 53,
71, 72,
3 3
], ],
"type": "StdLibCall", "type": "StdLibCall",
@ -39,8 +39,8 @@ description: Operations executed import_function_not_sketch.kcl
} }
}, },
"sourceRange": [ "sourceRange": [
312, 313,
326, 327,
3 3
] ]
}, },
@ -52,16 +52,16 @@ description: Operations executed import_function_not_sketch.kcl
} }
}, },
"sourceRange": [ "sourceRange": [
328,
329, 329,
330,
3 3
] ]
} }
}, },
"name": "revolve", "name": "revolve",
"sourceRange": [ "sourceRange": [
304, 305,
330, 331,
3 3
], ],
"type": "StdLibCall", "type": "StdLibCall",

View File

@ -1,4 +1,6 @@
export fn foo = () => { return 0 } export fn foo() {
return 0
}
// This interacts with the engine. // This interacts with the engine.
part001 = startSketchOn('XY') 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 description: Operations executed import_side_effect.kcl
--- ---
[ [
@ -11,16 +11,16 @@ description: Operations executed import_side_effect.kcl
"value": "XY" "value": "XY"
}, },
"sourceRange": [ "sourceRange": [
91,
95, 95,
99,
3 3
] ]
} }
}, },
"name": "startSketchOn", "name": "startSketchOn",
"sourceRange": [ "sourceRange": [
81, 77,
100, 96,
3 3
], ],
"type": "StdLibCall", "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()))? .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] #[pyfunction]
fn format(code: String) -> PyResult<String> { fn format(code: String) -> PyResult<String> {
let program = kcl_lib::Program::parse_no_errs(&code).map_err(|err| into_miette_for_parse("", &code, err))?; 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) 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. /// Lint the kcl code.
#[pyfunction] #[pyfunction]
fn lint(code: String) -> PyResult<Vec<Discovered>> { 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_and_export, m)?)?;
m.add_function(wrap_pyfunction!(execute_code_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, m)?)?;
m.add_function(wrap_pyfunction!(format_dir, m)?)?;
m.add_function(wrap_pyfunction!(lint, m)?)?; m.add_function(wrap_pyfunction!(lint, m)?)?;
Ok(()) Ok(())
} }

View File

@ -129,6 +129,9 @@ def test_kcl_format():
assert formatted_code is not None assert formatted_code is not None
assert len(formatted_code) > 0 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(): def test_kcl_lint():
# Read from a file. # Read from a file.