pub fn generate(&self, output_dir: &PathBuf, no_input: bool) -> Result<()> {
        // Get the variables from the user first
        let conf_path = self.path.join("template.toml");
        if !conf_path.exists() {
            return Err(new_error(ErrorKind::MissingTemplateDefinition));
        }

        let definition: TemplateDefinition = toml::from_str(&read_file(&conf_path)?)
            .map_err(|err| new_error(ErrorKind::Toml { err }))?;

        let variables = definition.ask_questions(no_input)?;
        let mut context = Context::new();
        for (key, val) in &variables {
            context.insert(key, val);
        }

        if !output_dir.exists() {
            create_directory(&output_dir)?;
        }

        // Create the glob patterns of files to copy without rendering first, only once
        let patterns: Vec<Pattern> = definition.copy_without_render
            .iter()
            .map(|s| Pattern::new(s).unwrap())
            .collect();

        // And now generate the files in the output dir given
        let walker = WalkDir::new(&self.path)
            .into_iter()
            .filter_entry(|e| !is_vcs(e))
            .filter_map(|e| e.ok());

        'outer: for entry in walker {
            // Skip root folder and the template.toml
            if entry.path() == self.path || entry.path() == conf_path {
                continue;
            }

            let path = entry.path().strip_prefix(&self.path).unwrap();
            let path_str = format!("{}", path.display());
            for ignored in &definition.ignore {
                if ignored == &path_str || path_str.starts_with(ignored) {
                    continue 'outer;
                }
            }

            let tpl = Tera::one_off(&path_str, &context, false)
                .map_err(|err| new_error(ErrorKind::Tera { err, path: None }))?;

            let real_path = output_dir.join(Path::new(&tpl));

            if entry.path().is_dir() {
                create_directory(&real_path)?;
                continue;
            }

            // Only pass non-binary files or the files not matching the copy_without_render patterns through Tera
            let mut f = File::open(&entry.path())?;
            let mut buffer = Vec::new();
            f.read_to_end(&mut buffer)?;

            let no_render = patterns.iter().map(|p| p.matches_path(&real_path)).any(|x| x);

            if no_render || is_binary(&buffer) {
                fs::copy(&entry.path(), &real_path)
                    .map_err(|err| new_error(ErrorKind::Io { err, path: entry.path().to_path_buf() }))?;
                continue;
            }

            let contents = Tera::one_off(&str::from_utf8(&buffer).unwrap(), &context, false)
                .map_err(|err| new_error(ErrorKind::Tera { err, path: Some(entry.path().to_path_buf()) }))?;
            write_file(&real_path, &contents)?;
        }

        for cleanup in &definition.cleanup {
            if let Some(val) = variables.get(&cleanup.name) {
                if *val == cleanup.value {
                    for p in &cleanup.paths {
                        let actual_path = Tera::one_off(&p, &context, false)
                            .map_err(|err| new_error(ErrorKind::Tera { err, path: None }))?;
                        let path_to_delete = output_dir.join(actual_path);
                        if !path_to_delete.exists() {
                            continue;
                        }
                        if path_to_delete.is_dir() {
                            fs::remove_dir_all(&path_to_delete)
                                .map_err(|err| new_error(ErrorKind::Io { err, path: path_to_delete.to_path_buf() }))?;
                        } else {
                            fs::remove_file(&path_to_delete)
                                .map_err(|err| new_error(ErrorKind::Io { err, path: path_to_delete.to_path_buf() }))?;
                        }
                    }
                }
            }
        }

        Ok(())
    }
/// Generate the template at the given output directory
Generate the template at the given output directory
Generate the template at the given output directory
pub fn generate(&self, output_dir: &PathBuf, no_input: bool) -> Result<()> {
        // Get the variables from the user first
        let conf_path = self.path.join("template.toml");
        if !conf_path.exists() {
            return Err(new_error(ErrorKind::MissingTemplateDefinition));
        }
        let definition: TemplateDefinition = toml::from_str(&read_file(&conf_path)?)
            .map_err(|err| new_error(ErrorKind::Toml { err }))?;
        let variables = definition.ask_questions(no_input)?;
        let mut context = Context::new();
        for (key, val) in &variables {
            context.insert(key, val);
        }
        if !output_dir.exists() {
            create_directory(&output_dir)?;
        }
        // Create the glob patterns of files to copy without rendering first, only once
        let patterns: Vec<Pattern> = definition.copy_without_render
            .iter()
            .map(|s| Pattern::new(s).unwrap())
            .collect();
        // And now generate the files in the output dir given
        let walker = WalkDir::new(&self.path)
            .into_iter()
            .filter_entry(|e| !is_vcs(e))
            .filter_map(|e| e.ok());
        'outer: for entry in walker {
            // Skip root folder and the template.toml
            if entry.path() == self.path || entry.path() == conf_path {
                continue;
            }
            let path = entry.path().strip_prefix(&self.path).unwrap();
            let path_str = format!("{}", path.display());
            for ignored in &definition.ignore {
                if ignored == &path_str || path_str.starts_with(ignored) {
                    continue 'outer;
                }
            }
            let tpl = Tera::one_off(&path_str, &context, false)
                .map_err(|err| new_error(ErrorKind::Tera { err, path: None }))?;
            let real_path = output_dir.join(Path::new(&tpl));
            if entry.path().is_dir() {
                create_directory(&real_path)?;
                continue;
            }
            // Only pass non-binary files or the files not matching the copy_without_render patterns through Tera
            let mut f = File::open(&entry.path())?;
            let mut buffer = Vec::new();
            f.read_to_end(&mut buffer)?;
            let no_render = patterns.iter().map(|p| p.matches_path(&real_path)).any(|x| x);
            if no_render || is_binary(&buffer) {
                fs::copy(&entry.path(), &real_path)
                    .map_err(|err| new_error(ErrorKind::Io { err, path: entry.path().to_path_buf() }))?;
                continue;
            }
            let contents = Tera::one_off(&str::from_utf8(&buffer).unwrap(), &context, false)
                .map_err(|err| new_error(ErrorKind::Tera { err, path: Some(entry.path().to_path_buf()) }))?;
            write_file(&real_path, &contents)?;
        }
        for cleanup in &definition.cleanup {
            if let Some(val) = variables.get(&cleanup.name) {
                if *val == cleanup.value {
                    for p in &cleanup.paths {
                        let actual_path = Tera::one_off(&p, &context, false)
                            .map_err(|err| new_error(ErrorKind::Tera { err, path: None }))?;
                        let path_to_delete = output_dir.join(actual_path);
                        if !path_to_delete.exists() {
                            continue;
                        }
                        if path_to_delete.is_dir() {
                            fs::remove_dir_all(&path_to_delete)
                                .map_err(|err| new_error(ErrorKind::Io { err, path: path_to_delete.to_path_buf() }))?;
                        } else {
                            fs::remove_file(&path_to_delete)
                                .map_err(|err| new_error(ErrorKind::Io { err, path: path_to_delete.to_path_buf() }))?;
                        }
                    }
                }
            }
        }
        Ok(())
    }
