Some(repo_desc) => {
let parsed_repo = parsed_repo.expect("ERROR: attempted to fill repo assets without a repository");
let repo = repo.expect("ERROR: attempted to fill repo assets without a repository");
- //let repo_path = repo.path().to_str().expect("ERROR: repository has no path!");
if repo_desc.asset_files.is_some() {
let target_dir = self.settings.outputs.repo_assets::<GitFile>(Some(&parsed_repo), None);
for src_file in repo_desc.asset_files.as_ref().unwrap() {
- let src_file = self.settings.outputs.asset(src_file, Some(parsed_repo), Some(repo));
+ // Read the asset file contents from the git repo
+ let src_file = PathBuf::from(src_file);
+ let src_contents = self.settings.outputs
+ .asset_contents(&src_file, Some(parsed_repo), Some(repo))?;
+
+ // Determine the output path
let mut dst_file = PathBuf::from(&target_dir);
- dst_file.push(src_file.file_name().expect(&format!(
- "Failed to copy repo asset file: {} ({})",
- src_file.display(),
- repo_desc.name.as_deref().unwrap_or_default()
- )));
- std::fs::copy(&src_file, &dst_file).expect(&format!(
- "Failed to copy repo asset file: {} ({})",
- src_file.display(),
- repo_desc.name.as_deref().unwrap_or_default()
- ));
+ let basename = src_file.file_name()
+ .ok_or(GitsyError::kind(
+ GitsyErrorKind::Settings,
+ Some(&format!(
+ "ERROR: repo asset file missing filename: {}",
+ src_file.display()
+ ))))?;
+ dst_file.push(basename);
+
+ // Open destination file for writing
+ let mut file = File::create(&dst_file)
+ .map_err(|e| GitsyError::sourced_kind(
+ GitsyErrorKind::Settings,
+ Some(&format!(
+ "ERROR: unable to open repo asset file for writing: {}",
+ dst_file.display()
+ )),
+ e))?;
+
+ // Write to disk
+ file.write(&src_contents)
+ .map_err(|e| GitsyError::sourced_kind(
+ GitsyErrorKind::Settings,
+ Some(&format!(
+ "ERROR: unable to write repo asset file: {}",
+ dst_file.display()
+ )),
+ e))?;
+
if let Ok(meta) = std::fs::metadata(dst_file) {
bytes += meta.len() as usize;
}
- loud!(" - copied asset: {}", src_file.display());
+ loud!(" - copied repo asset: {}", src_file.display());
}
}
}
if self.settings.asset_files.is_some() {
let target_dir = self.settings.outputs.global_assets::<GitFile>(None, None);
for src_file in self.settings.asset_files.as_ref().unwrap() {
- let src_file = self.settings.outputs.asset(src_file, None, None);
+ let src_file = self.settings.outputs.asset_path(src_file, None, None);
let mut dst_file = PathBuf::from(&target_dir);
dst_file.push(
src_file
if let Ok(meta) = std::fs::metadata(dst_file) {
bytes += meta.len() as usize;
}
- loud!(" - copied asset: {}", src_file.display());
+ loud!(" - copied global asset: {}", src_file.display());
}
}
}
* along with Itsy-Gitsy. If not, see <http://www.gnu.org/licenses/>.
*/
use crate::git::GitRepo;
-use crate::util::SafePathVar;
+use crate::util::{GitsyError, GitsyErrorKind, SafePathVar};
use crate::{error, louder};
use clap::Parser;
use git2::Repository;
}
}
- pub fn asset<P: AsRef<Path>>(&self, asset: &P, parsed_repo: Option<&GitRepo>, repo: Option<&Repository>) -> PathBuf {
+ pub fn asset_contents<P: AsRef<Path>>(&self, asset: &P,
+ parsed_repo: Option<&GitRepo>,
+ repo: Option<&Repository>) -> Result<Vec<u8>, GitsyError> {
+ let tmpl_path = asset.as_ref().to_path_buf();
+ let asset_path = substitute_path_vars(&tmpl_path, parsed_repo, Some(self));
+
+ // try to get a copy of the file contents from the git repo
+ match parsed_repo {
+ Some(p_repo) => {
+ match p_repo.all_files.iter().find(|f| f.path == asset_path.to_string_lossy()) {
+ Some(f) => {
+ match repo {
+ Some(repo) => {
+ let oid = git2::Oid::from_str(&f.id)?;
+ // the only happy path is if the repo exists, the file exists, and
+ // the contents load.
+ Ok(repo.find_blob(oid)?.content().to_owned())
+ },
+ None => {
+ Err(GitsyError::kind(
+ GitsyErrorKind::Settings,
+ Some(&format!(
+ "ERROR: not provided git repo for asset file: {}",
+ asset.as_ref().to_string_lossy()
+ ))))
+ }
+ }
+ },
+ _ => {
+ Err(GitsyError::kind(
+ GitsyErrorKind::Settings,
+ Some(&format!(
+ "ERROR: could not find repo asset file: {}",
+ asset.as_ref().to_string_lossy()
+ ))))
+ }
+ }
+ },
+ None => {
+ Err(GitsyError::kind(
+ GitsyErrorKind::Settings,
+ Some("ERROR: requested per-repo asset file without a repo.")))
+ }
+ }
+ }
+
+ pub fn asset_path<P: AsRef<Path>>(&self, asset: &P, parsed_repo: Option<&GitRepo>, repo: Option<&Repository>) -> PathBuf {
let tmpl_path = asset.as_ref().to_path_buf();
let asset_path = substitute_path_vars(&tmpl_path, parsed_repo, Some(self));
let full_path = match repo {