Skip to main content

isoloom_render/container/
project_files.rs

1//! The project files Compose reads from its own environment: a container's file from the project
2//! with an owner or a mode (outside Swarm, Compose ignores both for a `file` config), copied in
3//! from a variable whoever starts Compose sets first (the runner, a Docker host's start
4//! script).
5
6use isoloom_plan::{Environment, MachineShape};
7use isoloom_spec::model::MachineFile;
8use isoloom_spec::shell::quote;
9
10/// The variable of Compose's own environment holding machine `machine`'s `n`th file, when it
11/// is a project file with an owner or a mode (`ISOLOOM_FILE_WEB_1`). Machine names are
12/// kebab-case, so two files never share one.
13#[must_use]
14pub fn variable(machine: &str, n: usize) -> String {
15    format!("ISOLOOM_FILE_{}_{n}", machine.to_ascii_uppercase().replace('-', "_"))
16}
17
18/// Whether file `f` is copied in from Compose's environment: a project file the spec gives an
19/// owner or a mode.
20#[must_use]
21pub fn copied_from_project(f: &MachineFile) -> bool {
22    f.source.is_some() && f.sets_owner_or_mode()
23}
24
25/// The project files Compose reads from its own environment, as (variable, path in the
26/// project).
27#[must_use]
28pub fn project_variables(env: &Environment) -> Vec<(String, String)> {
29    env.machines
30        .iter()
31        .filter(|(_, mp)| mp.shape == MachineShape::Container)
32        .flat_map(|(machine, mp)| {
33            mp.files
34                .iter()
35                .enumerate()
36                .filter(|(_, f)| copied_from_project(f))
37                .filter_map(move |(n, f)| Some((variable(machine, n), f.source.clone()?)))
38        })
39        .collect()
40}
41
42/// On a Docker host, in the project's folder before `docker compose up`: each project file with
43/// an owner or a mode read into its variable, its last line breaks kept, as commands joined by
44/// `&&` (ending with one). Nothing when there are none.
45#[must_use]
46pub fn host_environment(env: &Environment) -> String {
47    project_variables(env)
48        .into_iter()
49        .map(|(var, path)| format!("{var}=\"$(cat {}; printf x)\" && {var}=\"${{{var}%x}}\" && export {var} && ", quote(&path)))
50        .collect::<Vec<_>>()
51        .concat()
52}