Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add preserve_hidden_files configuration option #1985

Merged
merged 8 commits into from
Nov 19, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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!(
flxzt marked this conversation as resolved.
Show resolved Hide resolved
"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")?;
}
}
flxzt marked this conversation as resolved.
Show resolved Hide resolved
}

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