Skip to content

Commit

Permalink
Add flag to override prompt for existing dir (#1986)
Browse files Browse the repository at this point in the history
* Add flag to override prompt for existing dir

Added --force flag to build subcommand.

* Remove unnecessary 'force' check

* Remove prompt to overwrite directory on build cmd
  • Loading branch information
Yaroslav-95 authored and Keats committed Feb 16, 2023
1 parent 4a6d13f commit 88433b6
Show file tree
Hide file tree
Showing 5 changed files with 13 additions and 43 deletions.
2 changes: 1 addition & 1 deletion docs/content/documentation/getting-started/cli-usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ $ zola build --base-url $DEPLOY_URL
This is useful for example when you want to deploy previews of a site to a dynamic URL, such as Netlify
deploy previews.

You can override the default output directory `public` by passing another value to the `output-dir` flag (if this directory already exists, the user will be prompted whether to replace the folder).
You can override the default output directory `public` by passing another value to the `output-dir` flag. If this directory already exists, the user will be prompted whether to replace the folder; you can override this prompt by passing the --force flag.

```bash
$ zola build --output-dir $DOCUMENT_ROOT
Expand Down
4 changes: 4 additions & 0 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ pub enum Command {
#[clap(short = 'o', long)]
output_dir: Option<PathBuf>,

/// Force building the site even if output directory is non-empty
#[clap(short = 'f', long)]
force: bool,

/// Include drafts when loading the site
#[clap(long)]
drafts: bool,
Expand Down
28 changes: 6 additions & 22 deletions src/cmd/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,38 +4,22 @@ use errors::{Error, Result};
use site::Site;

use crate::messages;
use crate::prompt::ask_bool_timeout;

const BUILD_PROMPT_TIMEOUT_MILLIS: u64 = 10_000;

pub fn build(
root_dir: &Path,
config_file: &Path,
base_url: Option<&str>,
output_dir: Option<&Path>,
force: bool,
include_drafts: bool,
) -> Result<()> {
let mut site = Site::new(root_dir, config_file)?;
if let Some(output_dir) = output_dir {
// Check whether output directory exists or not
// This way we don't replace already existing files.
if output_dir.exists() {
console::warn(&format!("The directory '{}' already exists. Building to this directory will delete files contained within this directory.", output_dir.display()));

// Prompt the user to ask whether they want to continue.
let clear_dir = tokio::runtime::Runtime::new()
.expect("Tokio runtime failed to instantiate")
.block_on(ask_bool_timeout(
"Are you sure you want to continue?",
false,
std::time::Duration::from_millis(BUILD_PROMPT_TIMEOUT_MILLIS),
))?;

if !clear_dir {
return Err(Error::msg(
"Cancelled build process because output directory already exists.",
));
}
if !force && output_dir.exists() {
return Err(Error::msg(format!(
"Directory '{}' already exists. User --force to overwrite.",
output_dir.display(),
)));
}

site.set_output_path(output_dir);
Expand Down
3 changes: 2 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ fn main() {
std::process::exit(1);
}
}
Command::Build { base_url, output_dir, drafts } => {
Command::Build { base_url, output_dir, force, drafts } => {
console::info("Building site...");
let start = Instant::now();
let (root_dir, config_file) = get_config_file_path(&cli_dir, &cli.config);
Expand All @@ -48,6 +48,7 @@ fn main() {
&config_file,
base_url.as_deref(),
output_dir.as_deref(),
force,
drafts,
) {
Ok(()) => messages::report_elapsed_time(start),
Expand Down
19 changes: 0 additions & 19 deletions src/prompt.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use std::io::{self, BufRead, Write};
use std::time::Duration;

use libs::url::Url;

Expand Down Expand Up @@ -33,24 +32,6 @@ pub fn ask_bool(question: &str, default: bool) -> Result<bool> {
}
}

/// Ask a yes/no question to the user with a timeout
pub async fn ask_bool_timeout(question: &str, default: bool, timeout: Duration) -> Result<bool> {
let (tx, rx) = tokio::sync::oneshot::channel();

let q = question.to_string();
std::thread::spawn(move || {
tx.send(ask_bool(&q, default)).unwrap();
});

match tokio::time::timeout(timeout, rx).await {
Err(_) => {
console::warn("\nWaited too long for response.");
Ok(default)
}
Ok(val) => val.expect("Tokio failed to properly execute"),
}
}

/// Ask a question to the user where they can write a URL
pub fn ask_url(question: &str, default: &str) -> Result<String> {
print!("{} ({}): ", question, default);
Expand Down

0 comments on commit 88433b6

Please sign in to comment.