From 4a21497884096e7fad288913f18e3c638d00802d Mon Sep 17 00:00:00 2001 From: Yu Zhang Date: Mon, 21 Sep 2026 14:22:00 +0800 Subject: [PATCH 1/2] refactor: separate package discovery from solving --- crates/moon/src/cli/build.rs | 10 +- crates/moon/src/cli/bundle.rs | 2 +- crates/moon/src/cli/check.rs | 14 +-- crates/moon/src/cli/doc.rs | 2 +- crates/moon/src/cli/info.rs | 8 +- crates/moon/src/cli/info/imp.rs | 4 +- crates/moon/src/cli/prove.rs | 4 +- crates/moon/src/cli/run.rs | 6 +- crates/moon/src/cli/test.rs | 20 +-- crates/moon/src/cli/tool/build_binary_dep.rs | 2 +- crates/moon/src/cli/tree.rs | 10 +- crates/moon/src/filter.rs | 75 ++++++++--- crates/moon/src/rr_build/mod.rs | 8 +- crates/moon/src/watch/prebuild_output.rs | 4 +- .../src/build_lower/mod.rs | 9 +- .../moonbuild-rupes-recta/src/compile/mod.rs | 36 ++++-- crates/moonbuild-rupes-recta/src/lib.rs | 10 +- .../moonbuild-rupes-recta/src/resolve/mod.rs | 116 ++++++++++++------ docs/dev/reference/modules-packages.md | 9 ++ 19 files changed, 236 insertions(+), 113 deletions(-) diff --git a/crates/moon/src/cli/build.rs b/crates/moon/src/cli/build.rs index ac99880763..b93d57f9c3 100644 --- a/crates/moon/src/cli/build.rs +++ b/crates/moon/src/cli/build.rs @@ -618,7 +618,7 @@ fn has_explicit_build_selector(cmd: &BuildSubcommand) -> bool { } fn resolve_build_target_selections( - resolve_output: &moonbuild_rupes_recta::ResolveOutput, + resolve_output: &moonbuild_rupes_recta::ProjectDeclarations, cmd: &BuildSubcommand, selected_target_backend: Option, user_log: &UserLog, @@ -652,7 +652,7 @@ fn resolve_build_target_selections( } fn resolve_selected_build_packages( - resolve_output: &moonbuild_rupes_recta::ResolveOutput, + resolve_output: &moonbuild_rupes_recta::ProjectDeclarations, cmd: &BuildSubcommand, target_backend: Option, user_log: &UserLog, @@ -697,7 +697,7 @@ fn resolve_selected_build_packages( fn calc_user_intent( path_filters: &[PathBuf], package_filter: Option<&str>, - resolve_output: &moonbuild_rupes_recta::ResolveOutput, + resolve_output: &moonbuild_rupes_recta::ProjectDeclarations, target_backend: TargetBackend, user_log: &UserLog, ) -> Result { @@ -734,7 +734,7 @@ fn calc_user_intent( } fn calc_user_intent_from_scoped_packages( - resolve_output: &moonbuild_rupes_recta::ResolveOutput, + resolve_output: &moonbuild_rupes_recta::ProjectDeclarations, supported_packages: &[PackageId], target_backend: TargetBackend, ) -> Result { @@ -760,7 +760,7 @@ fn calc_user_intent_from_scoped_packages( } fn get_linkable_pkgs( - resolve_output: &moonbuild_rupes_recta::ResolveOutput, + resolve_output: &moonbuild_rupes_recta::ProjectDeclarations, target_backend: TargetBackend, packages: impl Iterator, ) -> Vec { diff --git a/crates/moon/src/cli/bundle.rs b/crates/moon/src/cli/bundle.rs index c86a23a9a6..a5a924bee4 100644 --- a/crates/moon/src/cli/bundle.rs +++ b/crates/moon/src/cli/bundle.rs @@ -247,7 +247,7 @@ pub(crate) fn plan_bundle_rr_from_resolved( } fn bundle_user_intent( - resolve_output: &moonbuild_rupes_recta::ResolveOutput, + resolve_output: &moonbuild_rupes_recta::ProjectDeclarations, ) -> CalcUserIntentOutput { resolve_output .local_modules() diff --git a/crates/moon/src/cli/check.rs b/crates/moon/src/cli/check.rs index fe74e959d5..75a5fd677f 100644 --- a/crates/moon/src/cli/check.rs +++ b/crates/moon/src/cli/check.rs @@ -622,7 +622,7 @@ fn run_check_for_single_file_rr( } fn get_user_intents_single_file( - resolve_output: &moonbuild_rupes_recta::ResolveOutput, + resolve_output: &moonbuild_rupes_recta::ProjectDeclarations, _backend: TargetBackend, ) -> Result { let m_packages = resolve_output @@ -957,7 +957,7 @@ pub(crate) fn plan_check_rr_from_resolved_all( } fn validate_selector_flags_before_split( - resolve_output: &moonbuild_rupes_recta::ResolveOutput, + resolve_output: &moonbuild_rupes_recta::ProjectDeclarations, cmd: &CheckSubcommand, source_dir: &Path, target_backend: Option, @@ -1059,7 +1059,7 @@ fn plan_check_rr_from_selection( } pub(crate) fn resolve_check_target_selections( - resolve_output: &moonbuild_rupes_recta::ResolveOutput, + resolve_output: &moonbuild_rupes_recta::ProjectDeclarations, cmd: &CheckSubcommand, source_dir: &Path, selected_target_backend: Option, @@ -1102,7 +1102,7 @@ pub(crate) fn resolve_check_target_selections( } fn resolve_selected_packages( - resolve_output: &moonbuild_rupes_recta::ResolveOutput, + resolve_output: &moonbuild_rupes_recta::ProjectDeclarations, cmd: &CheckSubcommand, source_dir: &Path, target_backend: Option, @@ -1138,7 +1138,7 @@ fn resolve_selected_packages( } fn filter_packages_for_backend( - resolve_output: &moonbuild_rupes_recta::ResolveOutput, + resolve_output: &moonbuild_rupes_recta::ProjectDeclarations, packages: Vec, target_backend: TargetBackend, user_log: &UserLog, @@ -1181,7 +1181,7 @@ fn filter_packages_for_backend( } fn calc_user_intent_from_package_path( - resolve_output: &moonbuild_rupes_recta::ResolveOutput, + resolve_output: &moonbuild_rupes_recta::ProjectDeclarations, source_dir: &Path, filter_path: &Path, target_backend: TargetBackend, @@ -1197,7 +1197,7 @@ fn calc_user_intent_from_package_path( #[instrument(level = Level::DEBUG, skip_all)] fn calc_user_intent( - resolve_output: &moonbuild_rupes_recta::ResolveOutput, + resolve_output: &moonbuild_rupes_recta::ProjectDeclarations, paths: &[PathBuf], target_backend: TargetBackend, patch_file: Option<&Path>, diff --git a/crates/moon/src/cli/doc.rs b/crates/moon/src/cli/doc.rs index 1534eb2032..2790c342ab 100644 --- a/crates/moon/src/cli/doc.rs +++ b/crates/moon/src/cli/doc.rs @@ -212,7 +212,7 @@ pub(crate) fn run_doc_rr( } fn selected_doc_module_id( - resolve_output: &moonbuild_rupes_recta::ResolveOutput, + resolve_output: &moonbuild_rupes_recta::ProjectDeclarations, selected_module_dir: &Path, ) -> anyhow::Result { resolve_output diff --git a/crates/moon/src/cli/info.rs b/crates/moon/src/cli/info.rs index 012da1dde1..414714093f 100644 --- a/crates/moon/src/cli/info.rs +++ b/crates/moon/src/cli/info.rs @@ -24,8 +24,8 @@ use anyhow::bail; use moonbuild::BuildMeta; use moonbuild::execution::BuildInput; use moonbuild_rupes_recta::{ - ResolveConfig, ResolveOutput, intent::UserIntent, model::PackageId, resolve_synced_project, - sync_dependencies, + ProjectDeclarations, ResolveConfig, ResolveOutput, intent::UserIntent, model::PackageId, + resolve_synced_project, sync_dependencies, }; use moonutil::{ build_options::RunMode, @@ -100,7 +100,7 @@ enum SelectionMode { impl PackageSelection { fn new( cmd: &InfoSubcommand, - resolve_output: &ResolveOutput, + resolve_output: &ProjectDeclarations, user_log: &UserLog, ) -> anyhow::Result { let package_ids: Vec<_> = resolve_output @@ -179,7 +179,7 @@ struct InfoIntentContext<'a> { fn calc_user_intent_for_info( ctx: &InfoIntentContext, - resolve_output: &ResolveOutput, + resolve_output: &ProjectDeclarations, target_backend: TargetBackend, ) -> Result { let is_canonical_run = matches!(ctx.target_kind, imp::TargetKind::Canonical); diff --git a/crates/moon/src/cli/info/imp.rs b/crates/moon/src/cli/info/imp.rs index 45fb0f1187..4f65986c9d 100644 --- a/crates/moon/src/cli/info/imp.rs +++ b/crates/moon/src/cli/info/imp.rs @@ -30,7 +30,7 @@ use indexmap::IndexMap; use moonbuild::BuildMeta; use moonbuild::expect::write_diff; use moonbuild_rupes_recta::{ - ResolveOutput, build_plan::ArtifactKey, model::PackageId, pkg_name::PackageFQN, + ProjectDeclarations, build_plan::ArtifactKey, model::PackageId, pkg_name::PackageFQN, }; use moonutil::{constants::MBTI_GENERATED, target::TargetBackend}; use sha2::Digest; @@ -100,7 +100,7 @@ impl<'a> PackageOutputGroup<'a> { } pub(super) fn plan_info_outputs( - resolve_output: &ResolveOutput, + resolve_output: &ProjectDeclarations, packages: impl IntoIterator, ) -> InfoOutputPlan { let mut planned = IndexMap::new(); diff --git a/crates/moon/src/cli/prove.rs b/crates/moon/src/cli/prove.rs index 20e1042109..de27928965 100644 --- a/crates/moon/src/cli/prove.rs +++ b/crates/moon/src/cli/prove.rs @@ -216,7 +216,7 @@ pub(crate) fn run_prove( fn calc_user_intent( path_filter: Option<&Path>, selected_module_dir: Option<&Path>, - resolve_output: &moonbuild_rupes_recta::ResolveOutput, + resolve_output: &moonbuild_rupes_recta::ProjectDeclarations, target_backend: TargetBackend, prove_why3_config: Option<&Path>, proof_prelude: &Path, @@ -297,7 +297,7 @@ fn resolve_proof_prelude() -> anyhow::Result { } fn selected_main_module_id( - resolve_output: &moonbuild_rupes_recta::ResolveOutput, + resolve_output: &moonbuild_rupes_recta::ProjectDeclarations, selected_module_dir: Option<&Path>, ) -> anyhow::Result { if let Some(selected_module_dir) = selected_module_dir { diff --git a/crates/moon/src/cli/run.rs b/crates/moon/src/cli/run.rs index f570a6dc3c..8ba0bd327f 100644 --- a/crates/moon/src/cli/run.rs +++ b/crates/moon/src/cli/run.rs @@ -24,7 +24,7 @@ use anyhow::{Context, bail}; use moonbuild::BuildMeta; use moonbuild::execution::BuildInput; use moonbuild_rupes_recta::{ - ResolveOutput, + ProjectDeclarations, ResolveOutput, build_plan::{ArtifactKey, InputDirective}, intent::UserIntent, model::{BackendConfig, PackageId}, @@ -60,7 +60,7 @@ impl ResolvedRunSelection { fn into_user_intent( self, input_path: &str, - resolve_output: &ResolveOutput, + resolve_output: &ProjectDeclarations, value_tracing: bool, target_backend: TargetBackend, ) -> Result { @@ -696,7 +696,7 @@ fn get_run_executable(build_meta: &BuildMeta) -> &Path { #[instrument(level = Level::DEBUG, skip_all)] fn resolve_run_selection( input_path: &str, - resolve_output: &ResolveOutput, + resolve_output: &ProjectDeclarations, ) -> Result { let (dir, _filename) = crate::filter::canonicalize_with_filename(Path::new(input_path))?; let package = crate::filter::filter_pkg_by_dir(resolve_output, &dir)?; diff --git a/crates/moon/src/cli/test.rs b/crates/moon/src/cli/test.rs index 83053dfbbb..754cd1217c 100644 --- a/crates/moon/src/cli/test.rs +++ b/crates/moon/src/cli/test.rs @@ -75,7 +75,7 @@ enum ResolvedTestSelection { impl ResolvedTestSelection { fn to_runtime_filter( &self, - resolve_output: &moonbuild_rupes_recta::ResolveOutput, + resolve_output: &moonbuild_rupes_recta::ProjectDeclarations, cmd: &TestLikeSubcommand<'_>, ) -> Result { let mut filter = TestFilter { @@ -121,7 +121,7 @@ impl ResolvedTestSelection { fn to_build_intent( &self, - resolve_output: &moonbuild_rupes_recta::ResolveOutput, + resolve_output: &moonbuild_rupes_recta::ProjectDeclarations, cmd: &TestLikeSubcommand<'_>, target_backend: TargetBackend, filter: &TestFilter, @@ -1357,7 +1357,7 @@ fn artifacts_from_target(x: BuildTarget) -> [ArtifactKey; 3] { #[instrument(level = "debug", skip(affected_packages, resolve_output, out_filter))] fn apply_list_of_filters( affected_packages: &[PackageId], - resolve_output: &moonbuild_rupes_recta::ResolveOutput, + resolve_output: &moonbuild_rupes_recta::ProjectDeclarations, package_filter: &[String], file_filter: Option<&str>, index_filter: Option, @@ -1458,7 +1458,7 @@ fn apply_list_of_filters( /// fuzzy matching process is quite complex, we would avoid doing it twice. #[instrument(level = "debug", skip(resolve_output, cmd, out_filter))] fn calc_user_intent( - resolve_output: &moonbuild_rupes_recta::ResolveOutput, + resolve_output: &moonbuild_rupes_recta::ProjectDeclarations, cmd: &TestLikeSubcommand<'_>, out_filter: &mut TestFilter, target_backend: moonutil::target::TargetBackend, @@ -1489,7 +1489,7 @@ fn calc_user_intent( #[allow(clippy::too_many_arguments)] fn calc_user_intent_from_packages( - resolve_output: &moonbuild_rupes_recta::ResolveOutput, + resolve_output: &moonbuild_rupes_recta::ProjectDeclarations, cmd: &TestLikeSubcommand<'_>, out_filter: &mut TestFilter, all_affected_packages: &[PackageId], @@ -1630,7 +1630,7 @@ fn calc_user_intent_from_packages( fn resolve_scoped_test_selection( cmd: &TestLikeSubcommand<'_>, - resolve_output: &moonbuild_rupes_recta::ResolveOutput, + resolve_output: &moonbuild_rupes_recta::ProjectDeclarations, scoped_packages: Vec, ) -> anyhow::Result { if !cmd.explicit_path_filters.is_empty() { @@ -1671,7 +1671,7 @@ fn selected_test_index(cmd: &TestLikeSubcommand<'_>) -> anyhow::Result Vec { packages @@ -1702,7 +1702,7 @@ fn has_explicit_test_selector(cmd: &TestLikeSubcommand<'_>) -> bool { } fn resolve_test_target_selections( - resolve_output: &moonbuild_rupes_recta::ResolveOutput, + resolve_output: &moonbuild_rupes_recta::ProjectDeclarations, cmd: &TestLikeSubcommand<'_>, user_log: &UserLog, ) -> anyhow::Result> { @@ -1723,7 +1723,7 @@ fn resolve_test_target_selections( } fn resolve_selected_test_packages( - resolve_output: &moonbuild_rupes_recta::ResolveOutput, + resolve_output: &moonbuild_rupes_recta::ProjectDeclarations, cmd: &TestLikeSubcommand<'_>, user_log: &UserLog, ) -> anyhow::Result> { @@ -1770,7 +1770,7 @@ fn resolve_selected_test_packages( } fn validate_original_package_selection_filters( - resolve_output: &moonbuild_rupes_recta::ResolveOutput, + resolve_output: &moonbuild_rupes_recta::ProjectDeclarations, cmd: &TestLikeSubcommand<'_>, ) -> anyhow::Result<()> { let Some(package_filter) = cmd.package.as_deref() else { diff --git a/crates/moon/src/cli/tool/build_binary_dep.rs b/crates/moon/src/cli/tool/build_binary_dep.rs index 5a51a2f310..51263e13f8 100644 --- a/crates/moon/src/cli/tool/build_binary_dep.rs +++ b/crates/moon/src/cli/tool/build_binary_dep.rs @@ -202,7 +202,7 @@ pub(crate) fn run_build_binary_dep( } fn get_linkable_pkgs_for_bin_dep( - resolve_output: &moonbuild_rupes_recta::ResolveOutput, + resolve_output: &moonbuild_rupes_recta::ProjectDeclarations, packages: impl Iterator, default_backend: TargetBackend, user_log: &UserLog, diff --git a/crates/moon/src/cli/tree.rs b/crates/moon/src/cli/tree.rs index 787cede5a7..865b13c725 100644 --- a/crates/moon/src/cli/tree.rs +++ b/crates/moon/src/cli/tree.rs @@ -24,7 +24,10 @@ use anyhow::Context; use moonbuild_rupes_recta::{ discover::DiscoverResult, model::{BuildTarget, PackageId, TargetKind}, - resolve::{ResolveConfig, ResolveOutput, resolve_synced_project, sync_dependencies}, + resolve::{ + ProjectDeclarations, ResolveConfig, ResolveOutput, resolve_synced_project, + sync_dependencies, + }, }; use mooncake::pkg::{sync::SyncOutputOptions, tree::ResolvedTree}; use moonutil::{ @@ -592,7 +595,10 @@ fn render_package_tree( out } -fn selected_source_packages(resolve_output: &ResolveOutput, module: ModuleId) -> Vec { +fn selected_source_packages( + resolve_output: &ProjectDeclarations, + module: ModuleId, +) -> Vec { resolve_output .pkg_dirs .packages_for_module(module) diff --git a/crates/moon/src/filter.rs b/crates/moon/src/filter.rs index a4f0b278f9..641eeeec2b 100644 --- a/crates/moon/src/filter.rs +++ b/crates/moon/src/filter.rs @@ -26,7 +26,7 @@ use std::{ }; use anyhow::Context; -use moonbuild_rupes_recta::{ResolveOutput, fmt::FmtResolveOutput, model::PackageId}; +use moonbuild_rupes_recta::{ProjectDeclarations, fmt::FmtResolveOutput, model::PackageId}; use moonutil::resolution::{DirSyncResult, ResolvedEnv}; use moonutil::{ constants::{MOON_PKG, MOON_PKG_JSON, is_moon_pkg_exist}, @@ -136,7 +136,7 @@ where /// Perform fuzzy matching over package names and return the matching package IDs. pub(crate) fn match_packages_by_name_rr( - resolve_output: &ResolveOutput, + resolve_output: &ProjectDeclarations, main_modules: &[moonutil::resolution::ModuleId], needle: &str, user_log: &UserLog, @@ -176,7 +176,7 @@ impl AsNameMap for moonbuild_rupes_recta::discover::DiscoverResult { /// When a package cannot be found, returns a descriptive error that can be /// reported to the user. pub(crate) fn filter_pkg_by_dir( - resolve_output: &ResolveOutput, + resolve_output: &ProjectDeclarations, dir: &Path, ) -> anyhow::Result { let mut all_local_packages = resolve_output.local_modules().iter().flat_map(|&it| { @@ -291,7 +291,7 @@ pub(crate) fn report_package_not_found( } pub(crate) fn format_supported_backends( - resolve_output: &ResolveOutput, + resolve_output: &ProjectDeclarations, pkg_id: PackageId, ) -> String { let pkg = resolve_output.pkg_dirs.get_package(pkg_id); @@ -305,7 +305,7 @@ pub(crate) fn format_supported_backends( } pub(crate) fn package_supports_backend( - resolve_output: &ResolveOutput, + resolve_output: &ProjectDeclarations, pkg_id: PackageId, target_backend: TargetBackend, ) -> bool { @@ -323,7 +323,7 @@ pub(crate) struct TargetPackageGroup { } pub(crate) fn preferred_target_backend_for_package( - resolve_output: &ResolveOutput, + resolve_output: &ProjectDeclarations, pkg_id: PackageId, ) -> TargetBackend { let module_id = resolve_output.pkg_dirs.get_package(pkg_id).module; @@ -334,7 +334,7 @@ pub(crate) fn preferred_target_backend_for_package( } pub(crate) fn group_packages_by_preferred_backend( - resolve_output: &ResolveOutput, + resolve_output: &ProjectDeclarations, packages: impl IntoIterator, ) -> Vec { let mut groups = BTreeMap::>::new(); @@ -355,7 +355,7 @@ pub(crate) fn group_packages_by_preferred_backend( } pub(crate) fn ensure_package_supports_backend( - resolve_output: &ResolveOutput, + resolve_output: &ProjectDeclarations, pkg_id: PackageId, target_backend: TargetBackend, ) -> anyhow::Result<()> { @@ -373,7 +373,7 @@ pub(crate) fn ensure_package_supports_backend( } pub(crate) fn ensure_packages_support_backend( - resolve_output: &ResolveOutput, + resolve_output: &ProjectDeclarations, packages: I, target_backend: TargetBackend, ) -> anyhow::Result<()> @@ -413,7 +413,7 @@ where } pub(crate) fn select_supported_packages( - resolve_output: &ResolveOutput, + resolve_output: &ProjectDeclarations, paths: I, target_backend: TargetBackend, user_log: &UserLog, @@ -473,7 +473,7 @@ pub(crate) struct PackageMatchResult { /// matched by their fully qualified names, preferring exact matches and falling back to fuzzy /// suggestions. Results are deduplicated while preserving the order returned by the matcher. pub(crate) fn match_packages_with_fuzzy( - resolve_output: &ResolveOutput, + resolve_output: &ProjectDeclarations, candidates: impl IntoIterator, names: I, ) -> PackageMatchResult @@ -559,7 +559,9 @@ pub(crate) fn filter_pkg_by_dir_for_fmt( mod tests { use super::select_supported_packages; use log::LevelFilter; - use moonbuild_rupes_recta::ResolveConfig; + use moonbuild_rupes_recta::{ + ProjectDeclarations, ResolveConfig, pkg_solve::SolveError, resolve::ResolveError, + }; use moonutil::{ constants::{MOON_MOD_JSON, MOON_PKG_JSON, MOON_WORK}, project::{SourceTargetDirs, WorkspaceEnv}, @@ -579,7 +581,7 @@ mod tests { dunce::canonicalize(path).unwrap() } - fn resolve_output(source_dir: &Path) -> moonbuild_rupes_recta::ResolveOutput { + fn discover_project(source_dir: &Path) -> ProjectDeclarations { let cfg = ResolveConfig::new_with_load_defaults(false, false, false, WorkspaceEnv::Auto); let user_log = UserLog::new(LevelFilter::Error); let dirs = SourceTargetDirs { @@ -593,7 +595,48 @@ mod tests { .package_dirs() .unwrap(); let synced_env = moonbuild_rupes_recta::sync_dependencies(&cfg, &dirs, &user_log).unwrap(); - moonbuild_rupes_recta::resolve_synced_project(&cfg, synced_env, &user_log).unwrap() + moonbuild_rupes_recta::discover_synced_project(&cfg, synced_env, &user_log).unwrap() + } + + #[test] + fn package_selection_does_not_require_solvable_imports() { + let temp = tempfile::tempdir().unwrap(); + write_file( + &temp.path().join(MOON_MOD_JSON), + r#"{ "name": "test/app" }"#, + ); + write_file( + &temp.path().join("main").join(MOON_PKG_JSON), + r#"{ "is-main": true, "import": ["test/app/missing"] }"#, + ); + + let root = canonical(temp.path()); + let declarations = discover_project(&root); + let user_log = UserLog::new(LevelFilter::Error); + let selected = select_supported_packages( + &declarations, + [root.join("main")], + TargetBackend::default(), + &user_log, + ) + .unwrap(); + assert_eq!(selected.len(), 1); + assert_eq!( + declarations + .pkg_dirs + .get_package(selected[0]) + .fqn + .to_string(), + "test/app/main" + ); + + let ResolveError::SolveError(error) = declarations.resolve(&user_log).unwrap_err() else { + panic!("missing imports must be reported during package solving"); + }; + assert!(matches!( + *error, + SolveError::ImportNotFound { import, .. } if import == "test/app/missing" + )); } #[test] @@ -616,7 +659,7 @@ mod tests { let workspace_root = canonical(workspace_root); let dangling_pkg = workspace_root.join("dangling/pkg"); - let resolved = resolve_output(&workspace_root); + let resolved = discover_project(&workspace_root); assert_eq!( select_supported_packages( @@ -654,7 +697,7 @@ mod tests { let workspace_root = canonical(workspace_root); let external_pkg = canonical(external_module.join("src/main")); - let resolved = resolve_output(&workspace_root); + let resolved = discover_project(&workspace_root); let selected = select_supported_packages( &resolved, [&external_pkg], diff --git a/crates/moon/src/rr_build/mod.rs b/crates/moon/src/rr_build/mod.rs index 827f2d0ddc..d7ee7eaafd 100644 --- a/crates/moon/src/rr_build/mod.rs +++ b/crates/moon/src/rr_build/mod.rs @@ -39,7 +39,7 @@ use moonbuild::{ execution::{BuildInput, resolve_parallelism}, }; use moonbuild_rupes_recta::{ - CompileConfig, ResolveConfig, ResolveOutput, + CompileConfig, ProjectDeclarations, ResolveConfig, ResolveOutput, build_lower::WarningCondition, build_plan::{ArtifactKey, InputDirective}, fmt::{FmtConfig, FmtResolveOutput}, @@ -138,7 +138,7 @@ impl From<(Vec, InputDirective)> for CalcUserIntentOutput { } } -fn warn_local_legacy_supported_targets(resolve_output: &ResolveOutput, user_log: &UserLog) { +fn warn_local_legacy_supported_targets(resolve_output: &ProjectDeclarations, user_log: &UserLog) { let mut warned = BTreeSet::new(); for &module_id in resolve_output.local_modules() { if let Some(pkgs) = resolve_output.pkg_dirs.packages_for_module(module_id) { @@ -159,7 +159,7 @@ fn warn_local_legacy_supported_targets(resolve_output: &ResolveOutput, user_log: } pub(crate) fn local_packages( - resolve_output: &ResolveOutput, + resolve_output: &ProjectDeclarations, ) -> impl Iterator + '_ { resolve_output .local_modules() @@ -174,7 +174,7 @@ pub(crate) fn local_packages( } fn local_modules_preferred_target( - resolve_output: &ResolveOutput, + resolve_output: &ProjectDeclarations, user_log: &UserLog, ) -> Option { let preferred = resolve_output diff --git a/crates/moon/src/watch/prebuild_output.rs b/crates/moon/src/watch/prebuild_output.rs index dc497f7704..3d0cc38511 100644 --- a/crates/moon/src/watch/prebuild_output.rs +++ b/crates/moon/src/watch/prebuild_output.rs @@ -20,7 +20,7 @@ use std::path::{Path, PathBuf}; -use moonbuild_rupes_recta::ResolveOutput; +use moonbuild_rupes_recta::ProjectDeclarations; use moonutil::package::MoonPkgGenerate; pub(crate) struct PrebuildWatchPaths { @@ -29,7 +29,7 @@ pub(crate) struct PrebuildWatchPaths { } /// Generate the list of paths to watch or ignore for pre-builds during watch mode. -pub(crate) fn rr_get_prebuild_watch_paths(env: &ResolveOutput) -> PrebuildWatchPaths { +pub(crate) fn rr_get_prebuild_watch_paths(env: &ProjectDeclarations) -> PrebuildWatchPaths { let mut ignored_paths = vec![]; let mut watched_paths = vec![]; diff --git a/crates/moonbuild-rupes-recta/src/build_lower/mod.rs b/crates/moonbuild-rupes-recta/src/build_lower/mod.rs index 9f877dc606..cc42f73bfe 100644 --- a/crates/moonbuild-rupes-recta/src/build_lower/mod.rs +++ b/crates/moonbuild-rupes-recta/src/build_lower/mod.rs @@ -338,9 +338,12 @@ mod tests { ( ResolveOutput { - module_rel: modules, - module_dirs, - pkg_dirs: packages, + declarations: crate::resolve::ProjectDeclarations { + module_rel: modules, + module_dirs, + pkg_dirs: packages, + enable_coverage: false, + }, pkg_rel: DepRelationship::default(), }, package_id.build_target(TargetKind::Source), diff --git a/crates/moonbuild-rupes-recta/src/compile/mod.rs b/crates/moonbuild-rupes-recta/src/compile/mod.rs index 8fe3ddde9f..c934b194db 100644 --- a/crates/moonbuild-rupes-recta/src/compile/mod.rs +++ b/crates/moonbuild-rupes-recta/src/compile/mod.rs @@ -314,9 +314,12 @@ mod tests { let mut module_dirs = DirSyncResult::default(); module_dirs.insert(module, PathBuf::from(".")); let resolved = ResolveOutput { - module_rel: modules, - module_dirs, - pkg_dirs: packages, + declarations: crate::resolve::ProjectDeclarations { + module_rel: modules, + module_dirs, + pkg_dirs: packages, + enable_coverage: false, + }, pkg_rel: relationship, }; for symbols in [ @@ -528,9 +531,12 @@ mod tests { with_flags, ); let resolved = ResolveOutput { - module_rel: modules, - module_dirs: DirSyncResult::default(), - pkg_dirs: packages, + declarations: crate::resolve::ProjectDeclarations { + module_rel: modules, + module_dirs: DirSyncResult::default(), + pkg_dirs: packages, + enable_coverage: false, + }, pkg_rel: DepRelationship::default(), }; // Empty plans exercise capability forwarding without resolving host tools. @@ -730,9 +736,12 @@ mod tests { module_dirs.insert(dependency_module, PathBuf::from("../dependency")); module_dirs.insert(module, PathBuf::from(".")); let resolved = ResolveOutput { - module_rel: modules, - module_dirs, - pkg_dirs: packages, + declarations: crate::resolve::ProjectDeclarations { + module_rel: modules, + module_dirs, + pkg_dirs: packages, + enable_coverage: false, + }, pkg_rel: relationship, }; let artifact_paths = ArtifactPathResolver::new( @@ -842,9 +851,12 @@ mod tests { let mut module_dirs = DirSyncResult::default(); module_dirs.insert(module, PathBuf::from(".")); let resolved = ResolveOutput { - module_rel: modules, - module_dirs, - pkg_dirs: packages, + declarations: crate::resolve::ProjectDeclarations { + module_rel: modules, + module_dirs, + pkg_dirs: packages, + enable_coverage: false, + }, pkg_rel: DepRelationship::default(), }; let artifact_paths = ArtifactPathResolver::new( diff --git a/crates/moonbuild-rupes-recta/src/lib.rs b/crates/moonbuild-rupes-recta/src/lib.rs index 99ba6073e0..f355085a28 100644 --- a/crates/moonbuild-rupes-recta/src/lib.rs +++ b/crates/moonbuild-rupes-recta/src/lib.rs @@ -26,8 +26,9 @@ - [`resolve`] Builds an in-memory representation of all modules and packages that needs to be used during the compile process, as well as the - dependency relationship between them. This part is always performed - without affected by the user input. + dependency relationship between them. Discovery produces + [`ProjectDeclarations`] for inspecting modules and packages; solving + their imports produces [`ResolveOutput`] for compilation. - [`compile`] takes in the resolved environment and produces an [`execution_plan::ExecutionPlan`]. This part converts the intent of the @@ -122,4 +123,7 @@ pub mod util; // Reexports pub use compile::{CompileConfig, CompileOutput, compile}; -pub use resolve::{ResolveConfig, ResolveOutput, resolve_synced_project, sync_dependencies}; +pub use resolve::{ + ProjectDeclarations, ResolveConfig, ResolveOutput, discover_synced_project, + resolve_synced_project, sync_dependencies, +}; diff --git a/crates/moonbuild-rupes-recta/src/resolve/mod.rs b/crates/moonbuild-rupes-recta/src/resolve/mod.rs index 4ad3927e80..8e1db4987e 100644 --- a/crates/moonbuild-rupes-recta/src/resolve/mod.rs +++ b/crates/moonbuild-rupes-recta/src/resolve/mod.rs @@ -18,12 +18,12 @@ //! High-level abstraction that handles module and package resolving. //! -//! Normal project resolution is split into an explicit dependency sync step and -//! a package discovery/solve step. This keeps dependency-directory mutation -//! visible to command adapters before RR consumes the synced dependencies as -//! input. +//! Normal project resolution has separate dependency sync, package discovery, +//! and package solving steps. Discovery produces [`ProjectDeclarations`]; +//! solving adds the package dependency graph to produce [`ResolveOutput`]. +//! Dependency-directory mutation remains explicit in the sync step. -use std::path::Path; +use std::{ops::Deref, path::Path}; use anyhow::Context; use indexmap::IndexMap; @@ -58,20 +58,54 @@ use crate::{ pkg_solve::{self, DepRelationship}, }; -/// Represents the overall result of a resolve process. +/// Module and package declarations available before solving package dependencies. #[derive(Debug, Clone)] -pub struct ResolveOutput { +pub struct ProjectDeclarations { /// Module dependency relationship pub module_rel: ResolvedEnv, /// Module directories pub module_dirs: DirSyncResult, /// Package directories pub pkg_dirs: DiscoverResult, + /// Keep graph injection consistent with coverage sources added during discovery. + pub(crate) enable_coverage: bool, +} + +/// Project declarations with their resolved package dependency graph. +#[derive(Debug, Clone)] +pub struct ResolveOutput { + pub declarations: ProjectDeclarations, /// Package dependency relationship pub pkg_rel: DepRelationship, } -impl ResolveOutput { +/// A resolved project provides read-only access to its declarations. +impl Deref for ResolveOutput { + type Target = ProjectDeclarations; + + fn deref(&self) -> &Self::Target { + &self.declarations + } +} + +impl ProjectDeclarations { + /// Solve package dependencies, returning a resolved project only if the graph is valid. + #[instrument(skip_all)] + pub fn resolve(self, user_log: &UserLog) -> Result { + let pkg_rel = pkg_solve::solve( + &self.module_rel, + &self.pkg_dirs, + self.enable_coverage, + user_log, + ) + .map_err(|source| ResolveError::SolveError(Box::new(source)))?; + + Ok(ResolveOutput { + declarations: self, + pkg_rel, + }) + } + /// Returns the input/root modules of the current resolve. /// /// This is a role in the current resolution graph, not a check of @@ -352,6 +386,24 @@ pub fn resolve_synced_project( synced_dependencies: (ResolvedEnv, DirSyncResult), user_log: &UserLog, ) -> Result { + let resolved = + discover_synced_project(cfg, synced_dependencies, user_log)?.resolve(user_log)?; + + info!("Package dependency resolution completed successfully"); + debug!( + "Package dependency graph has {} nodes", + resolved.pkg_rel.dep_graph.node_count() + ); + Ok(resolved) +} + +/// Read package declarations from already synced dependencies without solving imports. +#[instrument(skip_all)] +pub fn discover_synced_project( + cfg: &ResolveConfig, + synced_dependencies: (ResolvedEnv, DirSyncResult), + user_log: &UserLog, +) -> Result { let (resolved_env, dir_sync_result) = synced_dependencies; let mut discover_result = discover_packages(&resolved_env, &dir_sync_result, user_log)?; @@ -369,25 +421,11 @@ pub fn resolve_synced_project( discover_result.package_count() ); - let dep_relationship = pkg_solve::solve( - &resolved_env, - &discover_result, - cfg.enable_coverage, - user_log, - ) - .map_err(|source| ResolveError::SolveError(Box::new(source)))?; - - info!("Package dependency resolution completed successfully"); - debug!( - "Package dependency graph has {} nodes", - dep_relationship.dep_graph.node_count() - ); - - Ok(ResolveOutput { + Ok(ProjectDeclarations { module_rel: resolved_env, module_dirs: dir_sync_result, pkg_dirs: discover_result, - pkg_rel: dep_relationship, + enable_coverage: cfg.enable_coverage, }) } @@ -403,6 +441,23 @@ pub fn resolve_single_file_project( run_mode: bool, user_log: &UserLog, ) -> Result<(ResolveOutput, Option), ResolveError> { + let (declarations, backend) = + discover_single_file_project(cfg, dirs, source_file, run_mode, user_log)?; + Ok((declarations.resolve(user_log)?, backend)) +} + +/// Synthesize single-file project declarations and read the preferred backend +/// without solving package dependencies. +/// `source_file` must be the absolute invoked path from +/// `SingleFilePackageDirs::input_path`, preserving a file symlink's own filename. +#[instrument(skip_all, fields(run_mode = run_mode))] +pub fn discover_single_file_project( + cfg: &ResolveConfig, + dirs: &PackageDirs, + source_file: &Path, + run_mode: bool, + user_log: &UserLog, +) -> Result<(ProjectDeclarations, Option), ResolveError> { let source_kind = if source_file.extension().is_some_and(|ext| ext == "mbtx") { SingleFileSourceKind::Mbtx } else if source_file.extension().is_some_and(|ext| ext == "md") { @@ -469,20 +524,11 @@ Use moonbit.import with 'username/module@version[/package]' entries to opt in to front_matter_config.package_imports, )?; - // Solve package dependency relationship - let dep_relationship = pkg_solve::solve( - &resolved_env, - &discover_result, - cfg.enable_coverage, - user_log, - ) - .map_err(|source| ResolveError::SolveError(Box::new(source)))?; - - let res = ResolveOutput { + let res = ProjectDeclarations { module_rel: resolved_env, module_dirs: dir_sync_result, pkg_dirs: discover_result, - pkg_rel: dep_relationship, + enable_coverage: cfg.enable_coverage, }; Ok((res, backend)) } diff --git a/docs/dev/reference/modules-packages.md b/docs/dev/reference/modules-packages.md index b8d207d791..9b68fe7980 100644 --- a/docs/dev/reference/modules-packages.md +++ b/docs/dev/reference/modules-packages.md @@ -213,6 +213,15 @@ structured commands capture them with their other logs. ## Package discovery +Rupes Recta represents discovered modules and packages as `ProjectDeclarations`, +which contains the resolved module graph, module directories, and package +declarations. Package-selection helpers use this data without needing a solved +package graph. `ProjectDeclarations::resolve` validates imports and adds the +single package dependency graph to produce `ResolveOutput`, using the coverage +setting captured during discovery. The project and single-file resolution +entry points still perform both steps before commands select packages and plan +builds, preserving dependency-error ordering. + The `source` field in `moon.mod.json` specifies where package scanning starts, relative to the folder containing `moon.mod.json`. Package paths are the relative path (normalized to forward slash) relative to this root path. From 346936e2952c336e30e58b4fb4b565c00804379d Mon Sep 17 00:00:00 2001 From: Yu Zhang Date: Mon, 21 Sep 2026 15:00:03 +0800 Subject: [PATCH 2/2] refactor: name the discovery result DiscoveredProject --- crates/moon/src/cli/build.rs | 52 ++++---- crates/moon/src/cli/bundle.rs | 4 +- crates/moon/src/cli/check.rs | 68 +++++----- crates/moon/src/cli/doc.rs | 6 +- crates/moon/src/cli/info.rs | 29 +++-- crates/moon/src/cli/info/imp.rs | 9 +- crates/moon/src/cli/prove.rs | 31 ++--- crates/moon/src/cli/run.rs | 17 +-- crates/moon/src/cli/test.rs | 118 ++++++++---------- crates/moon/src/cli/tool/build_binary_dep.rs | 4 +- crates/moon/src/cli/tree.rs | 10 +- crates/moon/src/filter.rs | 104 ++++++++------- crates/moon/src/rr_build/mod.rs | 35 +++--- crates/moon/src/watch/prebuild_output.rs | 10 +- .../src/build_lower/mod.rs | 2 +- .../moonbuild-rupes-recta/src/compile/mod.rs | 8 +- crates/moonbuild-rupes-recta/src/lib.rs | 4 +- .../moonbuild-rupes-recta/src/resolve/mod.rs | 40 +++--- docs/dev/reference/modules-packages.md | 8 +- 19 files changed, 260 insertions(+), 299 deletions(-) diff --git a/crates/moon/src/cli/build.rs b/crates/moon/src/cli/build.rs index b93d57f9c3..b39ced20a6 100644 --- a/crates/moon/src/cli/build.rs +++ b/crates/moon/src/cli/build.rs @@ -618,14 +618,14 @@ fn has_explicit_build_selector(cmd: &BuildSubcommand) -> bool { } fn resolve_build_target_selections( - resolve_output: &moonbuild_rupes_recta::ProjectDeclarations, + discovered: &moonbuild_rupes_recta::DiscoveredProject, cmd: &BuildSubcommand, selected_target_backend: Option, user_log: &UserLog, ) -> anyhow::Result> { if let Some(target_backend) = selected_target_backend { let packages = - resolve_selected_build_packages(resolve_output, cmd, Some(target_backend), user_log)?; + resolve_selected_build_packages(discovered, cmd, Some(target_backend), user_log)?; if packages.is_empty() { return Ok(Vec::new()); } @@ -635,15 +635,15 @@ fn resolve_build_target_selections( }]); } - let selected = resolve_selected_build_packages(resolve_output, cmd, None, user_log)?; - let mut selections = group_packages_by_preferred_backend(resolve_output, selected); + let selected = resolve_selected_build_packages(discovered, cmd, None, user_log)?; + let mut selections = group_packages_by_preferred_backend(discovered, selected); for selection in &mut selections { selection.packages = selection .packages .iter() .copied() - .filter(|&pkg| package_supports_backend(resolve_output, pkg, selection.target_backend)) + .filter(|&pkg| package_supports_backend(discovered, pkg, selection.target_backend)) .collect(); } selections.retain(|selection| !selection.packages.is_empty()); @@ -652,17 +652,17 @@ fn resolve_build_target_selections( } fn resolve_selected_build_packages( - resolve_output: &moonbuild_rupes_recta::ProjectDeclarations, + discovered: &moonbuild_rupes_recta::DiscoveredProject, cmd: &BuildSubcommand, target_backend: Option, user_log: &UserLog, ) -> anyhow::Result> { if !cmd.path.is_empty() { if let Some(target_backend) = target_backend { - return select_supported_packages(resolve_output, &cmd.path, target_backend, user_log); + return select_supported_packages(discovered, &cmd.path, target_backend, user_log); } return Ok(select_packages(&cmd.path, user_log, |dir| { - filter_pkg_by_dir(resolve_output, dir) + filter_pkg_by_dir(discovered, dir) })? .into_iter() .map(|(_, pkg_id)| pkg_id) @@ -671,21 +671,21 @@ fn resolve_selected_build_packages( if let Some(package_filter) = cmd.package.as_deref() { let pkgs = match_packages_by_name_rr( - resolve_output, - resolve_output.local_modules(), + discovered, + discovered.local_modules(), package_filter, user_log, ); if let Some(target_backend) = target_backend { - ensure_packages_support_backend(resolve_output, pkgs.iter().copied(), target_backend)?; + ensure_packages_support_backend(discovered, pkgs.iter().copied(), target_backend)?; } return Ok(pkgs); } - Ok(rr_build::local_packages(resolve_output) + Ok(rr_build::local_packages(discovered) .filter(|&pkg_id| { target_backend - .is_none_or(|backend| package_supports_backend(resolve_output, pkg_id, backend)) + .is_none_or(|backend| package_supports_backend(discovered, pkg_id, backend)) }) .collect()) } @@ -697,13 +697,13 @@ fn resolve_selected_build_packages( fn calc_user_intent( path_filters: &[PathBuf], package_filter: Option<&str>, - resolve_output: &moonbuild_rupes_recta::ProjectDeclarations, + discovered: &moonbuild_rupes_recta::DiscoveredProject, target_backend: TargetBackend, user_log: &UserLog, ) -> Result { if !path_filters.is_empty() { let selected = - select_supported_packages(resolve_output, path_filters, target_backend, user_log)?; + select_supported_packages(discovered, path_filters, target_backend, user_log)?; Ok(selected .into_iter() .map(UserIntent::Build) @@ -711,12 +711,12 @@ fn calc_user_intent( .into()) } else if let Some(package_filter) = package_filter { let pkgs = match_packages_by_name_rr( - resolve_output, - resolve_output.local_modules(), + discovered, + discovered.local_modules(), package_filter, user_log, ); - ensure_packages_support_backend(resolve_output, pkgs.iter().copied(), target_backend)?; + ensure_packages_support_backend(discovered, pkgs.iter().copied(), target_backend)?; Ok(pkgs .into_iter() .map(UserIntent::Build) @@ -724,9 +724,9 @@ fn calc_user_intent( .into()) } else { calc_user_intent_from_scoped_packages( - resolve_output, - &rr_build::local_packages(resolve_output) - .filter(|&pkg_id| package_supports_backend(resolve_output, pkg_id, target_backend)) + discovered, + &rr_build::local_packages(discovered) + .filter(|&pkg_id| package_supports_backend(discovered, pkg_id, target_backend)) .collect::>(), target_backend, ) @@ -734,12 +734,12 @@ fn calc_user_intent( } fn calc_user_intent_from_scoped_packages( - resolve_output: &moonbuild_rupes_recta::ProjectDeclarations, + discovered: &moonbuild_rupes_recta::DiscoveredProject, supported_packages: &[PackageId], target_backend: TargetBackend, ) -> Result { let linkable_pkgs = get_linkable_pkgs( - resolve_output, + discovered, target_backend, supported_packages.iter().copied(), ); @@ -748,7 +748,7 @@ fn calc_user_intent_from_scoped_packages( .iter() .copied() .filter(|&pkg_id| { - let pkg = resolve_output.pkg_dirs.get_package(pkg_id); + let pkg = discovered.pkg_dirs.get_package(pkg_id); !pkg.is_stdlib }) .map(UserIntent::Build) @@ -760,13 +760,13 @@ fn calc_user_intent_from_scoped_packages( } fn get_linkable_pkgs( - resolve_output: &moonbuild_rupes_recta::ProjectDeclarations, + discovered: &moonbuild_rupes_recta::DiscoveredProject, target_backend: TargetBackend, packages: impl Iterator, ) -> Vec { let mut linkable_pkgs = vec![]; for pkg_id in packages { - let pkg = resolve_output.pkg_dirs.get_package(pkg_id); + let pkg = discovered.pkg_dirs.get_package(pkg_id); if pkg.raw.force_link || pkg .raw diff --git a/crates/moon/src/cli/bundle.rs b/crates/moon/src/cli/bundle.rs index a5a924bee4..03dc167cfa 100644 --- a/crates/moon/src/cli/bundle.rs +++ b/crates/moon/src/cli/bundle.rs @@ -247,9 +247,9 @@ pub(crate) fn plan_bundle_rr_from_resolved( } fn bundle_user_intent( - resolve_output: &moonbuild_rupes_recta::ProjectDeclarations, + discovered: &moonbuild_rupes_recta::DiscoveredProject, ) -> CalcUserIntentOutput { - resolve_output + discovered .local_modules() .iter() .map(|&module| UserIntent::Bundle(module)) diff --git a/crates/moon/src/cli/check.rs b/crates/moon/src/cli/check.rs index 75a5fd677f..4e5111784e 100644 --- a/crates/moon/src/cli/check.rs +++ b/crates/moon/src/cli/check.rs @@ -622,12 +622,12 @@ fn run_check_for_single_file_rr( } fn get_user_intents_single_file( - resolve_output: &moonbuild_rupes_recta::ProjectDeclarations, + discovered: &moonbuild_rupes_recta::DiscoveredProject, _backend: TargetBackend, ) -> Result { - let m_packages = resolve_output + let m_packages = discovered .pkg_dirs - .packages_for_module(resolve_output.local_modules()[0]) + .packages_for_module(discovered.local_modules()[0]) .context("single-file project must resolve a local module")?; let pkg = *m_packages .iter() @@ -957,7 +957,7 @@ pub(crate) fn plan_check_rr_from_resolved_all( } fn validate_selector_flags_before_split( - resolve_output: &moonbuild_rupes_recta::ProjectDeclarations, + discovered: &moonbuild_rupes_recta::DiscoveredProject, cmd: &CheckSubcommand, source_dir: &Path, target_backend: Option, @@ -968,7 +968,7 @@ fn validate_selector_flags_before_split( } let selected = - resolve_selected_packages(resolve_output, cmd, source_dir, target_backend, user_log)?; + resolve_selected_packages(discovered, cmd, source_dir, target_backend, user_log)?; if cmd.patch_file.is_some() && selected.len() != 1 { anyhow::bail!("`--patch-file` requires the selector to resolve to a single package"); } @@ -1059,33 +1059,28 @@ fn plan_check_rr_from_selection( } pub(crate) fn resolve_check_target_selections( - resolve_output: &moonbuild_rupes_recta::ProjectDeclarations, + discovered: &moonbuild_rupes_recta::DiscoveredProject, cmd: &CheckSubcommand, source_dir: &Path, selected_target_backend: Option, user_log: &UserLog, ) -> anyhow::Result> { if let Some(target_backend) = selected_target_backend { - let packages = resolve_selected_packages( - resolve_output, - cmd, - source_dir, - Some(target_backend), - user_log, - )?; + let packages = + resolve_selected_packages(discovered, cmd, source_dir, Some(target_backend), user_log)?; return Ok(vec![TargetPackageGroup { target_backend, packages, }]); } - let selected = resolve_selected_packages(resolve_output, cmd, source_dir, None, user_log)?; - let selections = group_packages_by_preferred_backend(resolve_output, selected); + let selected = resolve_selected_packages(discovered, cmd, source_dir, None, user_log)?; + let selections = group_packages_by_preferred_backend(discovered, selected); let mut filtered = Vec::new(); for selection in selections { let packages = filter_packages_for_backend( - resolve_output, + discovered, selection.packages, selection.target_backend, user_log, @@ -1102,7 +1097,7 @@ pub(crate) fn resolve_check_target_selections( } fn resolve_selected_packages( - resolve_output: &moonbuild_rupes_recta::ProjectDeclarations, + discovered: &moonbuild_rupes_recta::DiscoveredProject, cmd: &CheckSubcommand, source_dir: &Path, target_backend: Option, @@ -1110,35 +1105,34 @@ fn resolve_selected_packages( ) -> anyhow::Result> { if let Some(filter_path) = cmd.package_path.as_deref() { let (dir, _) = canonicalize_with_filename(&source_dir.join(filter_path))?; - let pkg = filter_pkg_by_dir(resolve_output, &dir)?; + let pkg = filter_pkg_by_dir(discovered, &dir)?; if let Some(target_backend) = target_backend { - ensure_package_supports_backend(resolve_output, pkg, target_backend)?; + ensure_package_supports_backend(discovered, pkg, target_backend)?; } return Ok(vec![pkg]); } if !cmd.path.is_empty() { if let Some(target_backend) = target_backend { - return select_supported_packages(resolve_output, &cmd.path, target_backend, user_log); + return select_supported_packages(discovered, &cmd.path, target_backend, user_log); } return Ok(select_packages(&cmd.path, user_log, |dir| { - filter_pkg_by_dir(resolve_output, dir) + filter_pkg_by_dir(discovered, dir) })? .into_iter() .map(|(_, pkg_id)| pkg_id) .collect()); } - Ok(rr_build::local_packages(resolve_output) + Ok(rr_build::local_packages(discovered) .filter(|&pkg| { - target_backend - .is_none_or(|backend| package_supports_backend(resolve_output, pkg, backend)) + target_backend.is_none_or(|backend| package_supports_backend(discovered, pkg, backend)) }) .collect()) } fn filter_packages_for_backend( - resolve_output: &moonbuild_rupes_recta::ProjectDeclarations, + discovered: &moonbuild_rupes_recta::DiscoveredProject, packages: Vec, target_backend: TargetBackend, user_log: &UserLog, @@ -1147,7 +1141,7 @@ fn filter_packages_for_backend( let mut unsupported = Vec::new(); for pkg in packages { - if package_supports_backend(resolve_output, pkg, target_backend) { + if package_supports_backend(discovered, pkg, target_backend) { supported.push(pkg); } else { unsupported.push(pkg); @@ -1156,10 +1150,10 @@ fn filter_packages_for_backend( if supported.is_empty() && !unsupported.is_empty() { if let [pkg] = unsupported.as_slice() { - ensure_package_supports_backend(resolve_output, *pkg, target_backend)?; + ensure_package_supports_backend(discovered, *pkg, target_backend)?; } else { ensure_packages_support_backend( - resolve_output, + discovered, unsupported.iter().copied(), target_backend, )?; @@ -1168,12 +1162,12 @@ fn filter_packages_for_backend( for pkg in unsupported { let pkg_id = pkg; - let pkg = resolve_output.pkg_dirs.get_package(pkg_id); + let pkg = discovered.pkg_dirs.get_package(pkg_id); user_log.info(format!( "skipping package `{}` because it does not support the selected target backend `{}`. Supported backends: {}", pkg.fqn, target_backend, - format_supported_backends(resolve_output, pkg_id), + format_supported_backends(discovered, pkg_id), )); } @@ -1181,15 +1175,15 @@ fn filter_packages_for_backend( } fn calc_user_intent_from_package_path( - resolve_output: &moonbuild_rupes_recta::ProjectDeclarations, + discovered: &moonbuild_rupes_recta::DiscoveredProject, source_dir: &Path, filter_path: &Path, target_backend: TargetBackend, patch_file: Option<&Path>, ) -> Result { let (dir, _) = canonicalize_with_filename(&source_dir.join(filter_path))?; - let pkg = filter_pkg_by_dir(resolve_output, &dir)?; - ensure_package_supports_backend(resolve_output, pkg, target_backend)?; + let pkg = filter_pkg_by_dir(discovered, &dir)?; + ensure_package_supports_backend(discovered, pkg, target_backend)?; let directive = rr_build::build_patch_directive_for_package(pkg, false, None, patch_file, false)?; Ok((vec![UserIntent::Check(pkg)], directive).into()) @@ -1197,14 +1191,14 @@ fn calc_user_intent_from_package_path( #[instrument(level = Level::DEBUG, skip_all)] fn calc_user_intent( - resolve_output: &moonbuild_rupes_recta::ProjectDeclarations, + discovered: &moonbuild_rupes_recta::DiscoveredProject, paths: &[PathBuf], target_backend: TargetBackend, patch_file: Option<&Path>, user_log: &UserLog, ) -> Result { if !paths.is_empty() { - let selected = select_supported_packages(resolve_output, paths, target_backend, user_log)?; + let selected = select_supported_packages(discovered, paths, target_backend, user_log)?; let directive = build_directive_for_selected_packages(&selected, patch_file)?; Ok(( selected.into_iter().map(UserIntent::Check).collect(), @@ -1212,8 +1206,8 @@ fn calc_user_intent( ) .into()) } else { - let intents: Vec<_> = rr_build::local_packages(resolve_output) - .filter(|&pkg| package_supports_backend(resolve_output, pkg, target_backend)) + let intents: Vec<_> = rr_build::local_packages(discovered) + .filter(|&pkg| package_supports_backend(discovered, pkg, target_backend)) .map(UserIntent::Check) .collect(); Ok(intents.into()) diff --git a/crates/moon/src/cli/doc.rs b/crates/moon/src/cli/doc.rs index 2790c342ab..31ac7b9738 100644 --- a/crates/moon/src/cli/doc.rs +++ b/crates/moon/src/cli/doc.rs @@ -212,15 +212,15 @@ pub(crate) fn run_doc_rr( } fn selected_doc_module_id( - resolve_output: &moonbuild_rupes_recta::ProjectDeclarations, + discovered: &moonbuild_rupes_recta::DiscoveredProject, selected_module_dir: &Path, ) -> anyhow::Result { - resolve_output + discovered .local_modules() .iter() .copied() .find(|&module_id| { - resolve_output + discovered .module_dirs .get(module_id) .is_some_and(|module_dir| module_dir == selected_module_dir) diff --git a/crates/moon/src/cli/info.rs b/crates/moon/src/cli/info.rs index 414714093f..1c465a3bd0 100644 --- a/crates/moon/src/cli/info.rs +++ b/crates/moon/src/cli/info.rs @@ -24,7 +24,7 @@ use anyhow::bail; use moonbuild::BuildMeta; use moonbuild::execution::BuildInput; use moonbuild_rupes_recta::{ - ProjectDeclarations, ResolveConfig, ResolveOutput, intent::UserIntent, model::PackageId, + DiscoveredProject, ResolveConfig, ResolveOutput, intent::UserIntent, model::PackageId, resolve_synced_project, sync_dependencies, }; use moonutil::{ @@ -100,14 +100,14 @@ enum SelectionMode { impl PackageSelection { fn new( cmd: &InfoSubcommand, - resolve_output: &ProjectDeclarations, + discovered: &DiscoveredProject, user_log: &UserLog, ) -> anyhow::Result { - let package_ids: Vec<_> = resolve_output + let package_ids: Vec<_> = discovered .local_modules() .iter() .flat_map(|&module_id| { - resolve_output + discovered .pkg_dirs .packages_for_module(module_id) .into_iter() @@ -117,7 +117,7 @@ impl PackageSelection { if let [path] = cmd.path.as_slice() { let (dir, _) = canonicalize_with_filename(path)?; - let pkg = filter_pkg_by_dir(resolve_output, &dir)?; + let pkg = filter_pkg_by_dir(discovered, &dir)?; return Ok(Self { mode: SelectionMode::SinglePath, package_ids: vec![pkg], @@ -127,7 +127,7 @@ impl PackageSelection { if !cmd.path.is_empty() { let path_packages = select_packages(&cmd.path, user_log, |dir| { - filter_pkg_by_dir(resolve_output, dir) + filter_pkg_by_dir(discovered, dir) })?; let package_ids = path_packages.iter().map(|(_, pkg_id)| *pkg_id).collect(); return Ok(Self { @@ -139,7 +139,7 @@ impl PackageSelection { if let Some(filter) = cmd.package.as_deref() { let matches = match_packages_with_fuzzy( - resolve_output, + discovered, package_ids.iter().copied(), std::iter::once(filter), ); @@ -179,7 +179,7 @@ struct InfoIntentContext<'a> { fn calc_user_intent_for_info( ctx: &InfoIntentContext, - resolve_output: &ProjectDeclarations, + discovered: &DiscoveredProject, target_backend: TargetBackend, ) -> Result { let is_canonical_run = matches!(ctx.target_kind, imp::TargetKind::Canonical); @@ -188,14 +188,14 @@ fn calc_user_intent_for_info( SelectionMode::SinglePath => { let package = ctx.selection.package_ids[0]; let canonical = ctx.output_plan.canonical_backend_for(&package) == Some(target_backend); - let supported = package_supports_backend(resolve_output, package, target_backend); + let supported = package_supports_backend(discovered, package, target_backend); if (canonical || !is_canonical_run) && supported { vec![UserIntent::Info(package)] } else { ctx.user_log.warn(format!( "Skipping package `{}` for `moon info`: it does not support target backend `{}`", - resolve_output.pkg_dirs.get_package(package).fqn, + discovered.pkg_dirs.get_package(package).fqn, target_backend )); Vec::new() @@ -208,7 +208,7 @@ fn calc_user_intent_for_info( for (path, pkg_id) in &ctx.selection.path_packages { let canonical = ctx.output_plan.canonical_backend_for(pkg_id) == Some(target_backend); - let supported = package_supports_backend(resolve_output, *pkg_id, target_backend); + let supported = package_supports_backend(discovered, *pkg_id, target_backend); let should_include = (canonical || !is_canonical_run) && supported; if should_include { @@ -219,13 +219,13 @@ fn calc_user_intent_for_info( } for (path, pkg_id) in &unsupported { - let pkg = resolve_output.pkg_dirs.get_package(*pkg_id); + let pkg = discovered.pkg_dirs.get_package(*pkg_id); ctx.user_log.info(format!( "skipping path `{}` because package `{}` does not support target backend `{}`. Supported backends: {}", path.display(), pkg.fqn, target_backend, - format_supported_backends(resolve_output, *pkg_id), + format_supported_backends(discovered, *pkg_id), )); } @@ -247,8 +247,7 @@ fn calc_user_intent_for_info( .filter(|&pkg_id| { let canonical = ctx.output_plan.canonical_backend_for(&pkg_id) == Some(target_backend); - let supported = - package_supports_backend(resolve_output, pkg_id, target_backend); + let supported = package_supports_backend(discovered, pkg_id, target_backend); (canonical || !is_canonical_run) && supported }) .collect(); diff --git a/crates/moon/src/cli/info/imp.rs b/crates/moon/src/cli/info/imp.rs index 4f65986c9d..808087c8dc 100644 --- a/crates/moon/src/cli/info/imp.rs +++ b/crates/moon/src/cli/info/imp.rs @@ -30,7 +30,7 @@ use indexmap::IndexMap; use moonbuild::BuildMeta; use moonbuild::expect::write_diff; use moonbuild_rupes_recta::{ - ProjectDeclarations, build_plan::ArtifactKey, model::PackageId, pkg_name::PackageFQN, + DiscoveredProject, build_plan::ArtifactKey, model::PackageId, pkg_name::PackageFQN, }; use moonutil::{constants::MBTI_GENERATED, target::TargetBackend}; use sha2::Digest; @@ -100,16 +100,15 @@ impl<'a> PackageOutputGroup<'a> { } pub(super) fn plan_info_outputs( - resolve_output: &ProjectDeclarations, + discovered: &DiscoveredProject, packages: impl IntoIterator, ) -> InfoOutputPlan { let mut planned = IndexMap::new(); for package_id in packages { planned.entry(package_id).or_insert_with(|| { - let pkg = resolve_output.pkg_dirs.get_package(package_id); - let canonical_backend = - preferred_target_backend_for_package(resolve_output, package_id); + let pkg = discovered.pkg_dirs.get_package(package_id); + let canonical_backend = preferred_target_backend_for_package(discovered, package_id); PackageOutputPlan::new_from_fqn( &pkg.fqn, diff --git a/crates/moon/src/cli/prove.rs b/crates/moon/src/cli/prove.rs index de27928965..f67577fb22 100644 --- a/crates/moon/src/cli/prove.rs +++ b/crates/moon/src/cli/prove.rs @@ -216,7 +216,7 @@ pub(crate) fn run_prove( fn calc_user_intent( path_filter: Option<&Path>, selected_module_dir: Option<&Path>, - resolve_output: &moonbuild_rupes_recta::ProjectDeclarations, + discovered: &moonbuild_rupes_recta::DiscoveredProject, target_backend: TargetBackend, prove_why3_config: Option<&Path>, proof_prelude: &Path, @@ -230,9 +230,9 @@ fn calc_user_intent( if let Some(path) = path_filter { let (dir, _) = canonicalize_with_filename(path)?; - let pkg = filter_pkg_by_dir(resolve_output, &dir)?; - ensure_package_supports_backend(resolve_output, pkg, target_backend)?; - let pkg_info = resolve_output.pkg_dirs.get_package(pkg); + let pkg = filter_pkg_by_dir(discovered, &dir)?; + ensure_package_supports_backend(discovered, pkg, target_backend)?; + let pkg_info = discovered.pkg_dirs.get_package(pkg); let intents = pkg_info .raw .proof_enabled @@ -248,22 +248,17 @@ fn calc_user_intent( } Ok(CalcUserIntentOutput::new(intents, directive)) } else { - let main_module_id = selected_main_module_id(resolve_output, selected_module_dir)?; - let packages = resolve_output + let main_module_id = selected_main_module_id(discovered, selected_module_dir)?; + let packages = discovered .pkg_dirs .packages_for_module(main_module_id) .ok_or_else(|| anyhow::anyhow!("Cannot find the local module!"))?; let intents = packages .values() .copied() - .filter(|&pkg| package_supports_backend(resolve_output, pkg, target_backend)) - .filter(|&pkg| resolve_output.pkg_dirs.get_package(pkg).raw.proof_enabled) - .filter(|&pkg| { - resolve_output - .pkg_dirs - .get_package(pkg) - .has_implementation() - }) + .filter(|&pkg| package_supports_backend(discovered, pkg, target_backend)) + .filter(|&pkg| discovered.pkg_dirs.get_package(pkg).raw.proof_enabled) + .filter(|&pkg| discovered.pkg_dirs.get_package(pkg).has_implementation()) .map(UserIntent::Prove) .collect::>(); Ok((intents, directive).into()) @@ -297,16 +292,16 @@ fn resolve_proof_prelude() -> anyhow::Result { } fn selected_main_module_id( - resolve_output: &moonbuild_rupes_recta::ProjectDeclarations, + discovered: &moonbuild_rupes_recta::DiscoveredProject, selected_module_dir: Option<&Path>, ) -> anyhow::Result { if let Some(selected_module_dir) = selected_module_dir { - return resolve_output + return discovered .local_modules() .iter() .copied() .find(|&module_id| { - resolve_output + discovered .module_dirs .get(module_id) .is_some_and(|module_dir| module_dir == selected_module_dir) @@ -319,7 +314,7 @@ fn selected_main_module_id( }); } - match resolve_output.local_modules() { + match discovered.local_modules() { &[main_module_id] => Ok(main_module_id), _ => bail!("No multiple main modules are supported"), } diff --git a/crates/moon/src/cli/run.rs b/crates/moon/src/cli/run.rs index 8ba0bd327f..03802481f0 100644 --- a/crates/moon/src/cli/run.rs +++ b/crates/moon/src/cli/run.rs @@ -24,7 +24,7 @@ use anyhow::{Context, bail}; use moonbuild::BuildMeta; use moonbuild::execution::BuildInput; use moonbuild_rupes_recta::{ - ProjectDeclarations, ResolveOutput, + DiscoveredProject, ResolveOutput, build_plan::{ArtifactKey, InputDirective}, intent::UserIntent, model::{BackendConfig, PackageId}, @@ -60,19 +60,14 @@ impl ResolvedRunSelection { fn into_user_intent( self, input_path: &str, - resolve_output: &ProjectDeclarations, + discovered: &DiscoveredProject, value_tracing: bool, target_backend: TargetBackend, ) -> Result { - if !resolve_output - .pkg_dirs - .get_package(self.package) - .raw - .is_main - { + if !discovered.pkg_dirs.get_package(self.package).raw.is_main { bail!("`{}` is not a main package", input_path); } - ensure_package_supports_backend(resolve_output, self.package, target_backend)?; + ensure_package_supports_backend(discovered, self.package, target_backend)?; let directive = if value_tracing { InputDirective { @@ -696,10 +691,10 @@ fn get_run_executable(build_meta: &BuildMeta) -> &Path { #[instrument(level = Level::DEBUG, skip_all)] fn resolve_run_selection( input_path: &str, - resolve_output: &ProjectDeclarations, + discovered: &DiscoveredProject, ) -> Result { let (dir, _filename) = crate::filter::canonicalize_with_filename(Path::new(input_path))?; - let package = crate::filter::filter_pkg_by_dir(resolve_output, &dir)?; + let package = crate::filter::filter_pkg_by_dir(discovered, &dir)?; Ok(ResolvedRunSelection { package }) } diff --git a/crates/moon/src/cli/test.rs b/crates/moon/src/cli/test.rs index 754cd1217c..05361c9675 100644 --- a/crates/moon/src/cli/test.rs +++ b/crates/moon/src/cli/test.rs @@ -75,7 +75,7 @@ enum ResolvedTestSelection { impl ResolvedTestSelection { fn to_runtime_filter( &self, - resolve_output: &moonbuild_rupes_recta::ProjectDeclarations, + discovered: &moonbuild_rupes_recta::DiscoveredProject, cmd: &TestLikeSubcommand<'_>, ) -> Result { let mut filter = TestFilter { @@ -96,7 +96,7 @@ impl ResolvedTestSelection { if cmd.file.is_some() || cmd.index.is_some() || cmd.doc_index.is_some() { bail!( "Cannot filter by file or index when multiple packages are specified. Matched packages: {:?}", - package_names(resolve_output, packages) + package_names(discovered, packages) ); } for &pkg_id in packages { @@ -121,7 +121,7 @@ impl ResolvedTestSelection { fn to_build_intent( &self, - resolve_output: &moonbuild_rupes_recta::ProjectDeclarations, + discovered: &moonbuild_rupes_recta::DiscoveredProject, cmd: &TestLikeSubcommand<'_>, target_backend: TargetBackend, filter: &TestFilter, @@ -137,7 +137,7 @@ impl ResolvedTestSelection { let directive = match self { ResolvedTestSelection::Packages { packages } => { ensure_packages_support_backend( - resolve_output, + discovered, packages.iter().copied(), target_backend, )?; @@ -159,7 +159,7 @@ impl ResolvedTestSelection { if cmd.patch_file.is_some() && packages.len() > 1 { bail!( "Cannot apply patch file when multiple packages are specified. Matched packages: {:?}", - package_names(resolve_output, packages) + package_names(discovered, packages) ); } InputDirective::default() @@ -1354,10 +1354,10 @@ fn artifacts_from_target(x: BuildTarget) -> [ArtifactKey; 3] { /// Apply the hierarchy of filters of packages, file and index #[allow(clippy::too_many_arguments)] -#[instrument(level = "debug", skip(affected_packages, resolve_output, out_filter))] +#[instrument(level = "debug", skip(affected_packages, discovered, out_filter))] fn apply_list_of_filters( affected_packages: &[PackageId], - resolve_output: &moonbuild_rupes_recta::ProjectDeclarations, + discovered: &moonbuild_rupes_recta::DiscoveredProject, package_filter: &[String], file_filter: Option<&str>, index_filter: Option, @@ -1369,13 +1369,13 @@ fn apply_list_of_filters( user_log: &UserLog, ) -> Result { let package_matches = match_packages_with_fuzzy( - resolve_output, + discovered, affected_packages.iter().copied(), package_filter, ); let filtered_package_ids = package_matches.matched; ensure_packages_support_backend( - resolve_output, + discovered, filtered_package_ids.iter().copied(), target_backend, )?; @@ -1416,7 +1416,7 @@ fn apply_list_of_filters( let package_names = || { filtered_package_ids .iter() - .map(|id| resolve_output.pkg_dirs.get_package(*id).fqn.to_string()) + .map(|id| discovered.pkg_dirs.get_package(*id).fqn.to_string()) .collect::>() }; // Multiple filtered package, check if file/index filtering is applied @@ -1456,19 +1456,19 @@ fn apply_list_of_filters( /// both the test filter and user intent wants the same `BuildTarget` list, but /// the earliest time we can get them is during intent calculation. Since the /// fuzzy matching process is quite complex, we would avoid doing it twice. -#[instrument(level = "debug", skip(resolve_output, cmd, out_filter))] +#[instrument(level = "debug", skip(discovered, cmd, out_filter))] fn calc_user_intent( - resolve_output: &moonbuild_rupes_recta::ProjectDeclarations, + discovered: &moonbuild_rupes_recta::DiscoveredProject, cmd: &TestLikeSubcommand<'_>, out_filter: &mut TestFilter, target_backend: moonutil::target::TargetBackend, user_log: &UserLog, ) -> Result { - let all_affected_packages: Vec<_> = resolve_output + let all_affected_packages: Vec<_> = discovered .local_modules() .iter() .flat_map(|&module_id| { - resolve_output + discovered .pkg_dirs .packages_for_module(module_id) .into_iter() @@ -1476,7 +1476,7 @@ fn calc_user_intent( }) .collect(); calc_user_intent_from_packages( - resolve_output, + discovered, cmd, out_filter, &all_affected_packages, @@ -1489,7 +1489,7 @@ fn calc_user_intent( #[allow(clippy::too_many_arguments)] fn calc_user_intent_from_packages( - resolve_output: &moonbuild_rupes_recta::ProjectDeclarations, + discovered: &moonbuild_rupes_recta::DiscoveredProject, cmd: &TestLikeSubcommand<'_>, out_filter: &mut TestFilter, all_affected_packages: &[PackageId], @@ -1500,13 +1500,13 @@ fn calc_user_intent_from_packages( ) -> Result { debug!( package_count = all_affected_packages.len(), - module_count = resolve_output.local_modules().len(), + module_count = discovered.local_modules().len(), "calculating user intent for workspace" ); let backend_affected_packages = all_affected_packages .iter() .copied() - .filter(|&pkg_id| package_supports_backend(resolve_output, pkg_id, target_backend)) + .filter(|&pkg_id| package_supports_backend(discovered, pkg_id, target_backend)) .collect::>(); let directive = if !explicit_path_filters.is_empty() { @@ -1520,10 +1520,10 @@ fn calc_user_intent_from_packages( if let [path] = explicit_path_filters { let (dir, filename) = canonicalize_with_filename(path)?; - let pkg = filter_pkg_by_dir(resolve_output, &dir)?; + let pkg = filter_pkg_by_dir(discovered, &dir)?; - if !package_supports_backend(resolve_output, pkg, target_backend) { - ensure_packages_support_backend(resolve_output, [pkg], target_backend)?; + if !package_supports_backend(discovered, pkg, target_backend) { + ensure_packages_support_backend(discovered, [pkg], target_backend)?; } out_filter.add_autodetermine_target(pkg, filename.as_deref(), test_index); @@ -1536,7 +1536,7 @@ fn calc_user_intent_from_packages( let (dir, filename) = canonicalize_with_filename(path)?; debug!(dir = %dir.display(), filename = ?filename, "resolved explicit path filter"); - let Ok(pkg) = filter_pkg_by_dir(resolve_output, &dir) else { + let Ok(pkg) = filter_pkg_by_dir(discovered, &dir) else { user_log.info(format!( "skipping path `{}` because it is not a package in the current work context.", path.display() @@ -1544,7 +1544,7 @@ fn calc_user_intent_from_packages( continue; }; - if !package_supports_backend(resolve_output, pkg, target_backend) { + if !package_supports_backend(discovered, pkg, target_backend) { unsupported_paths.push((path, pkg)); continue; } @@ -1560,21 +1560,17 @@ fn calc_user_intent_from_packages( unsupported_packages.push(*pkg_id); } } - ensure_packages_support_backend( - resolve_output, - unsupported_packages, - target_backend, - )?; + ensure_packages_support_backend(discovered, unsupported_packages, target_backend)?; } for (path, pkg_id) in unsupported_paths { - let pkg = resolve_output.pkg_dirs.get_package(pkg_id); + let pkg = discovered.pkg_dirs.get_package(pkg_id); user_log.info(format!( "skipping path `{}` because package `{}` does not support target backend `{}`. Supported backends: {}", path.display(), pkg.fqn, target_backend, - format_supported_backends(resolve_output, pkg_id), + format_supported_backends(discovered, pkg_id), )); } @@ -1585,7 +1581,7 @@ fn calc_user_intent_from_packages( let value_tracing = cmd.build_flags.enable_value_tracing; apply_list_of_filters( all_affected_packages, - resolve_output, + discovered, package_filter, cmd.file.as_deref(), *cmd.index, @@ -1630,7 +1626,7 @@ fn calc_user_intent_from_packages( fn resolve_scoped_test_selection( cmd: &TestLikeSubcommand<'_>, - resolve_output: &moonbuild_rupes_recta::ProjectDeclarations, + discovered: &moonbuild_rupes_recta::DiscoveredProject, scoped_packages: Vec, ) -> anyhow::Result { if !cmd.explicit_path_filters.is_empty() { @@ -1639,7 +1635,7 @@ fn resolve_scoped_test_selection( let Ok((dir, filename)) = canonicalize_with_filename(path) else { continue; }; - let Ok(package) = filter_pkg_by_dir(resolve_output, &dir) else { + let Ok(package) = filter_pkg_by_dir(discovered, &dir) else { continue; }; if scoped_packages.contains(&package) { @@ -1671,12 +1667,12 @@ fn selected_test_index(cmd: &TestLikeSubcommand<'_>) -> anyhow::Result Vec { packages .iter() - .map(|id| resolve_output.pkg_dirs.get_package(*id).fqn.to_string()) + .map(|id| discovered.pkg_dirs.get_package(*id).fqn.to_string()) .collect() } @@ -1702,19 +1698,19 @@ fn has_explicit_test_selector(cmd: &TestLikeSubcommand<'_>) -> bool { } fn resolve_test_target_selections( - resolve_output: &moonbuild_rupes_recta::ProjectDeclarations, + discovered: &moonbuild_rupes_recta::DiscoveredProject, cmd: &TestLikeSubcommand<'_>, user_log: &UserLog, ) -> anyhow::Result> { - let selected = resolve_selected_test_packages(resolve_output, cmd, user_log)?; - let mut selections = group_packages_by_preferred_backend(resolve_output, selected); + let selected = resolve_selected_test_packages(discovered, cmd, user_log)?; + let mut selections = group_packages_by_preferred_backend(discovered, selected); for selection in &mut selections { selection.packages = selection .packages .iter() .copied() - .filter(|&pkg| package_supports_backend(resolve_output, pkg, selection.target_backend)) + .filter(|&pkg| package_supports_backend(discovered, pkg, selection.target_backend)) .collect(); } selections.retain(|selection| !selection.packages.is_empty()); @@ -1723,13 +1719,13 @@ fn resolve_test_target_selections( } fn resolve_selected_test_packages( - resolve_output: &moonbuild_rupes_recta::ProjectDeclarations, + discovered: &moonbuild_rupes_recta::DiscoveredProject, cmd: &TestLikeSubcommand<'_>, user_log: &UserLog, ) -> anyhow::Result> { if !cmd.explicit_path_filters.is_empty() { return Ok(select_packages(cmd.explicit_path_filters, user_log, |dir| { - filter_pkg_by_dir(resolve_output, dir) + filter_pkg_by_dir(discovered, dir) })? .into_iter() .map(|(_, pkg_id)| pkg_id) @@ -1737,30 +1733,27 @@ fn resolve_selected_test_packages( } if let Some(package_filter) = cmd.package.as_deref() { - let all_affected_packages: Vec<_> = resolve_output + let all_affected_packages: Vec<_> = discovered .local_modules() .iter() .flat_map(|&module_id| { - resolve_output + discovered .pkg_dirs .packages_for_module(module_id) .into_iter() .flat_map(|packages| packages.values().copied()) }) .collect(); - return Ok(match_packages_with_fuzzy( - resolve_output, - all_affected_packages, - package_filter, - ) - .matched); + return Ok( + match_packages_with_fuzzy(discovered, all_affected_packages, package_filter).matched, + ); } - Ok(resolve_output + Ok(discovered .local_modules() .iter() .flat_map(|&module_id| { - resolve_output + discovered .pkg_dirs .packages_for_module(module_id) .into_iter() @@ -1770,7 +1763,7 @@ fn resolve_selected_test_packages( } fn validate_original_package_selection_filters( - resolve_output: &moonbuild_rupes_recta::ProjectDeclarations, + discovered: &moonbuild_rupes_recta::DiscoveredProject, cmd: &TestLikeSubcommand<'_>, ) -> anyhow::Result<()> { let Some(package_filter) = cmd.package.as_deref() else { @@ -1786,17 +1779,14 @@ fn validate_original_package_selection_filters( } let matched_packages = match_packages_with_fuzzy( - resolve_output, - resolve_output - .local_modules() - .iter() - .flat_map(|&module_id| { - resolve_output - .pkg_dirs - .packages_for_module(module_id) - .into_iter() - .flat_map(|packages| packages.values().copied()) - }), + discovered, + discovered.local_modules().iter().flat_map(|&module_id| { + discovered + .pkg_dirs + .packages_for_module(module_id) + .into_iter() + .flat_map(|packages| packages.values().copied()) + }), package_filter, ) .matched; @@ -1808,7 +1798,7 @@ fn validate_original_package_selection_filters( let package_names = || { matched_packages .iter() - .map(|id| resolve_output.pkg_dirs.get_package(*id).fqn.to_string()) + .map(|id| discovered.pkg_dirs.get_package(*id).fqn.to_string()) .collect::>() }; diff --git a/crates/moon/src/cli/tool/build_binary_dep.rs b/crates/moon/src/cli/tool/build_binary_dep.rs index 51263e13f8..996755af37 100644 --- a/crates/moon/src/cli/tool/build_binary_dep.rs +++ b/crates/moon/src/cli/tool/build_binary_dep.rs @@ -202,14 +202,14 @@ pub(crate) fn run_build_binary_dep( } fn get_linkable_pkgs_for_bin_dep( - resolve_output: &moonbuild_rupes_recta::ProjectDeclarations, + discovered: &moonbuild_rupes_recta::DiscoveredProject, packages: impl Iterator, default_backend: TargetBackend, user_log: &UserLog, ) -> Vec<(PackageId, TargetBackend)> { let mut linkable_pkgs = vec![]; for pkg_id in packages { - let pkg = resolve_output.pkg_dirs.get_package(pkg_id); + let pkg = discovered.pkg_dirs.get_package(pkg_id); let pkg_bin_target = pkg.raw.bin_target.unwrap_or(default_backend); add_bin_dep(&mut linkable_pkgs, pkg_id, pkg, pkg_bin_target, user_log); diff --git a/crates/moon/src/cli/tree.rs b/crates/moon/src/cli/tree.rs index 865b13c725..971291bebc 100644 --- a/crates/moon/src/cli/tree.rs +++ b/crates/moon/src/cli/tree.rs @@ -25,8 +25,7 @@ use moonbuild_rupes_recta::{ discover::DiscoverResult, model::{BuildTarget, PackageId, TargetKind}, resolve::{ - ProjectDeclarations, ResolveConfig, ResolveOutput, resolve_synced_project, - sync_dependencies, + DiscoveredProject, ResolveConfig, ResolveOutput, resolve_synced_project, sync_dependencies, }, }; use mooncake::pkg::{sync::SyncOutputOptions, tree::ResolvedTree}; @@ -595,11 +594,8 @@ fn render_package_tree( out } -fn selected_source_packages( - resolve_output: &ProjectDeclarations, - module: ModuleId, -) -> Vec { - resolve_output +fn selected_source_packages(discovered: &DiscoveredProject, module: ModuleId) -> Vec { + discovered .pkg_dirs .packages_for_module(module) .into_iter() diff --git a/crates/moon/src/filter.rs b/crates/moon/src/filter.rs index 641eeeec2b..3460738d25 100644 --- a/crates/moon/src/filter.rs +++ b/crates/moon/src/filter.rs @@ -26,7 +26,7 @@ use std::{ }; use anyhow::Context; -use moonbuild_rupes_recta::{ProjectDeclarations, fmt::FmtResolveOutput, model::PackageId}; +use moonbuild_rupes_recta::{DiscoveredProject, fmt::FmtResolveOutput, model::PackageId}; use moonutil::resolution::{DirSyncResult, ResolvedEnv}; use moonutil::{ constants::{MOON_PKG, MOON_PKG_JSON, is_moon_pkg_exist}, @@ -136,7 +136,7 @@ where /// Perform fuzzy matching over package names and return the matching package IDs. pub(crate) fn match_packages_by_name_rr( - resolve_output: &ProjectDeclarations, + discovered: &DiscoveredProject, main_modules: &[moonutil::resolution::ModuleId], needle: &str, user_log: &UserLog, @@ -145,11 +145,11 @@ pub(crate) fn match_packages_by_name_rr( panic!("No multiple main modules are supported"); }; - let res = fuzzy_match_by_name(needle, &resolve_output.pkg_dirs); + let res = fuzzy_match_by_name(needle, &discovered.pkg_dirs); // Warn about non-local packages being matched for &pkg_id in &res { - let pkg = resolve_output.pkg_dirs.get_package(pkg_id); + let pkg = discovered.pkg_dirs.get_package(pkg_id); if pkg.module != main_module_id { user_log.warn(format!( "Package '{}' matched by name '{}' is not in the main module, it may not be accessible.", @@ -176,11 +176,11 @@ impl AsNameMap for moonbuild_rupes_recta::discover::DiscoverResult { /// When a package cannot be found, returns a descriptive error that can be /// reported to the user. pub(crate) fn filter_pkg_by_dir( - resolve_output: &ProjectDeclarations, + discovered: &DiscoveredProject, dir: &Path, ) -> anyhow::Result { - let mut all_local_packages = resolve_output.local_modules().iter().flat_map(|&it| { - resolve_output + let mut all_local_packages = discovered.local_modules().iter().flat_map(|&it| { + discovered .pkg_dirs .packages_for_module(it) .into_iter() @@ -189,15 +189,15 @@ pub(crate) fn filter_pkg_by_dir( all_local_packages .find(|&pkg_id| { - let pkg = resolve_output.pkg_dirs.get_package(pkg_id); + let pkg = discovered.pkg_dirs.get_package(pkg_id); pkg.root_path == dir }) .ok_or_else(|| { report_package_not_found( dir, - &resolve_output.module_rel, - &resolve_output.module_dirs, - resolve_output.local_modules(), + &discovered.module_rel, + &discovered.module_dirs, + discovered.local_modules(), ) }) } @@ -291,10 +291,10 @@ pub(crate) fn report_package_not_found( } pub(crate) fn format_supported_backends( - resolve_output: &ProjectDeclarations, + discovered: &DiscoveredProject, pkg_id: PackageId, ) -> String { - let pkg = resolve_output.pkg_dirs.get_package(pkg_id); + let pkg = discovered.pkg_dirs.get_package(pkg_id); let mut targets = pkg .effective_supported_targets .iter() @@ -305,11 +305,11 @@ pub(crate) fn format_supported_backends( } pub(crate) fn package_supports_backend( - resolve_output: &ProjectDeclarations, + discovered: &DiscoveredProject, pkg_id: PackageId, target_backend: TargetBackend, ) -> bool { - resolve_output + discovered .pkg_dirs .get_package(pkg_id) .effective_supported_targets @@ -323,24 +323,24 @@ pub(crate) struct TargetPackageGroup { } pub(crate) fn preferred_target_backend_for_package( - resolve_output: &ProjectDeclarations, + discovered: &DiscoveredProject, pkg_id: PackageId, ) -> TargetBackend { - let module_id = resolve_output.pkg_dirs.get_package(pkg_id).module; - resolve_output + let module_id = discovered.pkg_dirs.get_package(pkg_id).module; + discovered .module_info(module_id) .preferred_target .unwrap_or_default() } pub(crate) fn group_packages_by_preferred_backend( - resolve_output: &ProjectDeclarations, + discovered: &DiscoveredProject, packages: impl IntoIterator, ) -> Vec { let mut groups = BTreeMap::>::new(); for pkg_id in packages { groups - .entry(preferred_target_backend_for_package(resolve_output, pkg_id)) + .entry(preferred_target_backend_for_package(discovered, pkg_id)) .or_default() .push(pkg_id); } @@ -355,25 +355,25 @@ pub(crate) fn group_packages_by_preferred_backend( } pub(crate) fn ensure_package_supports_backend( - resolve_output: &ProjectDeclarations, + discovered: &DiscoveredProject, pkg_id: PackageId, target_backend: TargetBackend, ) -> anyhow::Result<()> { - if package_supports_backend(resolve_output, pkg_id, target_backend) { + if package_supports_backend(discovered, pkg_id, target_backend) { return Ok(()); } - let pkg = resolve_output.pkg_dirs.get_package(pkg_id); + let pkg = discovered.pkg_dirs.get_package(pkg_id); anyhow::bail!( "Package '{}' does not support target backend '{}'. Supported backends: {}", pkg.fqn, target_backend, - format_supported_backends(resolve_output, pkg_id), + format_supported_backends(discovered, pkg_id), ); } pub(crate) fn ensure_packages_support_backend( - resolve_output: &ProjectDeclarations, + discovered: &DiscoveredProject, packages: I, target_backend: TargetBackend, ) -> anyhow::Result<()> @@ -383,7 +383,7 @@ where let mut unsupported = Vec::new(); for pkg_id in packages { - if !package_supports_backend(resolve_output, pkg_id, target_backend) { + if !package_supports_backend(discovered, pkg_id, target_backend) { unsupported.push(pkg_id); } } @@ -395,11 +395,11 @@ where let details = unsupported .iter() .map(|&pkg_id| { - let pkg = resolve_output.pkg_dirs.get_package(pkg_id); + let pkg = discovered.pkg_dirs.get_package(pkg_id); format!( "{} ({})", pkg.fqn, - format_supported_backends(resolve_output, pkg_id) + format_supported_backends(discovered, pkg_id) ) }) .collect::>() @@ -413,7 +413,7 @@ where } pub(crate) fn select_supported_packages( - resolve_output: &ProjectDeclarations, + discovered: &DiscoveredProject, paths: I, target_backend: TargetBackend, user_log: &UserLog, @@ -425,10 +425,10 @@ where let mut selected = Vec::new(); let mut unsupported = Vec::new(); - for (path, pkg_id) in select_packages(paths, user_log, |dir| { - filter_pkg_by_dir(resolve_output, dir) - })? { - if package_supports_backend(resolve_output, pkg_id, target_backend) { + for (path, pkg_id) in + select_packages(paths, user_log, |dir| filter_pkg_by_dir(discovered, dir))? + { + if package_supports_backend(discovered, pkg_id, target_backend) { selected.push(pkg_id); } else { unsupported.push((path.to_path_buf(), pkg_id)); @@ -437,10 +437,10 @@ where if selected.is_empty() && !unsupported.is_empty() { if let [(_, pkg_id)] = unsupported.as_slice() { - ensure_package_supports_backend(resolve_output, *pkg_id, target_backend)?; + ensure_package_supports_backend(discovered, *pkg_id, target_backend)?; } else { ensure_packages_support_backend( - resolve_output, + discovered, unsupported.iter().map(|(_, pkg_id)| *pkg_id), target_backend, )?; @@ -448,13 +448,13 @@ where } for (path, pkg_id) in &unsupported { - let pkg = resolve_output.pkg_dirs.get_package(*pkg_id); + let pkg = discovered.pkg_dirs.get_package(*pkg_id); user_log.info(format!( "skipping path `{}` because package `{}` does not support target backend `{}`. Supported backends: {}", path.display(), pkg.fqn, target_backend, - format_supported_backends(resolve_output, *pkg_id), + format_supported_backends(discovered, *pkg_id), )); } @@ -473,7 +473,7 @@ pub(crate) struct PackageMatchResult { /// matched by their fully qualified names, preferring exact matches and falling back to fuzzy /// suggestions. Results are deduplicated while preserving the order returned by the matcher. pub(crate) fn match_packages_with_fuzzy( - resolve_output: &ProjectDeclarations, + discovered: &DiscoveredProject, candidates: impl IntoIterator, names: I, ) -> PackageMatchResult @@ -483,7 +483,7 @@ where { let mut name_map = BTreeMap::new(); for pkg_id in candidates { - let pkg = resolve_output.pkg_dirs.get_package(pkg_id); + let pkg = discovered.pkg_dirs.get_package(pkg_id); name_map.insert(pkg.fqn.to_string(), pkg_id); } @@ -560,7 +560,7 @@ mod tests { use super::select_supported_packages; use log::LevelFilter; use moonbuild_rupes_recta::{ - ProjectDeclarations, ResolveConfig, pkg_solve::SolveError, resolve::ResolveError, + DiscoveredProject, ResolveConfig, pkg_solve::SolveError, resolve::ResolveError, }; use moonutil::{ constants::{MOON_MOD_JSON, MOON_PKG_JSON, MOON_WORK}, @@ -581,7 +581,7 @@ mod tests { dunce::canonicalize(path).unwrap() } - fn discover_project(source_dir: &Path) -> ProjectDeclarations { + fn discover_project(source_dir: &Path) -> DiscoveredProject { let cfg = ResolveConfig::new_with_load_defaults(false, false, false, WorkspaceEnv::Auto); let user_log = UserLog::new(LevelFilter::Error); let dirs = SourceTargetDirs { @@ -611,10 +611,10 @@ mod tests { ); let root = canonical(temp.path()); - let declarations = discover_project(&root); + let discovered = discover_project(&root); let user_log = UserLog::new(LevelFilter::Error); let selected = select_supported_packages( - &declarations, + &discovered, [root.join("main")], TargetBackend::default(), &user_log, @@ -622,15 +622,11 @@ mod tests { .unwrap(); assert_eq!(selected.len(), 1); assert_eq!( - declarations - .pkg_dirs - .get_package(selected[0]) - .fqn - .to_string(), + discovered.pkg_dirs.get_package(selected[0]).fqn.to_string(), "test/app/main" ); - let ResolveError::SolveError(error) = declarations.resolve(&user_log).unwrap_err() else { + let ResolveError::SolveError(error) = discovered.resolve(&user_log).unwrap_err() else { panic!("missing imports must be reported during package solving"); }; assert!(matches!( @@ -659,11 +655,11 @@ mod tests { let workspace_root = canonical(workspace_root); let dangling_pkg = workspace_root.join("dangling/pkg"); - let resolved = discover_project(&workspace_root); + let discovered = discover_project(&workspace_root); assert_eq!( select_supported_packages( - &resolved, + &discovered, [&dangling_pkg], TargetBackend::default(), &UserLog::new(LevelFilter::Warn), @@ -697,9 +693,9 @@ mod tests { let workspace_root = canonical(workspace_root); let external_pkg = canonical(external_module.join("src/main")); - let resolved = discover_project(&workspace_root); + let discovered = discover_project(&workspace_root); let selected = select_supported_packages( - &resolved, + &discovered, [&external_pkg], TargetBackend::default(), &UserLog::new(LevelFilter::Warn), @@ -708,7 +704,7 @@ mod tests { assert_eq!(selected.len(), 1); assert_eq!( - resolved.pkg_dirs.get_package(selected[0]).root_path, + discovered.pkg_dirs.get_package(selected[0]).root_path, external_pkg ); } diff --git a/crates/moon/src/rr_build/mod.rs b/crates/moon/src/rr_build/mod.rs index d7ee7eaafd..c8a49ba501 100644 --- a/crates/moon/src/rr_build/mod.rs +++ b/crates/moon/src/rr_build/mod.rs @@ -39,7 +39,7 @@ use moonbuild::{ execution::{BuildInput, resolve_parallelism}, }; use moonbuild_rupes_recta::{ - CompileConfig, ProjectDeclarations, ResolveConfig, ResolveOutput, + CompileConfig, DiscoveredProject, ResolveConfig, ResolveOutput, build_lower::WarningCondition, build_plan::{ArtifactKey, InputDirective}, fmt::{FmtConfig, FmtResolveOutput}, @@ -138,15 +138,15 @@ impl From<(Vec, InputDirective)> for CalcUserIntentOutput { } } -fn warn_local_legacy_supported_targets(resolve_output: &ProjectDeclarations, user_log: &UserLog) { +fn warn_local_legacy_supported_targets(discovered: &DiscoveredProject, user_log: &UserLog) { let mut warned = BTreeSet::new(); - for &module_id in resolve_output.local_modules() { - if let Some(pkgs) = resolve_output.pkg_dirs.packages_for_module(module_id) { + for &module_id in discovered.local_modules() { + if let Some(pkgs) = discovered.pkg_dirs.packages_for_module(module_id) { for &pkg_id in pkgs.values() { if !warned.insert(pkg_id) { continue; } - let pkg = resolve_output.pkg_dirs.get_package(pkg_id); + let pkg = discovered.pkg_dirs.get_package(pkg_id); if pkg.supported_targets_decl == SupportedTargetsDeclKind::LegacyArray { user_log.warn(format!( "Package `{}` uses legacy array syntax for `supported_targets`; use expression syntax like `` instead", @@ -159,28 +159,25 @@ fn warn_local_legacy_supported_targets(resolve_output: &ProjectDeclarations, use } pub(crate) fn local_packages( - resolve_output: &ProjectDeclarations, + discovered: &DiscoveredProject, ) -> impl Iterator + '_ { - resolve_output - .local_modules() - .iter() - .flat_map(|&module_id| { - resolve_output - .pkg_dirs - .packages_for_module(module_id) - .into_iter() - .flat_map(|packages| packages.values().copied()) - }) + discovered.local_modules().iter().flat_map(|&module_id| { + discovered + .pkg_dirs + .packages_for_module(module_id) + .into_iter() + .flat_map(|packages| packages.values().copied()) + }) } fn local_modules_preferred_target( - resolve_output: &ProjectDeclarations, + discovered: &DiscoveredProject, user_log: &UserLog, ) -> Option { - let preferred = resolve_output + let preferred = discovered .local_modules() .iter() - .filter_map(|&module_id| resolve_output.module_info(module_id).preferred_target) + .filter_map(|&module_id| discovered.module_info(module_id).preferred_target) .collect::>(); if preferred.len() > 1 { diff --git a/crates/moon/src/watch/prebuild_output.rs b/crates/moon/src/watch/prebuild_output.rs index 3d0cc38511..ff405ad37c 100644 --- a/crates/moon/src/watch/prebuild_output.rs +++ b/crates/moon/src/watch/prebuild_output.rs @@ -20,7 +20,7 @@ use std::path::{Path, PathBuf}; -use moonbuild_rupes_recta::ProjectDeclarations; +use moonbuild_rupes_recta::DiscoveredProject; use moonutil::package::MoonPkgGenerate; pub(crate) struct PrebuildWatchPaths { @@ -29,16 +29,16 @@ pub(crate) struct PrebuildWatchPaths { } /// Generate the list of paths to watch or ignore for pre-builds during watch mode. -pub(crate) fn rr_get_prebuild_watch_paths(env: &ProjectDeclarations) -> PrebuildWatchPaths { +pub(crate) fn rr_get_prebuild_watch_paths(discovered: &DiscoveredProject) -> PrebuildWatchPaths { let mut ignored_paths = vec![]; let mut watched_paths = vec![]; - for &m in env.local_modules() { - let Some(packages) = env.pkg_dirs.packages_for_module(m) else { + for &m in discovered.local_modules() { + let Some(packages) = discovered.pkg_dirs.packages_for_module(m) else { continue; }; for &pkg_id in packages.values() { - let pkg = env.pkg_dirs.get_package(pkg_id); + let pkg = discovered.pkg_dirs.get_package(pkg_id); if let Some(prebuild) = pkg.raw.pre_build.as_ref() { push_prebuild_paths( &mut ignored_paths, diff --git a/crates/moonbuild-rupes-recta/src/build_lower/mod.rs b/crates/moonbuild-rupes-recta/src/build_lower/mod.rs index cc42f73bfe..7c6168f6cb 100644 --- a/crates/moonbuild-rupes-recta/src/build_lower/mod.rs +++ b/crates/moonbuild-rupes-recta/src/build_lower/mod.rs @@ -338,7 +338,7 @@ mod tests { ( ResolveOutput { - declarations: crate::resolve::ProjectDeclarations { + discovered: crate::resolve::DiscoveredProject { module_rel: modules, module_dirs, pkg_dirs: packages, diff --git a/crates/moonbuild-rupes-recta/src/compile/mod.rs b/crates/moonbuild-rupes-recta/src/compile/mod.rs index c934b194db..57a5eb39cc 100644 --- a/crates/moonbuild-rupes-recta/src/compile/mod.rs +++ b/crates/moonbuild-rupes-recta/src/compile/mod.rs @@ -314,7 +314,7 @@ mod tests { let mut module_dirs = DirSyncResult::default(); module_dirs.insert(module, PathBuf::from(".")); let resolved = ResolveOutput { - declarations: crate::resolve::ProjectDeclarations { + discovered: crate::resolve::DiscoveredProject { module_rel: modules, module_dirs, pkg_dirs: packages, @@ -531,7 +531,7 @@ mod tests { with_flags, ); let resolved = ResolveOutput { - declarations: crate::resolve::ProjectDeclarations { + discovered: crate::resolve::DiscoveredProject { module_rel: modules, module_dirs: DirSyncResult::default(), pkg_dirs: packages, @@ -736,7 +736,7 @@ mod tests { module_dirs.insert(dependency_module, PathBuf::from("../dependency")); module_dirs.insert(module, PathBuf::from(".")); let resolved = ResolveOutput { - declarations: crate::resolve::ProjectDeclarations { + discovered: crate::resolve::DiscoveredProject { module_rel: modules, module_dirs, pkg_dirs: packages, @@ -851,7 +851,7 @@ mod tests { let mut module_dirs = DirSyncResult::default(); module_dirs.insert(module, PathBuf::from(".")); let resolved = ResolveOutput { - declarations: crate::resolve::ProjectDeclarations { + discovered: crate::resolve::DiscoveredProject { module_rel: modules, module_dirs, pkg_dirs: packages, diff --git a/crates/moonbuild-rupes-recta/src/lib.rs b/crates/moonbuild-rupes-recta/src/lib.rs index f355085a28..bca2705e2e 100644 --- a/crates/moonbuild-rupes-recta/src/lib.rs +++ b/crates/moonbuild-rupes-recta/src/lib.rs @@ -27,7 +27,7 @@ - [`resolve`] Builds an in-memory representation of all modules and packages that needs to be used during the compile process, as well as the dependency relationship between them. Discovery produces - [`ProjectDeclarations`] for inspecting modules and packages; solving + [`DiscoveredProject`] for inspecting modules and packages; solving their imports produces [`ResolveOutput`] for compilation. - [`compile`] takes in the resolved environment and produces an @@ -124,6 +124,6 @@ pub mod util; // Reexports pub use compile::{CompileConfig, CompileOutput, compile}; pub use resolve::{ - ProjectDeclarations, ResolveConfig, ResolveOutput, discover_synced_project, + DiscoveredProject, ResolveConfig, ResolveOutput, discover_synced_project, resolve_synced_project, sync_dependencies, }; diff --git a/crates/moonbuild-rupes-recta/src/resolve/mod.rs b/crates/moonbuild-rupes-recta/src/resolve/mod.rs index 8e1db4987e..8a25fc68fe 100644 --- a/crates/moonbuild-rupes-recta/src/resolve/mod.rs +++ b/crates/moonbuild-rupes-recta/src/resolve/mod.rs @@ -19,7 +19,7 @@ //! High-level abstraction that handles module and package resolving. //! //! Normal project resolution has separate dependency sync, package discovery, -//! and package solving steps. Discovery produces [`ProjectDeclarations`]; +//! and package solving steps. Discovery produces [`DiscoveredProject`]; //! solving adds the package dependency graph to produce [`ResolveOutput`]. //! Dependency-directory mutation remains explicit in the sync step. @@ -58,9 +58,9 @@ use crate::{ pkg_solve::{self, DepRelationship}, }; -/// Module and package declarations available before solving package dependencies. +/// A project's modules and packages before solving package dependencies. #[derive(Debug, Clone)] -pub struct ProjectDeclarations { +pub struct DiscoveredProject { /// Module dependency relationship pub module_rel: ResolvedEnv, /// Module directories @@ -71,24 +71,24 @@ pub struct ProjectDeclarations { pub(crate) enable_coverage: bool, } -/// Project declarations with their resolved package dependency graph. +/// A discovered project with its resolved package dependency graph. #[derive(Debug, Clone)] pub struct ResolveOutput { - pub declarations: ProjectDeclarations, + pub discovered: DiscoveredProject, /// Package dependency relationship pub pkg_rel: DepRelationship, } -/// A resolved project provides read-only access to its declarations. +/// A resolved project provides read-only access to its modules and packages. impl Deref for ResolveOutput { - type Target = ProjectDeclarations; + type Target = DiscoveredProject; fn deref(&self) -> &Self::Target { - &self.declarations + &self.discovered } } -impl ProjectDeclarations { +impl DiscoveredProject { /// Solve package dependencies, returning a resolved project only if the graph is valid. #[instrument(skip_all)] pub fn resolve(self, user_log: &UserLog) -> Result { @@ -101,12 +101,12 @@ impl ProjectDeclarations { .map_err(|source| ResolveError::SolveError(Box::new(source)))?; Ok(ResolveOutput { - declarations: self, + discovered: self, pkg_rel, }) } - /// Returns the input/root modules of the current resolve. + /// Returns the input/root modules of the project. /// /// This is a role in the current resolution graph, not a check of /// `ModuleSourceKind::Local`. @@ -397,13 +397,13 @@ pub fn resolve_synced_project( Ok(resolved) } -/// Read package declarations from already synced dependencies without solving imports. +/// Discover packages from already synced dependencies without solving imports. #[instrument(skip_all)] pub fn discover_synced_project( cfg: &ResolveConfig, synced_dependencies: (ResolvedEnv, DirSyncResult), user_log: &UserLog, -) -> Result { +) -> Result { let (resolved_env, dir_sync_result) = synced_dependencies; let mut discover_result = discover_packages(&resolved_env, &dir_sync_result, user_log)?; @@ -421,7 +421,7 @@ pub fn discover_synced_project( discover_result.package_count() ); - Ok(ProjectDeclarations { + Ok(DiscoveredProject { module_rel: resolved_env, module_dirs: dir_sync_result, pkg_dirs: discover_result, @@ -441,12 +441,12 @@ pub fn resolve_single_file_project( run_mode: bool, user_log: &UserLog, ) -> Result<(ResolveOutput, Option), ResolveError> { - let (declarations, backend) = + let (discovered, backend) = discover_single_file_project(cfg, dirs, source_file, run_mode, user_log)?; - Ok((declarations.resolve(user_log)?, backend)) + Ok((discovered.resolve(user_log)?, backend)) } -/// Synthesize single-file project declarations and read the preferred backend +/// Discover a single-file project and read its preferred backend /// without solving package dependencies. /// `source_file` must be the absolute invoked path from /// `SingleFilePackageDirs::input_path`, preserving a file symlink's own filename. @@ -457,7 +457,7 @@ pub fn discover_single_file_project( source_file: &Path, run_mode: bool, user_log: &UserLog, -) -> Result<(ProjectDeclarations, Option), ResolveError> { +) -> Result<(DiscoveredProject, Option), ResolveError> { let source_kind = if source_file.extension().is_some_and(|ext| ext == "mbtx") { SingleFileSourceKind::Mbtx } else if source_file.extension().is_some_and(|ext| ext == "md") { @@ -524,11 +524,11 @@ Use moonbit.import with 'username/module@version[/package]' entries to opt in to front_matter_config.package_imports, )?; - let res = ProjectDeclarations { + let discovered = DiscoveredProject { module_rel: resolved_env, module_dirs: dir_sync_result, pkg_dirs: discover_result, enable_coverage: cfg.enable_coverage, }; - Ok((res, backend)) + Ok((discovered, backend)) } diff --git a/docs/dev/reference/modules-packages.md b/docs/dev/reference/modules-packages.md index 9b68fe7980..48cff13c36 100644 --- a/docs/dev/reference/modules-packages.md +++ b/docs/dev/reference/modules-packages.md @@ -213,10 +213,10 @@ structured commands capture them with their other logs. ## Package discovery -Rupes Recta represents discovered modules and packages as `ProjectDeclarations`, -which contains the resolved module graph, module directories, and package -declarations. Package-selection helpers use this data without needing a solved -package graph. `ProjectDeclarations::resolve` validates imports and adds the +Rupes Recta represents discovered modules and packages as `DiscoveredProject`, +which contains the resolved module graph, module directories, and the package-level +`DiscoverResult`. Package-selection helpers use this data without needing a +solved package graph. `DiscoveredProject::resolve` validates imports and adds the single package dependency graph to produce `ResolveOutput`, using the coverage setting captured during discovery. The project and single-file resolution entry points still perform both steps before commands select packages and plan