rustyphoenixlecture 1.7.2

This project aims to provide a simple a powerfull lecture compilation to generate html web sites
/***************************************
	Auteur : Pierre Aubert
	Mail : pierre.aubert@lapp.in2p3.fr
	Licence : CeCILL-C
****************************************/

use std::{fs, path::PathBuf, process::Command};

use crate::phighlighter::PLocation;
use crate::plectureparser::find_common_start::remove_common_start;

///Manage the archive of a lecture ressource
#[derive(Debug,Clone)]
pub struct PRessourceArchive{
	///Path of the Ressource file relative to the current lecture file 
	p_relative_input_ressource_dir: PathBuf,
	///Path of the Ressource file absolute to the current lecture file 
	p_absolute_input_ressource_dir: PathBuf,
	///Relative path to the output archive file
	p_relative_output_archive_file: PathBuf,
	///Absolute path to the output archive file
	p_absolute_output_archive_file: PathBuf,
	///Absolute path to the parent directory of the output archive file
	p_absolute_output_archive_directory: PathBuf,
	
	///Location where the archive was called in the lecture
	p_location_lecture_file: PLocation,
	///Asbolute path of the lecture output directory
	p_absolute_lecture_output_dir: PathBuf,
}

impl PRessourceArchive {
	///Constructor of the PRessourceArchive
	/// # Parameters
	/// - `relative_ressource_dir` : path of the Ressource directory relative to the current lecture file
	/// - `location_lecture_file` : location of the lecture file (file, line and column) (given by the PFileParserIter)
	/// - `absolute_lecture_output_dir` : asbolute path of the lecture output directory
	/// # Returns
	/// Initialised PRessourceArchive
	pub fn new(relative_ressource_dir: &PathBuf, location_lecture_file: &PLocation, absolute_lecture_output_dir: &PathBuf) -> Self{
		let mut other = PRessourceArchive{
			p_relative_input_ressource_dir: relative_ressource_dir.clone(),
			p_absolute_input_ressource_dir: Default::default(),
			p_relative_output_archive_file: Default::default(),
			p_absolute_output_archive_file: Default::default(),
			p_absolute_output_archive_directory: Default::default(),
			
			p_location_lecture_file: location_lecture_file.clone(),
			p_absolute_lecture_output_dir: absolute_lecture_output_dir.clone(),
		};
		other.make_ressource_path();
		return other;
	}
	///Make the missing path of the PRessourceArchive
	/// # Errors
	/// This function may panic if the lecture source file PLocation does not exist, but the error should be understandable
	fn make_ressource_path(&mut self){
		// Let's get the absolute path of the input source_file
		let absolute_ressource_file = match self.p_location_lecture_file.get_filename().canonicalize(){
			Ok(absolute_path) => match absolute_path.parent(){
				Some(parent_path) => parent_path.join(&self.p_relative_input_ressource_dir),
				None => panic!("PRessourceArchive::make_ressource_path : Cannot get parent of absolute path of {:?}", self.p_location_lecture_file)
			},
			Err(err) => panic!("PRessourceArchive::make_ressource_path : Cannot get absolute path of {:?}\n\tError {}", self.p_location_lecture_file, err)
		};
		//Let's get the relative path to the file without the common prefix
		let end_source_file: PathBuf = remove_common_start(&absolute_ressource_file, &self.p_absolute_lecture_output_dir);
		
		//here the input directory is in ressource, and the output directory is in archive
		self.p_absolute_input_ressource_dir = self.p_absolute_lecture_output_dir.join(PathBuf::from("ressource")).join(&end_source_file);
		self.p_relative_output_archive_file = PathBuf::from("archive").join(&self.p_relative_input_ressource_dir);
		//The add extension in in place and breaks the chain of PathBuf because why not
		self.p_relative_output_archive_file.add_extension("tar.gz");
		self.p_absolute_output_archive_file = self.p_absolute_lecture_output_dir.join(&self.p_relative_output_archive_file);
		self.p_absolute_output_archive_directory = PathBuf::from(self.p_absolute_output_archive_file.parent().unwrap());
	}
	///Create the output directory for the ressource file
	pub fn create_dir_all(&self){
		match fs::create_dir_all(&self.p_absolute_output_archive_directory) {
			Ok(_) => {},
			Err(err) => panic!("PRessourceArchive::create_dir_all : cannot create output directory {:?}\n\tError {}", self.p_absolute_output_archive_directory, err)
		};
	}
	///Create the archive
	pub fn create_archive(&self){
		//First, we check if the output directory does exist
		if !self.p_absolute_output_archive_directory.exists() {
			//If not we create it
			self.create_dir_all();
		}
		
		let input_parent_dir = self.p_absolute_input_ressource_dir.parent().unwrap();
		let input_dir_name = self.p_absolute_input_ressource_dir.file_name().unwrap();
		match Command::new("tar")
			.arg("-zcf")
			.arg(&self.p_absolute_output_archive_file)
			.arg(&input_dir_name)
			.current_dir(input_parent_dir)
			.output()
		{
			Ok(output) => {
				if !output.status.success() {
					println!("PRessourceArchive::create_archive : Cannot create the archive (wrong exist status) {:?}\n\tFrom Directory {:?}\n\tDefined in lecture at {}", self.p_absolute_output_archive_file, self.p_absolute_input_ressource_dir, self.p_location_lecture_file);
					//Sounds fun to be bothered by a stupid map because the output is not in plain text !!!!?????
					// And of course the output is so ugly and unreadable... even with char
					let error: String = output.stderr.iter().map(|value| *value as char).collect();
					panic!("{:?}", error);
				}
			},
			Err(err) => panic!("PRessourceArchive::create_archive : Cannot create the archive {:?}\n\tFrom Directory {:?}\n\tDefined in lecture at {}\n\tError {}", self.p_absolute_output_archive_file, self.p_absolute_input_ressource_dir, self.p_location_lecture_file, err)
		};
	}
	///Get the output archive name
	/// # Returns
	/// Archive simple file name without any directory
	pub fn get_archive_file_name(&self) -> String{
		String::from(self.p_relative_output_archive_file.file_name().unwrap().to_str().unwrap())
	}
	///Get the relative path to the output archive file
	/// # Returns
	/// Relative path to the output file
	pub fn get_relative_output_archive_file(&self) -> &PathBuf{
		&self.p_relative_output_archive_file
	}
	///Get the absolute path to the output archive file
	/// # Returns
	/// Relative path to the output file
	pub fn get_absolute_output_archive_file(&self) -> &PathBuf{
		&self.p_absolute_output_archive_file
	}
}