pub fn generate ( & self , output_dir : & PathBuf , no_input : bool ) -> Result < ( ) > { // Get the variables from the user first let conf_path = self . path . join ( " " ) ; if ! conf_path . exists ( ) { return Err ( new_error ( ErrorKind :: MissingTemplateDefinition ) ) ; } let definition : TemplateDefinition = toml :: from_str ( & read_file ( & conf_path ) ? ) . map_err ( | err | new_error ( ErrorKind :: Toml { err } ) ) ? ; let variables = definition . ask_questions ( no_input ) ? ; let mut context = Context :: new ( ) ; for ( key , val ) in & variables { context . insert ( key , val ) ; } if ! output_dir . exists ( ) { create_directory ( & output_dir ) ? ; } // Create the glob patterns of files to copy without rendering first, only once let patterns : Vec < Pattern > = definition . copy_without_render . iter ( ) . map ( | s | Pattern :: new ( s ) . unwrap ( ) ) . collect ( ) ; // And now generate the files in the output dir given let walker = WalkDir :: new ( & self . path ) . into_iter ( ) . filter_entry ( | e | ! is_vcs ( e ) ) . filter_map ( | e | e . ok ( ) ) ; ' outer : for entry in walker { // Skip root folder and the template.toml if entry . path ( ) == self . path || entry . path ( ) == conf_path { continue ; } let path = entry . path ( ) . strip_prefix ( & self . path ) . unwrap ( ) ; let path_str = format ! ( " " path display ( ) ) ; for ignored in & definition . ignore { if ignored == & path_str || path_str . starts_with ( ignored ) { continue ' outer ; } } let tpl = Tera :: one_off ( & path_str , & context , false ) . map_err ( | err | new_error ( ErrorKind :: Tera { err , path : None } ) ) ? ; let real_path = output_dir . join ( Path :: new ( & tpl ) ) ; if entry . path ( ) . is_dir ( ) { create_directory ( & real_path ) ? ; continue ; } // Only pass non-binary files or the files not matching the copy_without_render patterns through Tera let mut f = File :: open ( & entry . path ( ) ) ? ; let mut buffer = Vec :: new ( ) ; f . read_to_end ( & mut buffer ) ? ; let no_render = patterns . iter ( ) . map ( | p | p . matches_path ( & real_path ) ) . any ( | x | x ) ; if no_render || is_binary ( & buffer ) { fs :: copy ( & entry . path ( ) , & real_path ) . map_err ( | err | new_error ( ErrorKind :: Io { err , path : entry . path ( ) . to_path_buf ( ) } ) ) ? ; continue ; } let contents = Tera :: one_off ( & str :: from_utf8 ( & buffer ) . unwrap ( ) , & context , false ) . map_err ( | err | new_error ( ErrorKind :: Tera { err , path : Some ( entry . path ( ) . to_path_buf ( ) ) } ) ) ? ; write_file ( & real_path , & contents ) ? ; } for cleanup in & definition . cleanup { if let Some ( val ) = variables . get ( & cleanup . name ) { if * val == cleanup . value { for p in & cleanup . paths { let actual_path = Tera :: one_off ( & p , & context , false ) . map_err ( | err | new_error ( ErrorKind :: Tera { err , path : None } ) ) ? ; let path_to_delete = output_dir . join ( actual_path ) ; if ! path_to_delete . exists ( ) { continue ; } if path_to_delete . is_dir ( ) { fs :: remove_dir_all ( & path_to_delete ) . map_err ( | err | new_error ( ErrorKind :: Io { err , path : path_to_delete . to_path_buf ( ) } ) ) ? ; } else { fs :: remove_file ( & path_to_delete ) . map_err ( | err | new_error ( ErrorKind :: Io { err , path : path_to_delete . to_path_buf ( ) } ) ) ? ; } } } } } Ok ( ( ) ) }
Generate the template at the given output directory
Generate the template at the given output directory
&self
output_dir
&PathBuf
no_input
bool