diff --git a/Cargo.lock b/Cargo.lock index a1c249b0..b94fc047 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,5 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. + [[package]] name = "MacTypes-sys" version = "2.1.0" diff --git a/components/site/src/lib.rs b/components/site/src/lib.rs index ea2467a4..57ba91d1 100644 --- a/components/site/src/lib.rs +++ b/components/site/src/lib.rs @@ -66,7 +66,7 @@ pub struct Site { impl Site { /// Parse a site at the given path. Defaults to the current dir - /// Passing in a path is only used in tests + /// Passing in a path is possible using the `base-path` command line build option pub fn new>(path: P, config_file: &str) -> Result { let path = path.as_ref(); let mut config = get_config(path, config_file); diff --git a/docs/content/documentation/getting-started/cli-usage.md b/docs/content/documentation/getting-started/cli-usage.md index 95267f53..4b247cad 100644 --- a/docs/content/documentation/getting-started/cli-usage.md +++ b/docs/content/documentation/getting-started/cli-usage.md @@ -36,6 +36,14 @@ $ 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 `base_path` by passing a new directory to the `base-path` flag. If no `base-path` flag +is provided, zola defaults to your current working directory. This is useful if your zola project is located in +a different directory from where you're executing zola from. + +```bash +$ zola build --base-path /path/to/zola/site +``` + You can override the default output directory 'public' by passing a other value to the `output-dir` flag. ```bash @@ -67,6 +75,7 @@ $ zola serve --interface 0.0.0.0 $ zola serve --interface 0.0.0.0 --port 2000 $ zola serve --interface 0.0.0.0 --base-url 127.0.0.1 $ zola serve --interface 0.0.0.0 --port 2000 --output-dir www/public +$ zola serve --interface 0.0.0.0 --port 2000 --base-path mysite/ --output-dir mysite/www/public $ zola serve --watch-only ``` diff --git a/src/cli.rs b/src/cli.rs index 304d135b..500aa042 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -30,6 +30,11 @@ pub fn build_cli() -> App<'static, 'static> { .long("base-url") .takes_value(true) .help("Force the base URL to be that value (default to the one in config.toml)"), + Arg::with_name("base_path") + .short("b") + .long("base-path") + .takes_value(true) + .help("Force the base site path to a certain directory [default: the current working directory]"), Arg::with_name("output_dir") .short("o") .long("output-dir") @@ -56,6 +61,11 @@ pub fn build_cli() -> App<'static, 'static> { .default_value("public") .takes_value(true) .help("Outputs the generated site in the given path"), + Arg::with_name("base_path") + .short("b") + .long("base-path") + .takes_value(true) + .help("Force the base site path to a certain directory [default: the current working directory]"), Arg::with_name("base_url") .short("u") .long("base-url") diff --git a/src/cmd/build.rs b/src/cmd/build.rs index aca974e2..6bc8dc8d 100644 --- a/src/cmd/build.rs +++ b/src/cmd/build.rs @@ -1,12 +1,19 @@ use std::env; +use std::path::PathBuf; use errors::Result; use site::Site; use console; -pub fn build(config_file: &str, base_url: Option<&str>, output_dir: &str) -> Result<()> { - let mut site = Site::new(env::current_dir().unwrap(), config_file)?; +pub fn build( + config_file: &str, + base_path: Option<&str>, + base_url: Option<&str>, + output_dir: &str, +) -> Result<()> { + let bp = base_path.map(PathBuf::from).unwrap_or(env::current_dir().unwrap()); + let mut site = Site::new(bp, config_file)?; site.set_output_path(output_dir); if let Some(b) = base_url { site.set_base_url(b.to_string()); diff --git a/src/cmd/serve.rs b/src/cmd/serve.rs index 07544a06..50894c36 100644 --- a/src/cmd/serve.rs +++ b/src/cmd/serve.rs @@ -114,14 +114,15 @@ fn rebuild_done_handling(broadcaster: &Option, res: Result<()>, reload_p } } -fn create_new_site( +fn create_new_site>( interface: &str, port: u16, output_dir: &str, + base_path: P, base_url: &str, config_file: &str, ) -> Result<(Site, String)> { - let mut site = Site::new(env::current_dir().unwrap(), config_file)?; + let mut site = Site::new(base_path, config_file)?; let base_address = format!("{}:{}", base_url, port); let address = format!("{}:{}", interface, port); @@ -166,12 +167,15 @@ pub fn serve( interface: &str, port: u16, output_dir: &str, + base_path: Option<&str>, base_url: &str, config_file: &str, watch_only: bool, ) -> Result<()> { let start = Instant::now(); - let (mut site, address) = create_new_site(interface, port, output_dir, base_url, config_file)?; + let bp = base_path.map(PathBuf::from).unwrap_or(env::current_dir().unwrap()); + let (mut site, address) = + create_new_site(interface, port, output_dir, bp.clone(), base_url, config_file)?; console::report_elapsed_time(start); // Setup watchers @@ -180,28 +184,28 @@ pub fn serve( let (tx, rx) = channel(); let mut watcher = watcher(tx, Duration::from_secs(1)).unwrap(); watcher - .watch("content/", RecursiveMode::Recursive) + .watch(bp.join("content/"), RecursiveMode::Recursive) .map_err(|e| ZolaError::chain("Can't watch the `content` folder. Does it exist?", e))?; watcher - .watch(config_file, RecursiveMode::Recursive) + .watch(bp.join(config_file), RecursiveMode::Recursive) .map_err(|e| ZolaError::chain("Can't watch the `config` file. Does it exist?", e))?; - if Path::new("static").exists() { + if bp.join("static").exists() { watching_static = true; watcher - .watch("static/", RecursiveMode::Recursive) + .watch(bp.join("static/"), RecursiveMode::Recursive) .map_err(|e| ZolaError::chain("Can't watch the `static` folder.", e))?; } - if Path::new("templates").exists() { + if bp.join("templates").exists() { watching_templates = true; watcher - .watch("templates/", RecursiveMode::Recursive) + .watch(bp.join("templates/"), RecursiveMode::Recursive) .map_err(|e| ZolaError::chain("Can't watch the `templates` folder.", e))?; } // Sass support is optional so don't make it an error to no have a sass folder - let _ = watcher.watch("sass/", RecursiveMode::Recursive); + let _ = watcher.watch(bp.join("sass/"), RecursiveMode::Recursive); let ws_address = format!("{}:{}", interface, site.live_reload.unwrap()); let output_path = Path::new(output_dir).to_path_buf(); @@ -258,8 +262,6 @@ pub fn serve( None }; - let pwd = env::current_dir().unwrap(); - let mut watchers = vec!["content", "config.toml"]; if watching_static { watchers.push("static"); @@ -273,7 +275,7 @@ pub fn serve( println!( "Listening for changes in {}{}{{{}}}", - pwd.display(), + bp.display(), MAIN_SEPARATOR, watchers.join(", ") ); @@ -349,7 +351,8 @@ pub fn serve( if path.is_file() && is_temp_file(&path) { continue; } - let (change_kind, partial_path) = detect_change_kind(&pwd, &path); + let (change_kind, partial_path) = + detect_change_kind(&bp.canonicalize().unwrap(), &path); // We only care about changes in non-empty folders if path.is_dir() && is_folder_empty(&path) { @@ -381,6 +384,7 @@ pub fn serve( interface, port, output_dir, + bp.clone(), base_url, config_file, ) @@ -401,7 +405,7 @@ pub fn serve( ); let start = Instant::now(); - match detect_change_kind(&pwd, &path) { + match detect_change_kind(&bp.canonicalize().unwrap(), &path) { (ChangeKind::Content, _) => { console::info(&format!("-> Content changed {}", path.display())); // Force refresh @@ -420,6 +424,7 @@ pub fn serve( interface, port, output_dir, + bp.clone(), base_url, config_file, ) diff --git a/src/main.rs b/src/main.rs index 987e08bc..2ad43bac 100644 --- a/src/main.rs +++ b/src/main.rs @@ -46,7 +46,12 @@ fn main() { console::info("Building site..."); let start = Instant::now(); let output_dir = matches.value_of("output_dir").unwrap(); - match cmd::build(config_file, matches.value_of("base_url"), output_dir) { + match cmd::build( + config_file, + matches.value_of("base_path"), + matches.value_of("base_url"), + output_dir, + ) { Ok(()) => console::report_elapsed_time(start), Err(e) => { console::unravel_errors("Failed to build the site", &e); @@ -79,9 +84,18 @@ fn main() { } let watch_only = matches.is_present("watch_only"); let output_dir = matches.value_of("output_dir").unwrap(); + let base_path = matches.value_of("base_path"); let base_url = matches.value_of("base_url").unwrap(); console::info("Building site..."); - match cmd::serve(interface, port, output_dir, base_url, config_file, watch_only) { + match cmd::serve( + interface, + port, + output_dir, + base_path, + base_url, + config_file, + watch_only, + ) { Ok(()) => (), Err(e) => { console::unravel_errors("", &e);