From bf723eaa873e38121f79e779f1e0fdf6427a00ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrius=20Puk=C5=A1ta?= Date: Fri, 6 Feb 2026 11:51:25 +0200 Subject: [PATCH 01/13] enable faster toml parsing via fast_hash feature MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit See https://epage.github.io/blog/2025/07/toml-09/ for details Signed-off-by: Andrius Pukšta --- Cargo.lock | 1 + core/Cargo.toml | 2 +- sysand/Cargo.toml | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1bd00283..2c9db101 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3968,6 +3968,7 @@ version = "1.1.2+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81f3d15e84cbcd896376e6730314d59fb5a87f31e4b038454184435cd57defee" dependencies = [ + "foldhash", "indexmap", "serde_core", "serde_spanned", diff --git a/core/Cargo.toml b/core/Cargo.toml index 4b51676d..9eb87e2d 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -54,7 +54,7 @@ serde_json = { version = "1.0.149", default-features = false, features = ["prese sysand-macros = { path = "../macros"} spdx = "0.13.4" thiserror = { version = "2.0.18", default-features = false } -toml = "1.0.6" +toml = { version = "1.0.6", features = ["fast_hash"] } typed-path = { version = "0.12.3", default-features = false } walkdir = "2.5.0" # unicode-normalization = { version = "0.1.24", default-features = false } diff --git a/sysand/Cargo.toml b/sysand/Cargo.toml index 45272ed6..f22e6cab 100644 --- a/sysand/Cargo.toml +++ b/sysand/Cargo.toml @@ -32,7 +32,7 @@ env_logger = "0.11.9" log = { version = "0.4.29", default-features = false } sysand-core = { path = "../core", features = ["std", "filesystem", "networking"] } thiserror = "2.0.18" -toml = { version = "1.0.6", default-features = false } +toml = { version = "1.0.6", default-features = false, features = ["fast_hash"] } semver = "1.0.27" serde_json = { version = "1.0.149", default-features = false } spdx = "0.13.4" From 88d2d90dcb5785a9721ca1d8de99bf060d42eef1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrius=20Puk=C5=A1ta?= Date: Mon, 16 Mar 2026 07:35:20 +0200 Subject: [PATCH 02/13] wip MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Andrius Pukšta --- Cargo.lock | 2 +- bindings/java/src/lib.rs | 8 ++++++- bindings/py/src/lib.rs | 3 ++- core/scripts/run_tests.sh | 5 ++-- core/src/commands/build.rs | 45 +++++++++++++++++++++++++----------- core/src/commands/include.rs | 42 ++++++++++++++++----------------- core/src/model.rs | 16 +++++++++++++ docs/src/commands/build.md | 12 ++++++---- sysand/src/cli.rs | 5 ++++ sysand/src/commands/build.rs | 18 +++++++++++++-- sysand/src/lib.rs | 3 +++ 11 files changed, 114 insertions(+), 45 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2c9db101..ee1e4bf3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3968,7 +3968,7 @@ version = "1.1.2+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81f3d15e84cbcd896376e6730314d59fb5a87f31e4b038454184435cd57defee" dependencies = [ - "foldhash", + "foldhash 0.2.0", "indexmap", "serde_core", "serde_spanned", diff --git a/bindings/java/src/lib.rs b/bindings/java/src/lib.rs index 836bb9af..cecde8f0 100644 --- a/bindings/java/src/lib.rs +++ b/bindings/java/src/lib.rs @@ -498,6 +498,12 @@ fn compression_from_java_string( env.throw_exception(ExceptionKind::SysandException, err.to_string()); None } + KParBuildError::MissingIndexSymbol(path, symbol) => { + env.throw_exception( + ExceptionKind::SysandException, + format!("file `{path}` is missing symbol `{symbol}` found in index"), + ); + } } } @@ -530,7 +536,7 @@ pub extern "system" fn Java_com_sensmetry_sysand_Sysand_buildProject<'local>( &project, &output_path, compression, - true, + false, false, ); match command_result { diff --git a/bindings/py/src/lib.rs b/bindings/py/src/lib.rs index babb1b1f..f48c4e63 100644 --- a/bindings/py/src/lib.rs +++ b/bindings/py/src/lib.rs @@ -225,7 +225,7 @@ fn do_build_py( None => KparCompressionMethod::default(), }; - do_build_kpar(&project, &output_path, compression, true, false) + do_build_kpar(&project, &output_path, compression, false, false) .map(|_| ()) .map_err(|err| match err { KParBuildError::ProjectRead(_) => PyRuntimeError::new_err(err.to_string()), @@ -244,6 +244,7 @@ fn do_build_py( KParBuildError::WorkspaceMetamodelConflict { .. } => { PyValueError::new_err(err.to_string()) } + KParBuildError::MissingIndexSymbol(_, _) => PyValueError::new_err(err.to_string()), }) } diff --git a/core/scripts/run_tests.sh b/core/scripts/run_tests.sh index 9837efd9..46dfb183 100755 --- a/core/scripts/run_tests.sh +++ b/core/scripts/run_tests.sh @@ -12,5 +12,6 @@ PACKAGE_DIR=$(dirname "$SCRIPT_DIR") cd "$PACKAGE_DIR" cargo test --features filesystem,networking,alltests $@ -cargo test --features js $@ -cargo test --features python $@ +# Currently these features don't enable any tests +# cargo test --features js $@ +# cargo test --features python $@ diff --git a/core/src/commands/build.rs b/core/src/commands/build.rs index 611dd64d..bef391dd 100644 --- a/core/src/commands/build.rs +++ b/core/src/commands/build.rs @@ -4,9 +4,11 @@ use camino::{Utf8Path, Utf8PathBuf}; use thiserror::Error; +use std::collections::HashSet; + use crate::{ env::utils::{CloneError, ErrorBound}, - include::IncludeError, + include::{IncludeError, do_include, extract_symbols}, model::InterchangeProjectValidationError, project::{ ProjectRead, @@ -164,6 +166,8 @@ pub enum KParBuildError { project_metamodel: String, project_path: String, }, + #[error("file `{0}` is missing symbol `{1}` found in index")] + MissingIndexSymbol(Box, String), } impl From for KParBuildError { @@ -243,18 +247,20 @@ pub fn default_kpar_file_name( )) } +/// `update_index_checksum` controls whether to parse symbols from current +/// file to update index and also update file checksum pub fn do_build_kpar, Pr: ProjectRead>( project: &Pr, path: P, compression: KparCompressionMethod, - canonicalise: bool, + update_index_checksum: bool, allow_path_usage: bool, ) -> Result> { do_build_kpar_inner( project, path, compression, - canonicalise, + update_index_checksum, allow_path_usage, None, ) @@ -264,12 +270,10 @@ fn do_build_kpar_inner, Pr: ProjectRead>( project: &Pr, path: P, compression: KparCompressionMethod, - canonicalise: bool, + update_index_checksum: bool, allow_path_usage: bool, workspace_metamodel: Option<&str>, ) -> Result> { - use crate::project::local_src::LocalSrcProject; - let building = "Building"; let header = crate::style::get_style_config().header; log::info!("{header}{building:>12}{header:#} kpar `{}`", path.as_ref()); @@ -334,11 +338,26 @@ fn do_build_kpar_inner, Pr: ProjectRead>( } } - if canonicalise { - for path in meta.validate()?.source_paths(true) { - use crate::include::do_include; - - do_include(&mut local_project, &path, true, true, None)?; + let meta = meta.validate()?; + // Check whether index symbols are up to date + if update_index_checksum { + for p in meta.source_paths(true) { + do_include(&mut local_project, p, true, true, None)? + } + } else { + for p in meta.source_paths(true) { + let new_symbols = extract_symbols(&mut local_project, &p, None)?; + let new_symbols: HashSet = new_symbols.into_iter().collect(); + let old_symbols = meta.file_index_symbols(&p); + if let Some(only_in_old) = old_symbols.difference(&new_symbols).next() { + return Err(KParBuildError::MissingIndexSymbol( + p.as_str().into(), + only_in_old.clone(), + )); + } + for only_in_new in new_symbols.difference(&old_symbols) { + log::warn!("index is missing symbol `{only_in_new}` found in file `{p}`"); + } } } @@ -395,7 +414,7 @@ pub fn do_build_workspace_kpars>( workspace: &Workspace, path: P, compression: KparCompressionMethod, - canonicalise: bool, + update_index_checksum: bool, allow_path_usage: bool, ) -> Result, KParBuildError> { let ws_metamodel = workspace.metamodel().map(|iri| iri.as_str()); @@ -414,7 +433,7 @@ pub fn do_build_workspace_kpars>( &project, &output_path, compression, - canonicalise, + update_index_checksum, allow_path_usage, ws_metamodel, )?; diff --git a/core/src/commands/include.rs b/core/src/commands/include.rs index ca208181..61addf13 100644 --- a/core/src/commands/include.rs +++ b/core/src/commands/include.rs @@ -52,29 +52,29 @@ pub fn do_include>( log::info!("{header}{including:>12}{header:#} file `{}`", path.as_ref()); if index_symbols { - match force_format.or_else(|| Language::guess_from_path(&path)) { - Some(Language::SysML) => { - let new_symbols = crate::symbols::top_level_sysml( - project.read_source(&path).map_err(IncludeError::Project)?, - ) - .map_err(|e| IncludeError::Extract(path.as_ref().as_str().into(), e))?; - - project.replace_index_for_file(new_symbols.into_iter(), &path, true)?; - } - Some(Language::KerML) => { - let new_symbols = crate::symbols::top_level_kerml( - project.read_source(&path).map_err(IncludeError::Project)?, - ) - .map_err(|e| IncludeError::Extract(path.as_ref().as_str().into(), e))?; - - project.replace_index_for_file(new_symbols.into_iter(), &path, true)?; - } - _ => { - return Err(IncludeError::UnknownFormat(path.as_ref().as_str().into())); - } - } + let new_symbols = extract_symbols(project, &path, force_format)?; + project.replace_index_for_file(new_symbols.into_iter(), &path, true)?; } project.include_source(&path, compute_checksum, true)?; Ok(()) } + +/// Extract top level symbols from file at `path` belonging to `project` +pub fn extract_symbols>( + project: &mut Pr, + path: &P, + force_format: Option, +) -> Result, IncludeError> { + match force_format.or_else(|| Language::guess_from_path(path)) { + Some(Language::SysML) => crate::symbols::top_level_sysml( + project.read_source(path).map_err(IncludeError::Project)?, + ) + .map_err(|e| IncludeError::Extract(path.as_ref().as_str().into(), e)), + Some(Language::KerML) => crate::symbols::top_level_kerml( + project.read_source(path).map_err(IncludeError::Project)?, + ) + .map_err(|e| IncludeError::Extract(path.as_ref().as_str().into(), e)), + _ => Err(IncludeError::UnknownFormat(path.as_ref().as_str().into())), + } +} diff --git a/core/src/model.rs b/core/src/model.rs index 1b48db89..2a79fefc 100644 --- a/core/src/model.rs +++ b/core/src/model.rs @@ -505,6 +505,22 @@ pub enum InterchangeProjectValidationError { }, } +impl InterchangeProjectMetadata { + /// Get symbols recorded in `index` for file at `path` + pub fn file_index_symbols>(&self, path: P) -> HashSet { + self.index + .iter() + .filter_map(|(k, v)| { + if v == path.as_ref() { + Some(k.clone()) + } else { + None + } + }) + .collect() + } +} + impl Default for InterchangeProjectMetadataRaw { fn default() -> Self { InterchangeProjectMetadataRaw { diff --git a/docs/src/commands/build.md b/docs/src/commands/build.md index 0eb285a4..88833361 100644 --- a/docs/src/commands/build.md +++ b/docs/src/commands/build.md @@ -1,7 +1,7 @@ # `sysand build` -Build a KerML Project Archive (KPAR). If executed in a workspace outside of a -project, builds all projects in the workspace. +Build a KerML Project Archive (KPAR). If executed in a workspace +outside of a project, builds all projects in the workspace. ## Usage @@ -13,8 +13,8 @@ sysand build [OPTIONS] [PATH] Creates a KPAR file from the current project. -Current project is determined as in [sysand print-root](root.md) and -if none is found uses the current directory instead. +Current project is determined as in [`sysand print-root`](root.md) and +if none is found, defaults to current directory. If a `README.md` file exist at the project root, it is included in the `.kpar` archive. @@ -57,4 +57,8 @@ warning; the build still succeeds. computers, as `file://` URL always contains an absolute path. For multiple related projects, consider using a workspace instead +- `-u`, `--update-meta`: Update project metadata before building. This + includes updating project symbol index and adding/updating source + file checksums. + {{#include ./partials/global_opts.md}} diff --git a/sysand/src/cli.rs b/sysand/src/cli.rs index 9af02749..bfe09c2b 100644 --- a/sysand/src/cli.rs +++ b/sysand/src/cli.rs @@ -183,6 +183,11 @@ pub enum Command { /// For multiple related projects, consider using a workspace instead #[arg(long, short, default_value_t = false, verbatim_doc_comment)] allow_path_usage: bool, + // TODO: add tests + /// Update project metadata before building. This includes updating + /// project symbol index and adding/updating source file checksums + #[arg(long, short, default_value_t = false, verbatim_doc_comment)] + update_meta: bool, }, /// Publish a KPAR to a sysand package index Publish { diff --git a/sysand/src/commands/build.rs b/sysand/src/commands/build.rs index 12c525d9..d786be53 100644 --- a/sysand/src/commands/build.rs +++ b/sysand/src/commands/build.rs @@ -13,9 +13,16 @@ pub fn command_build_for_project>( path: P, compression: KparCompressionMethod, current_project: LocalSrcProject, + update_index_checksum: bool, allow_path_usage: bool, ) -> Result<()> { - match do_build_kpar(¤t_project, &path, compression, true, allow_path_usage) { + match do_build_kpar( + ¤t_project, + &path, + compression, + update_index_checksum, + allow_path_usage, + ) { Ok(_) => Ok(()), Err(err) => match err { KParBuildError::PathUsage(_) => bail!( @@ -31,6 +38,7 @@ pub fn command_build_for_workspace>( path: P, compression: KparCompressionMethod, workspace: Workspace, + update_index_checksum: bool, allow_path_usage: bool, ) -> Result<()> { log::warn!( @@ -39,7 +47,13 @@ pub fn command_build_for_workspace>( releases. For the status of this feature, see\n\ https://github.com/sensmetry/sysand/issues/101." ); - do_build_workspace_kpars(&workspace, &path, compression, true, allow_path_usage)?; + do_build_workspace_kpars( + &workspace, + &path, + compression, + update_index_checksum, + allow_path_usage, + )?; Ok(()) } diff --git a/sysand/src/lib.rs b/sysand/src/lib.rs index 8ba0eb0f..32fa42dc 100644 --- a/sysand/src/lib.rs +++ b/sysand/src/lib.rs @@ -667,6 +667,7 @@ pub fn run_cli(args: cli::Args) -> Result<()> { Command::Build { path, compression, + update_meta, allow_path_usage, } => { if let Some(current_project) = ctx.current_project { @@ -690,6 +691,7 @@ pub fn run_cli(args: cli::Args) -> Result<()> { path, compression.into(), current_project, + update_meta, allow_path_usage, ) } else { @@ -708,6 +710,7 @@ pub fn run_cli(args: cli::Args) -> Result<()> { output_dir, compression.into(), current_workspace, + update_meta, allow_path_usage, ) } From bca6a3c701c4c1d70c12a57aae56fd387f2698c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrius=20Puk=C5=A1ta?= Date: Wed, 22 Apr 2026 15:42:40 +0300 Subject: [PATCH 03/13] fix: fix build, update tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Andrius Pukšta --- bindings/java/src/lib.rs | 19 +--- sysand/src/cli.rs | 5 +- sysand/tests/cli_build.rs | 219 ++++++++++++++++++++++++++++++-------- 3 files changed, 182 insertions(+), 61 deletions(-) diff --git a/bindings/java/src/lib.rs b/bindings/java/src/lib.rs index cecde8f0..8ba13052 100644 --- a/bindings/java/src/lib.rs +++ b/bindings/java/src/lib.rs @@ -473,18 +473,15 @@ fn handle_build_error(env: &mut JNIEnv<'_>, error: KParBuildError format!("Workspace read error: {}", error), ); } - KParBuildError::PathUsage(usage) => { - env.throw_exception( - ExceptionKind::SysandException, - format!( - "project includes a path usage `{usage}`,\n\ - which is unlikely to be available on other computers at the same path" - ), - ); + KParBuildError::PathUsage(_) => { + env.throw_exception(ExceptionKind::SysandException, error.to_string()); } KParBuildError::WorkspaceMetamodelConflict { .. } => { env.throw_exception(ExceptionKind::SysandException, error.to_string()); } + KParBuildError::MissingIndexSymbol(_, _) => { + env.throw_exception(ExceptionKind::InvalidValue, error.to_string()) + } } } @@ -498,12 +495,6 @@ fn compression_from_java_string( env.throw_exception(ExceptionKind::SysandException, err.to_string()); None } - KParBuildError::MissingIndexSymbol(path, symbol) => { - env.throw_exception( - ExceptionKind::SysandException, - format!("file `{path}` is missing symbol `{symbol}` found in index"), - ); - } } } diff --git a/sysand/src/cli.rs b/sysand/src/cli.rs index bfe09c2b..d9644dbb 100644 --- a/sysand/src/cli.rs +++ b/sysand/src/cli.rs @@ -184,8 +184,9 @@ pub enum Command { #[arg(long, short, default_value_t = false, verbatim_doc_comment)] allow_path_usage: bool, // TODO: add tests - /// Update project metadata before building. This includes updating - /// project symbol index and adding/updating source file checksums + /// Update project metadata to be included in the build artifacts. This + /// includes updating project symbol index and adding/updating source file + /// checksums. Original project(s) will not be affected #[arg(long, short, default_value_t = false, verbatim_doc_comment)] update_meta: bool, }, diff --git a/sysand/tests/cli_build.rs b/sysand/tests/cli_build.rs index 6b19e4fc..037a6dd5 100644 --- a/sysand/tests/cli_build.rs +++ b/sysand/tests/cli_build.rs @@ -2,16 +2,21 @@ // SPDX-FileCopyrightText: © 2025 Sysand contributors use assert_cmd::prelude::*; +use camino::Utf8PathBuf; use clap::ValueEnum; use predicates::prelude::*; -use std::io::{Read, Write}; +use serde_json::json; +use std::{ + fs, + io::{Read, Write}, +}; use sysand::cli::KparCompressionMethodCli; use sysand_core::{ - model::{InterchangeProjectChecksumRaw, KerMlChecksumAlg}, - project::{ - ProjectRead, - local_kpar::{KparInnerPath, LocalKParProject}, + model::{ + InterchangeProjectChecksumRaw, InterchangeProjectInfoRaw, InterchangeProjectMetadataRaw, + KerMlChecksumAlg, }, + project::{ProjectRead, local_kpar::LocalKParProjectRaw}, }; // pub due to https://github.com/rust-lang/rust/issues/46379 @@ -30,6 +35,10 @@ fn project_build() -> Result<(), Box> { let out = run_sysand_in(&cwd, ["include", "--no-index-symbols", "test.sysml"], None)?; out.assert().success(); + let orig_info_path = cwd.join(".project.json"); + let orig_meta_path = cwd.join(".meta.json"); + let orig_info_contents = fs::read_to_string(&orig_info_path)?; + let orig_meta_contents = fs::read_to_string(&orig_meta_path)?; let out = run_sysand_in(&cwd, ["build", "./test_build.kpar"], None)?; @@ -46,19 +55,33 @@ fn project_build() -> Result<(), Box> { .stdout(predicate::str::contains("Name: test_build")) .stdout(predicate::str::contains("Version: 1.2.3")); - let kpar_project = LocalKParProject::new( - cwd.join("test_build.kpar"), - KparInnerPath::Guess, - None, - None, - ); + let kpar_project = LocalKParProjectRaw::new_guess_root(cwd.join("test_build.kpar"))?; - let (Some(_), Some(meta)) = kpar_project.get_project()? else { + let (Some(info), Some(meta)) = kpar_project.get_project()? else { panic!("failed to get built project info/meta"); }; - // Ensure things get canonicalised during build + // Ensure the build artifact matches original project + let original_meta: InterchangeProjectMetadataRaw = serde_json::from_str(&orig_meta_contents)?; + let original_info: InterchangeProjectInfoRaw = serde_json::from_str(&orig_info_contents)?; + assert_eq!(original_info, info); + assert_eq!(original_meta, meta); + // Ensure no changes were made to the original project + let new_info_contents = fs::read_to_string(&orig_info_path)?; + let new_meta_contents = fs::read_to_string(&orig_meta_path)?; + assert_eq!(orig_info_contents, new_info_contents); + assert_eq!(orig_meta_contents, new_meta_contents); + + // Now canonicalize meta during build + let out = run_sysand_in(&cwd, ["build", "--update-meta", "./test_build2.kpar"], None)?; + out.assert().success(); + let kpar_project = LocalKParProjectRaw::new_guess_root(cwd.join("test_build2.kpar"))?; + + let (Some(_), Some(meta)) = kpar_project.get_project()? else { + panic!("failed to get built project info/meta"); + }; + // File hash should be updated assert_eq!(meta.checksum.as_ref().unwrap().len(), 1); assert_eq!( meta.checksum.as_ref().unwrap().get("test.sysml").unwrap(), @@ -71,6 +94,12 @@ fn project_build() -> Result<(), Box> { assert_eq!(meta.index.len(), 1); assert_eq!(meta.index.get("P").unwrap(), "test.sysml"); + // Ensure no changes were made to the original project + let new_info_contents = fs::read_to_string(&orig_info_path)?; + let new_meta_contents = fs::read_to_string(&orig_meta_path)?; + assert_eq!(orig_info_contents, new_info_contents); + assert_eq!(orig_meta_contents, new_meta_contents); + Ok(()) } @@ -122,12 +151,7 @@ fn project_build_path_usage() -> Result<(), Box> { .stdout(predicate::str::contains("Version: 1.2.3")) .stdout(predicate::str::contains(file_url_from_path(&cwd2))); - let kpar_project = LocalKParProject::new( - cwd1.join("test_build.kpar"), - KparInnerPath::Guess, - None, - None, - ); + let kpar_project = LocalKParProjectRaw::new_guess_root(cwd1.join("test_build.kpar"))?; let (Some(_), Some(_)) = kpar_project.get_project()? else { panic!("failed to get built project info/meta"); @@ -136,11 +160,36 @@ fn project_build_path_usage() -> Result<(), Box> { Ok(()) } +struct WProject { + name: String, + info_path: Utf8PathBuf, + meta_path: Utf8PathBuf, + orig_info_contents: String, + orig_meta_contents: String, +} +impl WProject { + fn new(cwd: Utf8PathBuf) -> Result> { + let name = cwd.file_name().unwrap().to_owned(); + let info_path = cwd.join(".project.json"); + let meta_path = cwd.join(".meta.json"); + let orig_info_contents = fs::read_to_string(&info_path)?; + let orig_meta_contents = fs::read_to_string(&meta_path)?; + Ok(Self { + name, + info_path, + meta_path, + orig_info_contents, + orig_meta_contents, + }) + } +} + #[test] fn workspace_build() -> Result<(), Box> { let (_temp_dir, cwd) = new_temp_cwd()?; let project_group_cwd = cwd.join("subgroup"); std::fs::create_dir(&project_group_cwd)?; + let project1_cwd = project_group_cwd.join("project1"); let project2_cwd = project_group_cwd.join("project2"); let project3_cwd = cwd.join("project3"); @@ -148,19 +197,25 @@ fn workspace_build() -> Result<(), Box> { // Create .workspace.json file std::fs::write( cwd.join(".workspace.json"), - br#"{"projects": [ - {"path": "subgroup/project1", "iris": ["urn:kpar:project1"]}, - {"path": "subgroup/project2", "iris": ["urn:kpar:project2"]}, - {"path": "project3", "iris": ["urn:kpar:project3"]} - ]}"#, + json!({"projects": [ + {"path": "subgroup/project1", "iris": ["urn:kpar:project1"]}, + {"path": "subgroup/project2", "iris": ["urn:kpar:project2"]}, + {"path": "project3", "iris": ["urn:kpar:project3"]} + ]}) + .to_string(), )?; for project_cwd in [&project1_cwd, &project2_cwd, &project3_cwd] { std::fs::create_dir(project_cwd)?; - let project_name = project_cwd.file_name().unwrap(); let out = run_sysand_in( project_cwd, - ["init", "--version", "1.2.3", "--name", project_name], + [ + "init", + "--version", + "1.2.3", + "--name", + project_cwd.file_name().unwrap(), + ], None, )?; out.assert().success(); @@ -174,13 +229,19 @@ fn workspace_build() -> Result<(), Box> { out.assert().success(); } + let projects = [ + WProject::new(project1_cwd)?, + WProject::new(project2_cwd)?, + WProject::new(project3_cwd)?, + ]; + let out = run_sysand_in(&cwd, ["build"], None)?; out.assert().success(); - for project_name in ["project1", "project2", "project3"] { + for project in &projects { let kpar_path = cwd .join("output") - .join(format!("{}-1.2.3.kpar", project_name)); + .join(format!("{}-1.2.3.kpar", project.name)); assert!( kpar_path.is_file(), "kpar file does not exist: {}", @@ -191,29 +252,103 @@ fn workspace_build() -> Result<(), Box> { out.assert() .success() - .stdout(predicate::str::contains(format!("Name: {}", project_name))) + .stdout(predicate::str::contains(format!("Name: {}", project.name))) .stdout(predicate::str::contains("Version: 1.2.3")); - let kpar_project = LocalKParProject::new(kpar_path, KparInnerPath::Guess, None, None); + let kpar_project = LocalKParProjectRaw::new_guess_root(kpar_path)?; - let (Some(_), Some(meta)) = kpar_project.get_project()? else { + let (Some(info), Some(meta)) = kpar_project.get_project()? else { panic!("failed to get built project info/meta"); }; - // Ensure things get canonicalised during build + // Ensure the build artifact matches original project + let original_meta: InterchangeProjectMetadataRaw = + serde_json::from_str(&project.orig_meta_contents)?; + let original_info: InterchangeProjectInfoRaw = + serde_json::from_str(&project.orig_info_contents)?; + assert_eq!(original_info, info); + assert_eq!(original_meta, meta); + + // Ensure no changes were made to the original project + let new_info_contents = fs::read_to_string(&project.info_path)?; + let new_meta_contents = fs::read_to_string(&project.meta_path)?; + assert_eq!(project.orig_info_contents, new_info_contents); + assert_eq!(project.orig_meta_contents, new_meta_contents); + + // out.assert() + // .success() + // .stdout(predicate::str::contains(format!("Name: {}", project.name))) + // .stdout(predicate::str::contains("Version: 1.2.3")); + + // let kpar_project = LocalKParProject::new_guess_root(kpar_path)?; + + // let (Some(_), Some(meta)) = kpar_project.get_project()? else { + // panic!("failed to get built project info/meta"); + // }; + + // // Ensure things get canonicalised during build + + // assert_eq!(meta.checksum.as_ref().unwrap().len(), 1); + // assert_eq!( + // meta.checksum.as_ref().unwrap().get("test.sysml").unwrap(), + // &InterchangeProjectChecksumRaw { + // value: "b4ee9d8a3ffb51787bd30ab1a74c2333565fd2b8be1334e827c5937f44d54dd8" + // .to_string(), + // algorithm: KerMlChecksumAlg::Sha256.into(), + // } + // ); + + // assert_eq!(meta.index.len(), 1); + // assert_eq!(meta.index.get("P").unwrap(), "test.sysml"); + } + + // Now canonicalize meta during build. Previous artifacts should be overwritten + let out = run_sysand_in(&cwd, ["build", "--update-meta"], None)?; + out.assert().success(); + + for project in &projects { + println!("W9: {}", project.name); + let kpar_path = cwd + .join("output") + .join(format!("{}-1.2.3.kpar", project.name)); + assert!( + kpar_path.is_file(), + "kpar file does not exist: {}", + kpar_path + ); + + let out = run_sysand_in(&cwd, ["info", "--path", kpar_path.as_str()], None)?; + + out.assert() + .success() + .stdout(predicate::str::contains(format!("Name: {}", project.name))) + .stdout(predicate::str::contains("Version: 1.2.3")); + + let kpar_project = LocalKParProjectRaw::new_guess_root(kpar_path)?; + + let (Some(_), Some(meta)) = kpar_project.get_project()? else { + panic!("failed to get built project info/meta"); + }; + // File hash should be updated assert_eq!(meta.checksum.as_ref().unwrap().len(), 1); assert_eq!( meta.checksum.as_ref().unwrap().get("test.sysml").unwrap(), &InterchangeProjectChecksumRaw { value: "b4ee9d8a3ffb51787bd30ab1a74c2333565fd2b8be1334e827c5937f44d54dd8" .to_string(), - algorithm: KerMlChecksumAlg::Sha256.into(), + algorithm: KerMlChecksumAlg::Sha256.into() } ); assert_eq!(meta.index.len(), 1); assert_eq!(meta.index.get("P").unwrap(), "test.sysml"); + + // Ensure no changes were made to the original project + let new_info_contents = fs::read_to_string(&project.info_path)?; + let new_meta_contents = fs::read_to_string(&project.meta_path)?; + assert_eq!(project.orig_info_contents, new_info_contents); + assert_eq!(project.orig_meta_contents, new_meta_contents); } Ok(()) @@ -263,7 +398,7 @@ fn workspace_build_with_metamodel() -> Result<(), Box> { kpar_path ); - let kpar_project = LocalKParProject::new(kpar_path, KparInnerPath::Guess, None, None); + let kpar_project = LocalKParProjectRaw::new_guess_root(kpar_path)?; let (Some(_), Some(meta)) = kpar_project.get_project()? else { panic!("failed to get built project info/meta"); }; @@ -321,7 +456,7 @@ fn workspace_build_with_unknown_metamodel() -> Result<(), Box Result<(), Box Result<(), Box) -> Result<(), Box) -> Result<(), Box Date: Fri, 29 May 2026 12:23:01 +0300 Subject: [PATCH 04/13] cleanup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Andrius Pukšta --- sysand/tests/cli_build.rs | 26 -------------------------- 1 file changed, 26 deletions(-) diff --git a/sysand/tests/cli_build.rs b/sysand/tests/cli_build.rs index 037a6dd5..6db17764 100644 --- a/sysand/tests/cli_build.rs +++ b/sysand/tests/cli_build.rs @@ -274,32 +274,6 @@ fn workspace_build() -> Result<(), Box> { let new_meta_contents = fs::read_to_string(&project.meta_path)?; assert_eq!(project.orig_info_contents, new_info_contents); assert_eq!(project.orig_meta_contents, new_meta_contents); - - // out.assert() - // .success() - // .stdout(predicate::str::contains(format!("Name: {}", project.name))) - // .stdout(predicate::str::contains("Version: 1.2.3")); - - // let kpar_project = LocalKParProject::new_guess_root(kpar_path)?; - - // let (Some(_), Some(meta)) = kpar_project.get_project()? else { - // panic!("failed to get built project info/meta"); - // }; - - // // Ensure things get canonicalised during build - - // assert_eq!(meta.checksum.as_ref().unwrap().len(), 1); - // assert_eq!( - // meta.checksum.as_ref().unwrap().get("test.sysml").unwrap(), - // &InterchangeProjectChecksumRaw { - // value: "b4ee9d8a3ffb51787bd30ab1a74c2333565fd2b8be1334e827c5937f44d54dd8" - // .to_string(), - // algorithm: KerMlChecksumAlg::Sha256.into(), - // } - // ); - - // assert_eq!(meta.index.len(), 1); - // assert_eq!(meta.index.get("P").unwrap(), "test.sysml"); } // Now canonicalize meta during build. Previous artifacts should be overwritten From 1ae86325473cbf6b8c741dc13e5f04483e7a77ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrius=20Puk=C5=A1ta?= Date: Fri, 29 May 2026 12:51:11 +0300 Subject: [PATCH 05/13] try disabling fast_hash MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Andrius Pukšta --- Cargo.lock | 1 - core/Cargo.toml | 2 +- sysand/Cargo.toml | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ee1e4bf3..1bd00283 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3968,7 +3968,6 @@ version = "1.1.2+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81f3d15e84cbcd896376e6730314d59fb5a87f31e4b038454184435cd57defee" dependencies = [ - "foldhash 0.2.0", "indexmap", "serde_core", "serde_spanned", diff --git a/core/Cargo.toml b/core/Cargo.toml index 9eb87e2d..ac32e1dd 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -54,7 +54,7 @@ serde_json = { version = "1.0.149", default-features = false, features = ["prese sysand-macros = { path = "../macros"} spdx = "0.13.4" thiserror = { version = "2.0.18", default-features = false } -toml = { version = "1.0.6", features = ["fast_hash"] } +toml = { version = "1.0.6" } typed-path = { version = "0.12.3", default-features = false } walkdir = "2.5.0" # unicode-normalization = { version = "0.1.24", default-features = false } diff --git a/sysand/Cargo.toml b/sysand/Cargo.toml index f22e6cab..45272ed6 100644 --- a/sysand/Cargo.toml +++ b/sysand/Cargo.toml @@ -32,7 +32,7 @@ env_logger = "0.11.9" log = { version = "0.4.29", default-features = false } sysand-core = { path = "../core", features = ["std", "filesystem", "networking"] } thiserror = "2.0.18" -toml = { version = "1.0.6", default-features = false, features = ["fast_hash"] } +toml = { version = "1.0.6", default-features = false } semver = "1.0.27" serde_json = { version = "1.0.149", default-features = false } spdx = "0.13.4" From 122c23ff804957c8318995a4a94520cd803474dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrius=20Puk=C5=A1ta?= Date: Fri, 29 May 2026 14:29:55 +0300 Subject: [PATCH 06/13] revert, attempt fix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Andrius Pukšta --- Cargo.lock | 1 + core/Cargo.toml | 2 +- sysand/Cargo.toml | 2 +- sysand/tests/cli_add_remove.rs | 1 + 4 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1bd00283..ee1e4bf3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3968,6 +3968,7 @@ version = "1.1.2+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81f3d15e84cbcd896376e6730314d59fb5a87f31e4b038454184435cd57defee" dependencies = [ + "foldhash 0.2.0", "indexmap", "serde_core", "serde_spanned", diff --git a/core/Cargo.toml b/core/Cargo.toml index ac32e1dd..9eb87e2d 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -54,7 +54,7 @@ serde_json = { version = "1.0.149", default-features = false, features = ["prese sysand-macros = { path = "../macros"} spdx = "0.13.4" thiserror = { version = "2.0.18", default-features = false } -toml = { version = "1.0.6" } +toml = { version = "1.0.6", features = ["fast_hash"] } typed-path = { version = "0.12.3", default-features = false } walkdir = "2.5.0" # unicode-normalization = { version = "0.1.24", default-features = false } diff --git a/sysand/Cargo.toml b/sysand/Cargo.toml index 45272ed6..d0e6a595 100644 --- a/sysand/Cargo.toml +++ b/sysand/Cargo.toml @@ -32,7 +32,7 @@ env_logger = "0.11.9" log = { version = "0.4.29", default-features = false } sysand-core = { path = "../core", features = ["std", "filesystem", "networking"] } thiserror = "2.0.18" -toml = { version = "1.0.6", default-features = false } +toml = { version = "1.0.6", features = ["fast_hash"] } semver = "1.0.27" serde_json = { version = "1.0.149", default-features = false } spdx = "0.13.4" diff --git a/sysand/tests/cli_add_remove.rs b/sysand/tests/cli_add_remove.rs index bed3816b..0930eadd 100644 --- a/sysand/tests/cli_add_remove.rs +++ b/sysand/tests/cli_add_remove.rs @@ -519,6 +519,7 @@ fn add_and_remove_as_local_kpar() -> Result<(), Box> { ["init", "--version", "1.2.3", "--name", "add_and_remove"], None, )?; + dbg!("hello"); out.assert().success(); From 977665404ed3f943ff8d8d296ea12ffcec16ed2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrius=20Puk=C5=A1ta?= Date: Fri, 29 May 2026 14:50:49 +0300 Subject: [PATCH 07/13] try reducing stack use MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Andrius Pukšta --- sysand/src/cli.rs | 12 ++++++------ sysand/src/lib.rs | 8 +++++--- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/sysand/src/cli.rs b/sysand/src/cli.rs index d9644dbb..2f72510f 100644 --- a/sysand/src/cli.rs +++ b/sysand/src/cli.rs @@ -183,12 +183,12 @@ pub enum Command { /// For multiple related projects, consider using a workspace instead #[arg(long, short, default_value_t = false, verbatim_doc_comment)] allow_path_usage: bool, - // TODO: add tests - /// Update project metadata to be included in the build artifacts. This - /// includes updating project symbol index and adding/updating source file - /// checksums. Original project(s) will not be affected - #[arg(long, short, default_value_t = false, verbatim_doc_comment)] - update_meta: bool, + // // TODO: add tests + // /// Update project metadata to be included in the build artifacts. This + // /// includes updating project symbol index and adding/updating source file + // /// checksums. Original project(s) will not be affected + // #[arg(long, short, default_value_t = false, verbatim_doc_comment)] + // update_meta: bool, }, /// Publish a KPAR to a sysand package index Publish { diff --git a/sysand/src/lib.rs b/sysand/src/lib.rs index 32fa42dc..098de2e3 100644 --- a/sysand/src/lib.rs +++ b/sysand/src/lib.rs @@ -667,7 +667,7 @@ pub fn run_cli(args: cli::Args) -> Result<()> { Command::Build { path, compression, - update_meta, + // update_meta, allow_path_usage, } => { if let Some(current_project) = ctx.current_project { @@ -691,7 +691,8 @@ pub fn run_cli(args: cli::Args) -> Result<()> { path, compression.into(), current_project, - update_meta, + true, + // update_meta, allow_path_usage, ) } else { @@ -710,7 +711,8 @@ pub fn run_cli(args: cli::Args) -> Result<()> { output_dir, compression.into(), current_workspace, - update_meta, + true, + // update_meta, allow_path_usage, ) } From 0d6fedafbc9cce08d2229cfb037c67c24072359c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrius=20Puk=C5=A1ta?= Date: Fri, 29 May 2026 15:02:29 +0300 Subject: [PATCH 08/13] try increasing stack size MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Andrius Pukšta --- .cargo/config.toml | 4 +++- sysand/src/cli.rs | 11 +++++------ sysand/src/lib.rs | 8 +++----- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/.cargo/config.toml b/.cargo/config.toml index 89430923..8b1be352 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -9,5 +9,7 @@ # crt-static reference: See https://rust-lang.github.io/rfcs/1721-crt-static.html # dumpbin verification: https://github.com/sensmetry/sysand/pull/91#issuecomment-4081523020 # +# Increase the stack size, since Windows default 1 MiB causes a stack +# overflow on almost any CLI operation [target.'cfg(windows)'] -rustflags = ["-Ctarget-feature=+crt-static"] +rustflags = ["-Ctarget-feature=+crt-static", "-Clink-args=/STACK:8388608"] diff --git a/sysand/src/cli.rs b/sysand/src/cli.rs index 2f72510f..6e2c3b3b 100644 --- a/sysand/src/cli.rs +++ b/sysand/src/cli.rs @@ -183,12 +183,11 @@ pub enum Command { /// For multiple related projects, consider using a workspace instead #[arg(long, short, default_value_t = false, verbatim_doc_comment)] allow_path_usage: bool, - // // TODO: add tests - // /// Update project metadata to be included in the build artifacts. This - // /// includes updating project symbol index and adding/updating source file - // /// checksums. Original project(s) will not be affected - // #[arg(long, short, default_value_t = false, verbatim_doc_comment)] - // update_meta: bool, + /// Update project metadata to be included in the build artifacts. This + /// includes updating project symbol index and adding/updating source file + /// checksums. Original project(s) will not be affected + #[arg(long, short, default_value_t = false, verbatim_doc_comment)] + update_meta: bool, }, /// Publish a KPAR to a sysand package index Publish { diff --git a/sysand/src/lib.rs b/sysand/src/lib.rs index 098de2e3..32fa42dc 100644 --- a/sysand/src/lib.rs +++ b/sysand/src/lib.rs @@ -667,7 +667,7 @@ pub fn run_cli(args: cli::Args) -> Result<()> { Command::Build { path, compression, - // update_meta, + update_meta, allow_path_usage, } => { if let Some(current_project) = ctx.current_project { @@ -691,8 +691,7 @@ pub fn run_cli(args: cli::Args) -> Result<()> { path, compression.into(), current_project, - true, - // update_meta, + update_meta, allow_path_usage, ) } else { @@ -711,8 +710,7 @@ pub fn run_cli(args: cli::Args) -> Result<()> { output_dir, compression.into(), current_workspace, - true, - // update_meta, + update_meta, allow_path_usage, ) } From 81e82ae7735c00d7e180fe55597d9bc9f4802a76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrius=20Puk=C5=A1ta?= Date: Fri, 29 May 2026 15:31:53 +0300 Subject: [PATCH 09/13] add tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Andrius Pukšta --- core/src/commands/build.rs | 7 +++- sysand/tests/cli_build.rs | 81 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+), 1 deletion(-) diff --git a/core/src/commands/build.rs b/core/src/commands/build.rs index bef391dd..c9bc5727 100644 --- a/core/src/commands/build.rs +++ b/core/src/commands/build.rs @@ -356,7 +356,12 @@ fn do_build_kpar_inner, Pr: ProjectRead>( )); } for only_in_new in new_symbols.difference(&old_symbols) { - log::warn!("index is missing symbol `{only_in_new}` found in file `{p}`"); + // TODO: figure out a way to only print suggestions when running the CLI + log::warn!( + "index is missing symbol `{only_in_new}` found in file `{p}`;\n\ + include the file again to update its exported symbols, or pass `--update-meta`\n\ + to do so for all files" + ); } } } diff --git a/sysand/tests/cli_build.rs b/sysand/tests/cli_build.rs index 6db17764..f3da9a21 100644 --- a/sysand/tests/cli_build.rs +++ b/sysand/tests/cli_build.rs @@ -103,6 +103,87 @@ fn project_build() -> Result<(), Box> { Ok(()) } +#[test] +fn project_build_errors_when_index_symbol_is_missing_from_file() +-> Result<(), Box> { + let (_temp_dir, cwd, out) = run_sysand( + [ + "init", + "--version", + "1.2.3", + "--name", + "test_build_missing_index_symbol", + ], + None, + )?; + out.assert().success(); + + std::fs::write(cwd.join("test.sysml"), b"package Present;\n")?; + let out = run_sysand_in( + &cwd, + [ + "include", + "--compute-checksum", + "--no-index-symbols", + "test.sysml", + ], + None, + )?; + out.assert().success(); + + let meta_path = cwd.join(".meta.json"); + let mut meta: serde_json::Value = serde_json::from_str(&fs::read_to_string(&meta_path)?)?; + meta["index"] = json!({ + "Missing": "test.sysml" + }); + std::fs::write(&meta_path, serde_json::to_string_pretty(&meta)?)?; + + let out = run_sysand_in(&cwd, ["build", "./test_build.kpar"], None)?; + out.assert().failure().stderr(predicate::str::contains( + "file `test.sysml` is missing symbol `Missing` found in index", + )); + assert!(!cwd.join("test_build.kpar").exists()); + + Ok(()) +} + +#[test] +fn project_build_warns_when_file_symbol_is_missing_from_index() +-> Result<(), Box> { + let (_temp_dir, cwd, out) = run_sysand( + [ + "init", + "--version", + "1.2.3", + "--name", + "test_build_missing_index_entry", + ], + None, + )?; + out.assert().success(); + + std::fs::write(cwd.join("test.sysml"), b"package Present;\n")?; + let out = run_sysand_in( + &cwd, + [ + "include", + "--compute-checksum", + "--no-index-symbols", + "test.sysml", + ], + None, + )?; + out.assert().success(); + + let out = run_sysand_in(&cwd, ["build", "./test_build.kpar"], None)?; + out.assert().success().stderr(predicate::str::contains( + "index is missing symbol `Present` found in file `test.sysml`", + )); + assert!(cwd.join("test_build.kpar").exists()); + + Ok(()) +} + /// Build a project that has a path (`file:`) usage #[test] fn project_build_path_usage() -> Result<(), Box> { From 2d0d1ceccb84cdb9842901c744baaac52630835d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrius=20Puk=C5=A1ta?= Date: Fri, 29 May 2026 15:43:06 +0300 Subject: [PATCH 10/13] Update .cargo/config.toml MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Erik Sundell Signed-off-by: Andrius Pukšta --- .cargo/config.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.cargo/config.toml b/.cargo/config.toml index 8b1be352..ffd72f00 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -9,7 +9,7 @@ # crt-static reference: See https://rust-lang.github.io/rfcs/1721-crt-static.html # dumpbin verification: https://github.com/sensmetry/sysand/pull/91#issuecomment-4081523020 # -# Increase the stack size, since Windows default 1 MiB causes a stack +# Increase the stack size to 8MiB, since Windows default 1 MiB causes a stack # overflow on almost any CLI operation [target.'cfg(windows)'] rustflags = ["-Ctarget-feature=+crt-static", "-Clink-args=/STACK:8388608"] From 89207c31bc298251899e07157b7aacabca71ca90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrius=20Puk=C5=A1ta?= Date: Fri, 29 May 2026 15:46:49 +0300 Subject: [PATCH 11/13] explanation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Andrius Pukšta --- .cargo/config.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.cargo/config.toml b/.cargo/config.toml index ffd72f00..89c6fc25 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -10,6 +10,7 @@ # dumpbin verification: https://github.com/sensmetry/sysand/pull/91#issuecomment-4081523020 # # Increase the stack size to 8MiB, since Windows default 1 MiB causes a stack -# overflow on almost any CLI operation +# overflow on almost any CLI operation. Likely related to +# https://github.com/clap-rs/clap/issues/5134 [target.'cfg(windows)'] rustflags = ["-Ctarget-feature=+crt-static", "-Clink-args=/STACK:8388608"] From e9224d2918fc296fe7403c1aae355a11c2c19965 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrius=20Puk=C5=A1ta?= Date: Fri, 29 May 2026 15:58:18 +0300 Subject: [PATCH 12/13] cleanup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Andrius Pukšta --- sysand/tests/cli_add_remove.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/sysand/tests/cli_add_remove.rs b/sysand/tests/cli_add_remove.rs index 0930eadd..bed3816b 100644 --- a/sysand/tests/cli_add_remove.rs +++ b/sysand/tests/cli_add_remove.rs @@ -519,7 +519,6 @@ fn add_and_remove_as_local_kpar() -> Result<(), Box> { ["init", "--version", "1.2.3", "--name", "add_and_remove"], None, )?; - dbg!("hello"); out.assert().success(); From 8c960da610b0769b50017b7eb430b28bcb4f193c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrius=20Puk=C5=A1ta?= Date: Fri, 29 May 2026 16:05:00 +0300 Subject: [PATCH 13/13] clarify MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Andrius Pukšta --- core/src/commands/build.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/commands/build.rs b/core/src/commands/build.rs index c9bc5727..2aa0d75e 100644 --- a/core/src/commands/build.rs +++ b/core/src/commands/build.rs @@ -359,8 +359,8 @@ fn do_build_kpar_inner, Pr: ProjectRead>( // TODO: figure out a way to only print suggestions when running the CLI log::warn!( "index is missing symbol `{only_in_new}` found in file `{p}`;\n\ - include the file again to update its exported symbols, or pass `--update-meta`\n\ - to do so for all files" + if this is not intentional, include the file again to update its\n\ + exported symbols, or pass `--update-meta` to do so for all files" ); } }