diff --git a/examples/target-path/index.html b/examples/target-path/index.html index fe2ce304..a6de188a 100644 --- a/examples/target-path/index.html +++ b/examples/target-path/index.html @@ -6,8 +6,8 @@ Trunk | target-path - - + + @@ -17,8 +17,8 @@ - - + + diff --git a/site/content/assets.md b/site/content/assets.md index f40ed4b8..b615817f 100644 --- a/site/content/assets.md +++ b/site/content/assets.md @@ -55,6 +55,7 @@ This will typically look like: `, } impl Css { @@ -49,6 +55,8 @@ impl Css { let minify = attrs.get(ATTR_MINIFY).is_none(); + let target_path = data_target_path(&attrs)?; + Ok(Self { id, cfg, @@ -56,6 +64,7 @@ impl Css { attrs, integrity, minify, + target_path, }) } @@ -71,18 +80,17 @@ impl Css { let rel_path = crate::common::strip_prefix(&self.asset.path); tracing::debug!(path = ?rel_path, "copying & hashing css"); let minify = self.cfg.release && self.minify && !self.cfg.no_minification; + + let result_path = + target_path(&self.cfg.staging_dist, self.target_path.as_deref(), None).await?; + let file = self .asset - .copy( - &self.cfg.staging_dist, - self.cfg.filehash, - minify, - AssetFileType::Css, - ) + .copy(&result_path, self.cfg.filehash, minify, AssetFileType::Css) .await?; tracing::debug!(path = ?rel_path, "finished copying & hashing css"); - let result_file = self.cfg.staging_dist.join(&file); + let result_file = result_path.join(&file); let integrity = OutputDigest::generate(self.integrity, || std::fs::read(&result_file)) .with_context(|| { format!( diff --git a/src/pipelines/icon.rs b/src/pipelines/icon.rs index 40977dcf..3af10740 100644 --- a/src/pipelines/icon.rs +++ b/src/pipelines/icon.rs @@ -1,6 +1,7 @@ //! Icon asset pipeline. -use super::{AssetFile, AttrWriter, Attrs, TrunkAssetPipelineOutput, ATTR_HREF}; +use super::{data_target_path, AssetFile, AttrWriter, Attrs, TrunkAssetPipelineOutput, ATTR_HREF}; +use crate::common::target_path; use crate::config::RtcBuild; use crate::pipelines::{AssetFileType, ImageType}; use crate::processing::integrity::{IntegrityType, OutputDigest}; @@ -21,6 +22,8 @@ pub struct Icon { asset: AssetFile, /// The required integrity setting integrity: IntegrityType, + /// Optional target path inside the dist dir. + target_path: Option, } impl Icon { @@ -42,11 +45,14 @@ impl Icon { let integrity = IntegrityType::from_attrs(&attrs, &cfg)?; + let target_path = data_target_path(&attrs)?; + Ok(Self { id, cfg, asset, integrity, + target_path, }) } @@ -66,17 +72,21 @@ impl Icon { "image/png" => ImageType::Png, _ => ImageType::Other, }; + + let result_dir = + target_path(&self.cfg.staging_dist, self.target_path.as_deref(), None).await?; + let file = self .asset .copy( - &self.cfg.staging_dist, + &result_dir, self.cfg.filehash, self.cfg.release && !self.cfg.no_minification, AssetFileType::Icon(image_type), ) .await?; - let result_file = self.cfg.staging_dist.join(&file); + let result_file = result_dir.join(&file); let integrity = OutputDigest::generate(self.integrity, || std::fs::read(&result_file)) .with_context(|| { format!( diff --git a/src/pipelines/js.rs b/src/pipelines/js.rs index 86508a60..1ecc8ce6 100644 --- a/src/pipelines/js.rs +++ b/src/pipelines/js.rs @@ -1,6 +1,9 @@ //! JS asset pipeline. -use super::{AssetFile, AttrWriter, Attrs, TrunkAssetPipelineOutput, ATTR_MINIFY, ATTR_SRC}; +use super::{ + data_target_path, AssetFile, AttrWriter, Attrs, TrunkAssetPipelineOutput, ATTR_MINIFY, ATTR_SRC, +}; +use crate::common::target_path; use crate::{ config::RtcBuild, pipelines::AssetFileType, @@ -28,6 +31,8 @@ pub struct Js { module: bool, /// Whether to minify or not minify: bool, + /// Optional target path inside the dist dir. + target_path: Option, } impl Js { @@ -48,6 +53,7 @@ impl Js { let integrity = IntegrityType::from_attrs(&attrs, &cfg)?; let module = attrs.get("type").map(|s| s.as_str()) == Some("module"); let minify = attrs.get(ATTR_MINIFY).is_none(); + let target_path = data_target_path(&attrs)?; Ok(Self { id, @@ -57,6 +63,7 @@ impl Js { attrs, integrity, minify, + target_path, }) } @@ -72,10 +79,14 @@ impl Js { let rel_path = crate::common::strip_prefix(&self.asset.path); tracing::debug!(path = ?rel_path, "copying & hashing js"); let minify = self.cfg.release && self.minify && !self.cfg.no_minification; + + let result_dir = + target_path(&self.cfg.staging_dist, self.target_path.as_deref(), None).await?; + let file = self .asset .copy( - &self.cfg.staging_dist, + &result_dir, self.cfg.filehash, minify, if self.module { @@ -87,7 +98,7 @@ impl Js { .await?; tracing::debug!(path = ?rel_path, "finished copying & hashing js"); - let result_file = self.cfg.staging_dist.join(&file); + let result_file = result_dir.join(&file); let integrity = OutputDigest::generate(self.integrity, || std::fs::read(&result_file)) .with_context(|| { format!( diff --git a/src/pipelines/mod.rs b/src/pipelines/mod.rs index f7b3d6ca..b81a3f88 100644 --- a/src/pipelines/mod.rs +++ b/src/pipelines/mod.rs @@ -46,6 +46,7 @@ const ATTR_SRC: &str = "src"; const ATTR_TYPE: &str = "type"; const ATTR_REL: &str = "rel"; const ATTR_MINIFY: &str = "data-no-minify"; +const ATTR_TARGET_PATH: &str = "data-target-path"; const SNIPPETS_DIR: &str = "snippets"; const TRUNK_ID: &str = "data-trunk-id"; const PNG_OPTIMIZATION_LEVEL: u8 = 6; @@ -398,3 +399,11 @@ impl fmt::Display for AttrWriter<'_> { Ok(()) } } + +/// Get the target path for an asset +fn data_target_path(attrs: &Attrs) -> Result> { + Ok(attrs + .get(ATTR_TARGET_PATH) + .map(|val| val.parse()) + .transpose()?) +}