Skip to main content

compose_lens/resolution/
mod.rs

1//! Explicit project paths, references, and default decisions.
2
3mod defaults;
4mod paths;
5mod references;
6
7pub use defaults::{
8    AppliedDefault, ComposeDefaults, ContainerPlatform, DefaultKind, DefaultLocation, DefaultProvider, DefaultRequest,
9    DefaultResolution, DefaultValue, NoDefaults, resolve_defaults,
10};
11pub use paths::{
12    HOME_DIRECTORY_REQUIRED, HostPathKind, PathContext, PathPurpose, PathResolution, ResolvedHostPath, resolve_paths,
13};
14pub use references::{
15    DISABLED_DEPENDENCY_HEALTHCHECK, INACTIVE_SERVICE_REFERENCE, MISSING_REFERENCE, Reference, ReferenceKind,
16    ReferenceStatus, ReferenceValidation, UNVERIFIED_DEPENDENCY_HEALTHCHECK, validate_references,
17};
18
19use crate::diagnostic::{Diagnostic, DiagnosticCode, Severity};
20use crate::merge::{MergedEntry, MergedProject, MergedValue};
21use crate::profiles::ProfileSelection;
22use crate::source::{SourceId, SourceSpan};
23
24/// A profile selection was created from another merged project.
25pub const SELECTION_PROJECT_MISMATCH: DiagnosticCode =
26    DiagnosticCode::new("compose.resolution.selection-project-mismatch");
27
28pub(crate) fn selection_matches(
29    project: &MergedProject,
30    selection: Option<&ProfileSelection>,
31    diagnostics: &mut Vec<Diagnostic>,
32) -> bool {
33    if selection.is_none_or(|selection| selection.belongs_to(project)) {
34        return true;
35    }
36    diagnostics.push(Diagnostic::new(
37        SELECTION_PROJECT_MISMATCH,
38        Severity::Error,
39        "profile selection does not belong to the merged project",
40    ));
41    false
42}
43
44pub(crate) fn service_entries(project: &MergedProject) -> &[MergedEntry] {
45    project
46        .root()
47        .get("services")
48        .and_then(MergedValue::as_mapping)
49        .unwrap_or_default()
50}
51
52pub(crate) fn service_in_scope(selection: Option<&ProfileSelection>, name: &str) -> bool {
53    selection.is_none_or(|selection| selection.is_active(name))
54}
55
56pub(crate) fn effective_span(value: &MergedValue) -> SourceSpan {
57    value
58        .provenance()
59        .effective_source()
60        .or_else(|| value.provenance().sources().first().copied())
61        .unwrap_or_else(|| SourceSpan::from_valid_offsets(SourceId::new(0), 0, 0))
62}
63
64pub(crate) fn entry_span(entry: &MergedEntry) -> SourceSpan {
65    entry
66        .key_sources()
67        .last()
68        .copied()
69        .or_else(|| entry.key_sources().first().copied())
70        .unwrap_or_else(|| SourceSpan::from_valid_offsets(SourceId::new(0), 0, 0))
71}