Skip to content

Commit

Permalink
add preserve_dotfiles_in_output configuration option (#1985)
Browse files Browse the repository at this point in the history
  • Loading branch information
flxzt authored Nov 19, 2022
1 parent ee4f53e commit e282bc8
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 4 deletions.
3 changes: 3 additions & 0 deletions components/config/src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ pub struct Config {
pub mode: Mode,

pub output_dir: String,
/// Whether dotfiles inside the output directory are preserved when rebuilding the site
pub preserve_dotfiles_in_output: bool,

pub link_checker: link_checker::LinkChecker,
/// The setup for which slugification strategies to use for paths, taxonomies and anchors
Expand Down Expand Up @@ -371,6 +373,7 @@ impl Default for Config {
ignored_content_globset: None,
translations: HashMap::new(),
output_dir: "public".to_string(),
preserve_dotfiles_in_output: false,
link_checker: link_checker::LinkChecker::default(),
slugify: slugify::Slugify::default(),
search: search::Search::default(),
Expand Down
32 changes: 28 additions & 4 deletions components/site/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ pub mod sitemap;
pub mod tpls;

use std::collections::HashMap;
use std::fs::remove_dir_all;
use std::fs::{remove_dir_all, remove_file};
use std::path::{Path, PathBuf};
use std::sync::{Arc, Mutex, RwLock};

Expand All @@ -23,6 +23,7 @@ use std::time::Instant;
use templates::{load_tera, render_redirect_template};
use utils::fs::{
copy_directory, copy_file_if_needed, create_directory, create_file, ensure_directory_exists,
is_dotfile,
};
use utils::net::get_available_port;
use utils::templates::{render_template, ShortcodeDefinition};
Expand Down Expand Up @@ -583,11 +584,34 @@ impl Site {
imageproc.do_process()
}

/// Deletes the `public` directory if it exists
/// Deletes the `public` directory if it exists and the `preserve_dotfiles_in_output` option is set to false,
/// or if set to true: its contents except for the dotfiles at the root level.
pub fn clean(&self) -> Result<()> {
if self.output_path.exists() {
// Delete current `public` directory so we can start fresh
remove_dir_all(&self.output_path).context("Couldn't delete output directory")?;
if !self.config.preserve_dotfiles_in_output {
return remove_dir_all(&self.output_path)
.context("Couldn't delete output directory");
}

for entry in self.output_path.read_dir().context(format!(
"Couldn't read output directory `{}`",
self.output_path.display()
))? {
let entry = entry.context("Couldn't read entry in output directory")?.path();

// Skip dotfiles if the preserve_dotfiles_in_output configuration option is set
if is_dotfile(&entry) {
continue;
}

if entry.is_dir() {
remove_dir_all(entry)
.context("Couldn't delete folder while cleaning the output directory")?;
} else {
remove_file(entry)
.context("Couldn't delete file while cleaning the output directory")?;
}
}
}

Ok(())
Expand Down
8 changes: 8 additions & 0 deletions components/utils/src/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,14 @@ where
time_source.and_then(|ts| time_target.map(|tt| ts > tt)).unwrap_or(true)
}

/// Checks if the file or folder for the given path is a dotfile, meaning starts with '.'
pub fn is_dotfile<P>(path: P) -> bool
where
P: AsRef<Path>,
{
path.as_ref().file_name().and_then(|s| s.to_str()).map(|s| s.starts_with('.')).unwrap_or(false)
}

#[cfg(test)]
mod tests {
use std::fs::{metadata, read_to_string, File};
Expand Down
4 changes: 4 additions & 0 deletions docs/content/documentation/getting-started/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ theme = ""
# For overriding the default output directory `public`, set it to another value (e.g.: "docs")
output_dir = "public"

# Whether dotfiles at the root level of the output directory are preserved when (re)building the site.
# Enabling this also prevents the deletion of the output folder itself on rebuilds.
preserve_dotfiles_in_output = false

# When set to "true", the Sass files in the `sass` directory in the site root are compiled.
# Sass files in theme directories are always compiled.
compile_sass = false
Expand Down

0 comments on commit e282bc8

Please sign in to comment.