mirror of
https://codeberg.org/icewind/haze.git
synced 2026-06-03 09:04:12 +02:00
248 lines
7 KiB
Rust
248 lines
7 KiB
Rust
use crate::config::{HazeConfig, HazeVolumeConfig};
|
|
use camino::{Utf8Path, Utf8PathBuf};
|
|
use miette::{IntoDiagnostic, Result};
|
|
use std::borrow::Cow;
|
|
use tokio::fs::{create_dir_all, write};
|
|
|
|
#[derive(Debug)]
|
|
pub struct Mapping<'a> {
|
|
source_type: MappingSourceType,
|
|
pub source: Cow<'a, Utf8Path>,
|
|
pub target: Cow<'a, Utf8Path>,
|
|
mapping_type: MappingType,
|
|
read_only: bool,
|
|
map: bool,
|
|
create: bool,
|
|
}
|
|
|
|
impl<'a> Mapping<'a> {
|
|
pub fn new<Source, Target>(
|
|
source_type: MappingSourceType,
|
|
source: Source,
|
|
target: Target,
|
|
) -> Self
|
|
where
|
|
Target: Into<&'a Utf8Path>,
|
|
Source: Into<&'a Utf8Path>,
|
|
{
|
|
Mapping {
|
|
source_type,
|
|
source: Cow::Borrowed(source.into()),
|
|
target: Cow::Borrowed(target.into()),
|
|
mapping_type: MappingType::Folder,
|
|
read_only: false,
|
|
map: true,
|
|
create: true,
|
|
}
|
|
}
|
|
|
|
pub fn owned<Source, Target>(
|
|
source_type: MappingSourceType,
|
|
source: Source,
|
|
target: Target,
|
|
) -> Self
|
|
where
|
|
Target: Into<Cow<'a, Utf8Path>>,
|
|
Source: Into<Cow<'a, Utf8Path>>,
|
|
{
|
|
Mapping {
|
|
source_type,
|
|
source: source.into(),
|
|
target: target.into(),
|
|
mapping_type: MappingType::Folder,
|
|
read_only: false,
|
|
map: true,
|
|
create: true,
|
|
}
|
|
}
|
|
|
|
pub fn read_only(self) -> Self {
|
|
Self {
|
|
read_only: true,
|
|
..self
|
|
}
|
|
}
|
|
|
|
pub fn dont_map(self) -> Self {
|
|
Self { map: false, ..self }
|
|
}
|
|
|
|
pub fn dont_create(self) -> Self {
|
|
Self {
|
|
create: false,
|
|
..self
|
|
}
|
|
}
|
|
|
|
pub fn file(self) -> Self {
|
|
Self {
|
|
mapping_type: MappingType::File,
|
|
..self
|
|
}
|
|
}
|
|
|
|
pub async fn create(&self, id: &str, config: &HazeConfig) -> Result<()> {
|
|
if !self.create {
|
|
return Ok(());
|
|
}
|
|
let source = match self.source_type {
|
|
MappingSourceType::WorkDir => config.work_dir.join(id).join(self.source.as_ref()),
|
|
MappingSourceType::GlobalWorkDir => config.work_dir.join(self.source.as_ref()),
|
|
MappingSourceType::Sources => return Ok(()),
|
|
MappingSourceType::Absolute => self.source.as_ref().into(),
|
|
};
|
|
match self.mapping_type {
|
|
MappingType::Folder => create_dir_all(source).await.into_diagnostic()?,
|
|
MappingType::File => write(source, "").await.into_diagnostic()?,
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
pub fn source(&self, id: &str, config: &HazeConfig, source_root: &Utf8Path) -> Utf8PathBuf {
|
|
match self.source_type {
|
|
MappingSourceType::WorkDir => config.work_dir.join(id).join(self.source.as_ref()),
|
|
MappingSourceType::GlobalWorkDir => config.work_dir.join(self.source.as_ref()),
|
|
MappingSourceType::Sources => source_root.join(self.source.as_ref()),
|
|
MappingSourceType::Absolute => self.source.as_ref().into(),
|
|
}
|
|
}
|
|
|
|
pub fn get_volume_arg(
|
|
&self,
|
|
id: &str,
|
|
config: &HazeConfig,
|
|
source_root: &Utf8Path,
|
|
) -> Option<String> {
|
|
if !self.map {
|
|
return None;
|
|
}
|
|
let source = self.source(id, config, source_root);
|
|
Some(if self.read_only {
|
|
format!("{}:{}:ro", source, self.target)
|
|
} else {
|
|
format!("{}:{}", source, self.target)
|
|
})
|
|
}
|
|
}
|
|
|
|
pub fn default_mappings<'a>() -> impl IntoIterator<Item = Mapping<'a>> {
|
|
use MappingSourceType::*;
|
|
|
|
let mappings = [
|
|
Mapping::new(Sources, "", "/var/www/html"),
|
|
Mapping::new(WorkDir, "data", "/var/www/html/data"),
|
|
Mapping::new(WorkDir, "config", "/var/www/html/config"),
|
|
Mapping::new(WorkDir, "store_app", "/var/www/html/store_app"),
|
|
Mapping::new(WorkDir, "data-autotest", "/var/www/html/data-autotest"),
|
|
Mapping::new(WorkDir, "skeleton", "/var/www/html/core/skeleton"),
|
|
Mapping::new(
|
|
Sources,
|
|
"core/skeleton/welcome.txt",
|
|
"/var/www/html/core/skeleton/welcome.txt",
|
|
)
|
|
.file()
|
|
.read_only()
|
|
.dont_create(),
|
|
Mapping::new(
|
|
WorkDir,
|
|
"integration/vendor",
|
|
"/var/www/html/build/integration/vendor",
|
|
),
|
|
Mapping::new(
|
|
WorkDir,
|
|
"integration/work",
|
|
"/var/www/html/build/integration/work",
|
|
),
|
|
Mapping::new(
|
|
WorkDir,
|
|
"integration/output",
|
|
"/var/www/html/build/integration/output",
|
|
),
|
|
Mapping::new(
|
|
WorkDir,
|
|
"integration/composer.lock",
|
|
"/var/www/html/build/integration/composer.lock",
|
|
)
|
|
.file(),
|
|
Mapping::new(
|
|
GlobalWorkDir,
|
|
"composer/cache",
|
|
"/home/haze/.composer/cache",
|
|
),
|
|
Mapping::new(GlobalWorkDir, "node_modules", "/var/www/html/node_modules"),
|
|
Mapping::new(
|
|
GlobalWorkDir,
|
|
"phpunit-cache",
|
|
"/var/www/html/tests/.phpunit.result.cache",
|
|
)
|
|
.file(),
|
|
Mapping::new(WorkDir, "config/CAN_INSTALL", "")
|
|
.file()
|
|
.dont_map(),
|
|
Mapping::new(Sources, ".htaccess", "/var/www/html/.htaccess")
|
|
.file()
|
|
.read_only(),
|
|
Mapping::new(Absolute, "/var/run/docker.sock", "/var/run/docker.sock")
|
|
.file()
|
|
.dont_create(),
|
|
Mapping::new(WorkDir, "xdebug", "/tmp/xdebug"),
|
|
Mapping::new(WorkDir, "profiling", "/tmp/profiling"),
|
|
Mapping::new(WorkDir, "php-config", "/config"),
|
|
];
|
|
|
|
IntoIterator::into_iter(mappings)
|
|
}
|
|
|
|
pub fn for_config<'a>(config: &'a HazeConfig) -> impl Iterator<Item = Mapping<'a>> {
|
|
let app_dir_mappings = config.app_directories.iter().map(|dir| {
|
|
Mapping::owned(
|
|
MappingSourceType::Absolute,
|
|
dir.as_path(),
|
|
Cow::Owned(Utf8PathBuf::from(format!(
|
|
"/var/www/html/{}",
|
|
dir.file_name().unwrap()
|
|
))),
|
|
)
|
|
});
|
|
|
|
config
|
|
.volume
|
|
.iter()
|
|
.map(Mapping::from)
|
|
.chain(app_dir_mappings)
|
|
.chain(default_mappings())
|
|
}
|
|
|
|
#[derive(Debug, Copy, Clone)]
|
|
pub enum MappingSourceType {
|
|
Sources,
|
|
WorkDir,
|
|
GlobalWorkDir,
|
|
Absolute,
|
|
}
|
|
|
|
#[derive(Debug, Copy, Clone)]
|
|
pub enum MappingType {
|
|
Folder,
|
|
File,
|
|
}
|
|
|
|
impl<'a> From<&'a HazeVolumeConfig> for Mapping<'a> {
|
|
fn from(config: &'a HazeVolumeConfig) -> Self {
|
|
let ty = if config.source.is_dir() {
|
|
MappingType::Folder
|
|
} else {
|
|
MappingType::File
|
|
};
|
|
Mapping {
|
|
source_type: MappingSourceType::Absolute,
|
|
source: Cow::Borrowed(config.source.as_path()),
|
|
target: Cow::Borrowed(config.target.as_path()),
|
|
mapping_type: ty,
|
|
read_only: config.read_only,
|
|
map: true,
|
|
create: config.create,
|
|
}
|
|
}
|
|
}
|