diff --git a/CHANGELOG.md b/CHANGELOG.md index 4bb61a82..2ab180c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ Subheadings to categorize changes are `added, changed, deprecated, removed, fixe ## Unreleased ### fixed - Fixed [#148](https://github.com/thedodd/trunk/issues/148): any changes detected under a `.git` path are now being ignored by default. +- Fixed [#163](https://github.com/thedodd/trunk/issues/163): allow using `copy-file` assets with files without a file extension. ## 0.10.0 ### changed diff --git a/src/pipelines/inline.rs b/src/pipelines/inline.rs index a432512d..cc6dbb4b 100644 --- a/src/pipelines/inline.rs +++ b/src/pipelines/inline.rs @@ -33,7 +33,7 @@ impl Inline { path.extend(href_attr.split('/')); let asset = AssetFile::new(&html_dir, path).await?; - let content_type = ContentType::from_attr_or_ext(attrs.get(ATTR_TYPE), &asset.ext)?; + let content_type = ContentType::from_attr_or_ext(attrs.get(ATTR_TYPE), asset.ext.as_deref())?; Ok(Self { id, asset, content_type }) } @@ -72,10 +72,15 @@ pub enum ContentType { impl ContentType { /// Either tries to parse the provided attribute to a ContentType /// or tries to infer the ContentType from the AssetFile extension. - fn from_attr_or_ext(attr: Option>, ext: &str) -> Result { + fn from_attr_or_ext(attr: Option>, ext: Option<&str>) -> Result { match attr { Some(attr) => Self::from_str(attr.as_ref()), - None => Self::from_str(ext), + None => match ext { + Some(ext) => Self::from_str(ext), + None => bail!( + r#"unknown type value for attr; please ensure the value is lowercase and is a supported content type"#, + ), + }, } } } diff --git a/src/pipelines/mod.rs b/src/pipelines/mod.rs index 504b17ce..9d0f9a83 100644 --- a/src/pipelines/mod.rs +++ b/src/pipelines/mod.rs @@ -134,7 +134,7 @@ pub struct AssetFile { /// The file stem of the asset file. pub file_stem: OsString, /// The extension of the file. - pub ext: String, + pub ext: Option, } impl AssetFile { @@ -168,8 +168,8 @@ impl AssetFile { None => bail!("asset has no file name stem {:?}", &path), }; let ext = match path.extension() { - Some(ext) => ext.to_string_lossy().to_lowercase(), - None => bail!("asset has no file extension {:?}", &path), + Some(ext) => Some(ext.to_owned().to_string_lossy().to_string()), + None => None, }; Ok(Self { path: path.into(), @@ -199,7 +199,12 @@ impl AssetFile { .await .with_context(|| format!("error reading file for copying {:?}", &self.path))?; let hash = seahash::hash(bytes.as_ref()); - let file_name = format!("{}-{:x}.{}", &self.file_stem.to_string_lossy(), hash, &self.ext); + let file_name = format!( + "{}-{:x}.{}", + &self.file_stem.to_string_lossy(), + hash, + &self.ext.as_deref().unwrap_or_default() + ); let file_path = to_dir.join(&file_name); fs::write(&file_path, bytes)