use compose_yml::v2 as dc;
use std::marker::PhantomData;
#[cfg(test)]
use std::path::Path;
use crate::errors::*;
use crate::ext::service::ServiceExt;
use crate::plugins;
use crate::plugins::{Operation, PluginNew, PluginTransform};
use crate::project::Project;
use crate::util::ConductorPathExt;
#[derive(Debug)]
#[allow(missing_copy_implementations)]
pub struct Plugin {
_placeholder: PhantomData<()>,
}
impl plugins::Plugin for Plugin {
fn name(&self) -> &'static str {
Self::plugin_name()
}
}
impl PluginNew for Plugin {
fn plugin_name() -> &'static str {
"sources"
}
fn new(_project: &Project) -> Result<Self> {
Ok(Plugin {
_placeholder: PhantomData,
})
}
}
impl PluginTransform for Plugin {
fn transform(
&self,
op: Operation,
ctx: &plugins::Context<'_>,
file: &mut dc::File,
) -> Result<()> {
if op != Operation::Output {
return Ok(());
}
let project = ctx.project;
let sources_dirs = project.sources_dirs();
for service in &mut file.services.values_mut() {
for source_mount in service.sources(project.sources())? {
let source = source_mount.source;
if source.is_available_locally(&sources_dirs) && source.mounted() {
let source_subdirectory = source_mount
.source_subdirectory
.unwrap_or_else(|| "".to_string());
let path = source
.path(&sources_dirs)
.join(source_subdirectory)
.to_absolute()?;
let mount =
dc::VolumeMount::host(&path, source_mount.container_path);
service.volumes.push(dc::value(mount));
if let Some(ref mut build) = service.build {
if source.context() == build.context.value()? {
build.context = dc::value(dc::Context::Dir(path));
}
}
}
}
}
Ok(())
}
}
#[test]
fn adds_a_volume_with_a_subdirectory() {
let _ = env_logger::try_init();
let mut proj = Project::from_fixture("with_repo_subdir").unwrap();
let plugin = Plugin::new(&proj).unwrap();
let sources_dirs = proj.sources_dirs();
{
let source = proj.sources_mut().find_by_alias_mut("rails_hello").unwrap();
source.fake_clone_source(&sources_dirs).unwrap();
}
let target = proj.current_target();
let frontend = proj.pod("frontend").unwrap();
let ctx = plugins::Context::new(&proj, frontend, "up");
let mut file = frontend.merged_file(target).unwrap();
plugin
.transform(Operation::Output, &ctx, &mut file)
.unwrap();
let web = file.services.get("web").unwrap();
let src_volume = web.volumes[0].value().unwrap();
let host_path = match src_volume.clone().host.unwrap() {
dc::HostVolume::Path(ref path_buf) => path_buf.clone(),
_ => unreachable!(),
};
assert!(host_path.ends_with(Path::new("src/rails_hello/myfolder")));
assert_eq!(src_volume.container, "/usr/src/app");
}