Skip to main content

compose_lens/resolution/
mod.rs

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