Merge pull request #644 from getzola/next

v0.7.0
This commit is contained in:
Vincent Prouillet 2019-04-28 10:41:12 +02:00 committed by GitHub
commit 986437546c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 591 additions and 551 deletions

View File

@ -1,5 +1,14 @@
# Changelog # Changelog
## 0.7.0 (2019-04-28)
### Breaking
- Remove --base-path option, it broke `serve` on Windows and wasn't properly tested
### Other
- Strip wrapping whitespaces from shortcodes
- Sort sitemap elements by permalink`
## 0.6.0 (2019-03-25) ## 0.6.0 (2019-03-25)
### Breaking ### Breaking

918
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
[package] [package]
name = "zola" name = "zola"
version = "0.6.0" version = "0.7.0"
authors = ["Vincent Prouillet <prouillet.vincent@gmail.com>"] authors = ["Vincent Prouillet <prouillet.vincent@gmail.com>"]
license = "MIT" license = "MIT"
readme = "README.md" readme = "README.md"

View File

@ -1,4 +1,5 @@
# zola (né Gutenberg) # zola (né Gutenberg)
[![Build Status](https://travis-ci.com/getzola/zola.svg?branch=master)](https://travis-ci.com/getzola/zola) [![Build Status](https://travis-ci.com/getzola/zola.svg?branch=master)](https://travis-ci.com/getzola/zola)
[![Build status](https://ci.appveyor.com/api/projects/status/i0ufvx2sdm2cmawo/branch/master?svg=true)](https://ci.appveyor.com/project/Keats/zola/branch/master) [![Build status](https://ci.appveyor.com/api/projects/status/i0ufvx2sdm2cmawo/branch/master?svg=true)](https://ci.appveyor.com/project/Keats/zola/branch/master)
@ -9,32 +10,31 @@ in the `docs/content` folder of the repository and the community can use [its fo
## Comparisons with other static site generators ## Comparisons with other static site generators
| | Zola | Cobalt | Hugo | Pelican | | | Zola | Cobalt | Hugo | Pelican |
|:-------------------------------:|:---------:|--------|------|---------| |:--------------------------------|:--------------------:|:--------------------:|:--------------------:|:--------------------:|
| Single binary | ✔ | ✔ | ✔ | ✕ | | Single binary | ![yes](./is-yes.svg) | ![yes](./is-yes.svg) | ![yes](./is-yes.svg) | ![no](./is-no.svg) |
| Language | Rust | Rust | Go | Python | | Language | Rust | Rust | Go | Python |
| Syntax highlighting | ✔ | ✔ | ✔ | ✔ | | Syntax highlighting | ![yes](./is-yes.svg) | ![yes](./is-yes.svg) | ![yes](./is-yes.svg) | ![yes](./is-yes.svg) |
| Sass compilation | ✔ | ✔ | ✔ | ✔ | | Sass compilation | ![yes](./is-yes.svg) | ![yes](./is-yes.svg) | ![yes](./is-yes.svg) | ![yes](./is-yes.svg) |
| Assets co-location | ✔ | ✔ | ✔ | ✔ | | Assets co-location | ![yes](./is-yes.svg) | ![yes](./is-yes.svg) | ![yes](./is-yes.svg) | ![yes](./is-yes.svg) |
| Multilingual site | ✔ | ✕ | ✔ | ✔ | | Multilingual site | ![yes](./is-yes.svg) | ![no](./is-no.svg) | ![yes](./is-yes.svg) | ![yes](./is-yes.svg) |
| Image processing | ✔ | ✕ | ✔ | ✔ | | Image processing | ![yes](./is-yes.svg) | ![no](./is-no.svg) | ![yes](./is-yes.svg) | ![yes](./is-yes.svg) |
| Sane & powerful template engine | ✔ | ~ | ~ | ✔ | | Sane & powerful template engine | ![yes](./is-yes.svg) | ![ehh](./is-ehh.svg) | ![ehh](./is-ehh.svg) | ![yes](./is-yes.svg) |
| Themes | ✔ | ✕ | ✔ | ✔ | | Themes | ![yes](./is-yes.svg) | ![no](./is-no.svg) | ![yes](./is-yes.svg) | ![yes](./is-yes.svg) |
| Shortcodes | ✔ | ✕ | ✔ | ✔ | | Shortcodes | ![yes](./is-yes.svg) | ![no](./is-no.svg) | ![yes](./is-yes.svg) | ![yes](./is-yes.svg) |
| Internal links | ✔ | ✕ | ✔ | ✔ | | Internal links | ![yes](./is-yes.svg) | ![no](./is-no.svg) | ![yes](./is-yes.svg) | ![yes](./is-yes.svg) |
| Link checker | ✔ | ✕ | ✕ | ✔ | | Link checker | ![yes](./is-yes.svg) | ![no](./is-no.svg) | ![no](./is-no.svg) | ![yes](./is-yes.svg) |
| Table of contents | ✔ | ✕ | ✔ | ✔ | | Table of contents | ![yes](./is-yes.svg) | ![no](./is-no.svg) | ![yes](./is-yes.svg) | ![yes](./is-yes.svg) |
| Automatic header anchors | ✔ | ✕ | ✔ | ✔ | | Automatic header anchors | ![yes](./is-yes.svg) | ![no](./is-no.svg) | ![yes](./is-yes.svg) | ![yes](./is-yes.svg) |
| Aliases | ✔ | ✕ | ✔ | ✔ | | Aliases | ![yes](./is-yes.svg) | ![no](./is-no.svg) | ![yes](./is-yes.svg) | ![yes](./is-yes.svg) |
| Pagination | ✔ | ✕ | ✔ | ✔ | | Pagination | ![yes](./is-yes.svg) | ![no](./is-no.svg) | ![yes](./is-yes.svg) | ![yes](./is-yes.svg) |
| Custom taxonomies | ✔ | ✕ | ✔ | ✕ | | Custom taxonomies | ![yes](./is-yes.svg) | ![no](./is-no.svg) | ![yes](./is-yes.svg) | ![no](./is-no.svg) |
| Search | ✔ | ✕ | ✕ | ✔ | | Search | ![yes](./is-yes.svg) | ![no](./is-no.svg) | ![no](./is-no.svg) | ![yes](./is-yes.svg) |
| Data files | ✔ | ✔ | ✔ | ✕ | | Data files | ![yes](./is-yes.svg) | ![yes](./is-yes.svg) | ![yes](./is-yes.svg) | ![no](./is-no.svg) |
| LiveReload | ✔ | ✕ | ✔ | ✔ | | LiveReload | ![yes](./is-yes.svg) | ![no](./is-no.svg) | ![yes](./is-yes.svg) | ![yes](./is-yes.svg) |
| Netlify support | ~ | ✕ | ✔ | ✕ | | Netlify support | ![ehh](./is-ehh.svg) | ![no](./is-no.svg) | ![yes](./is-yes.svg) | ![no](./is-no.svg) |
| Breadcrumbs | ✔ | ✕ | ✕ | ✔ | | Breadcrumbs | ![yes](./is-yes.svg) | ![no](./is-no.svg) | ![no](./is-no.svg) | ![yes](./is-yes.svg) |
| Custom output formats | ✕ | ✕ | ✔ | ? | | Custom output formats | ![no](./is-no.svg) | ![no](./is-no.svg) | ![yes](./is-yes.svg) | ![no](./is-no.svg) |
### Supported content formats ### Supported content formats
@ -45,11 +45,10 @@ in the `docs/content` folder of the repository and the community can use [its fo
### Template engine explanation ### Template engine explanation
Cobalt gets `~` as, while based on [Liquid](https://shopify.github.io/liquid/), the Rust library doesn't implement all its features but there is no documentation on what is and isn't implemented. The errors are also cryptic. Liquid itself is not powerful enough to do some of things you can do in Jinja2, Go templates or Tera. Cobalt gets ![ehh](./is-ehh.svg) because, while based on [Liquid](https://shopify.github.io/liquid/), the Rust library doesn't implement all its features and there is no documentation on what is and isn't implemented; the errors are cryptic; and Liquid itself is not powerful enough to do some of things you can do in Jinja2, Go templates, or Tera.
Hugo gets `~`. It is probably the most powerful template engine in the list after Jinja2 (hard to beat python code in templates) but personally drives me insane, to the point of writing my own template engine and static site generator. Yes, this is a bit biased. Hugo gets ![ehh](./is-ehh.svg) because while it is probably the most powerful template engine in the list, after Jinja2, it personally drives me insane, to the point of writing my own template engine and static site generator. Yes, this is a bit biased.
### Pelican notes ### Pelican notes
Many features of Pelican are coming from plugins, which might be tricky
to use because of version mismatch or lacking documentation. Netlify supports Python Many features of Pelican are coming from plugins, which might be tricky to use because of version mismatch or lacking documentation. Netlify supports Python and Pipenv but you still need to install your dependencies manually.
and Pipenv but you still need to install your dependencies manually.

View File

@ -16,6 +16,7 @@ pub struct ContentParser;
lazy_static! { lazy_static! {
static ref MULTIPLE_NEWLINE_RE: Regex = Regex::new(r"\n\s*\n").unwrap(); static ref MULTIPLE_NEWLINE_RE: Regex = Regex::new(r"\n\s*\n").unwrap();
static ref OUTER_NEWLINE_RE: Regex = Regex::new(r"^\s*\n|\n\s*$").unwrap();
} }
fn replace_string_markers(input: &str) -> String { fn replace_string_markers(input: &str) -> String {
@ -122,6 +123,8 @@ fn render_shortcode(
// at indentation, making the output a code block. // at indentation, making the output a code block.
let res = MULTIPLE_NEWLINE_RE.replace_all(&res, "\n"); let res = MULTIPLE_NEWLINE_RE.replace_all(&res, "\n");
let res = OUTER_NEWLINE_RE.replace_all(&res, "");
Ok(res.to_string()) Ok(res.to_string())
} }
@ -411,4 +414,20 @@ Some body {{ hello() }}{%/* end */%}"#,
let res = render_shortcodes("Body\n {% youtube() %}\nHello \n World{% end %}", &tera); let res = render_shortcodes("Body\n {% youtube() %}\nHello \n World{% end %}", &tera);
assert_eq!(res, "Body\n Hello \n World"); assert_eq!(res, "Body\n Hello \n World");
} }
#[test]
fn outer_newlines_removed_from_shortcodes_with_body() {
let mut tera = Tera::default();
tera.add_raw_template("shortcodes/youtube.html", " \n {{body}} \n ").unwrap();
let res = render_shortcodes("\n{% youtube() %} \n content \n {% end %}\n", &tera);
assert_eq!(res, "\n content \n");
}
#[test]
fn outer_newlines_removed_from_inline_shortcodes() {
let mut tera = Tera::default();
tera.add_raw_template("shortcodes/youtube.html", " \n Hello, Zola. \n ").unwrap();
let res = render_shortcodes("\n{{ youtube() }}\n", &tera);
assert_eq!(res, "\n Hello, Zola. \n");
}
} }

View File

@ -66,7 +66,7 @@ pub struct Site {
impl Site { impl Site {
/// Parse a site at the given path. Defaults to the current dir /// Parse a site at the given path. Defaults to the current dir
/// Passing in a path is possible using the `base-path` command line build option /// Passing in a path is only used in tests
pub fn new<P: AsRef<Path>>(path: P, config_file: &str) -> Result<Site> { pub fn new<P: AsRef<Path>>(path: P, config_file: &str) -> Result<Site> {
let path = path.as_ref(); let path = path.as_ref();
let mut config = get_config(path, config_file); let mut config = get_config(path, config_file);
@ -777,11 +777,15 @@ impl Site {
ensure_directory_exists(&self.output_path)?; ensure_directory_exists(&self.output_path)?;
let library = self.library.read().unwrap(); let library = self.library.read().unwrap();
let all_sitemap_entries = sitemap::find_entries( let all_sitemap_entries = {
&library, let mut all_sitemap_entries = sitemap::find_entries(
&self.taxonomies[..], &library,
&self.config, &self.taxonomies[..],
); &self.config,
);
all_sitemap_entries.sort();
all_sitemap_entries
};
let sitemap_limit = 30000; let sitemap_limit = 30000;
if all_sitemap_entries.len() < sitemap_limit { if all_sitemap_entries.len() < sitemap_limit {

View File

@ -5,6 +5,7 @@ use std::collections::{HashSet};
use tera::{Map, Value}; use tera::{Map, Value};
use config::{Config}; use config::{Config};
use library::{Library, Taxonomy}; use library::{Library, Taxonomy};
use std::cmp::Ordering;
/// The sitemap only needs links, potentially date and extra for pages in case of updates /// The sitemap only needs links, potentially date and extra for pages in case of updates
/// for examples so we trim down all entries to only that /// for examples so we trim down all entries to only that
@ -39,6 +40,18 @@ impl<'a> SitemapEntry<'a> {
} }
} }
impl<'a> PartialOrd for SitemapEntry<'a> {
fn partial_cmp(&self, other: &SitemapEntry) -> Option<Ordering> {
Some(self.permalink.as_ref().cmp(other.permalink.as_ref()))
}
}
impl<'a> Ord for SitemapEntry<'a> {
fn cmp(&self, other: &SitemapEntry) -> Ordering {
self.permalink.as_ref().cmp(other.permalink.as_ref())
}
}
/// Finds out all the links to put in a sitemap from the pages/sections/taxonomies /// Finds out all the links to put in a sitemap from the pages/sections/taxonomies
/// There are no duplicate permalinks in the output vec /// There are no duplicate permalinks in the output vec
pub fn find_entries<'a>(library: &'a Library, taxonomies: &'a [Taxonomy], config: &'a Config) -> Vec<SitemapEntry<'a>> { pub fn find_entries<'a>(library: &'a Library, taxonomies: &'a [Taxonomy], config: &'a Config) -> Vec<SitemapEntry<'a>> {

View File

@ -1,4 +1,4 @@
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"> <urlset xmlns="https://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
{% for sitemap_entry in entries %} {% for sitemap_entry in entries %}
<url> <url>
<loc>{{ sitemap_entry.permalink | safe }}</loc> <loc>{{ sitemap_entry.permalink | safe }}</loc>

View File

@ -1,4 +1,4 @@
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"> <sitemapindex xmlns="https://www.sitemaps.org/schemas/sitemap/0.9/siteindex.xsd">
{% for sitemap in sitemaps %} {% for sitemap in sitemaps %}
<sitemap> <sitemap>
<loc>{{ sitemap }}</loc> <loc>{{ sitemap }}</loc>

View File

@ -431,6 +431,7 @@ mod tests {
json!({ json!({
"category": { "category": {
"date": "1979-05-27T07:32:00Z", "date": "1979-05-27T07:32:00Z",
"lt1": "07:32:00",
"key": "value" "key": "value"
}, },
}) })

View File

@ -1,3 +1,4 @@
[category] [category]
key = "value" key = "value"
date = 1979-05-27T07:32:00Z date = 1979-05-27T07:32:00Z
lt1 = 07:32:00

View File

@ -36,14 +36,6 @@ $ 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 This is useful for example when you want to deploy previews of a site to a dynamic URL, such as Netlify
deploy previews. 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. You can override the default output directory 'public' by passing a other value to the `output-dir` flag.
```bash ```bash
@ -75,7 +67,6 @@ $ zola serve --interface 0.0.0.0
$ zola serve --interface 0.0.0.0 --port 2000 $ 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 --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 --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 $ zola serve --watch-only
``` ```

3
is-ehh.svg Normal file
View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" style="fill:#dbab09" width="16" height="16" viewBox="0 0 24 24">
<circle cx="12" cy="12" r="8"/>
</svg>

After

Width:  |  Height:  |  Size: 146 B

3
is-no.svg Normal file
View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" style="fill:#cb2431" width="16" height="16" viewBox="0 0 24 24">
<path d="M23 20.168l-8.185-8.187 8.185-8.174-2.832-2.807-8.182 8.179-8.176-8.179-2.81 2.81 8.186 8.196-8.186 8.184 2.81 2.81 8.203-8.192 8.18 8.192z"/>
</svg>

After

Width:  |  Height:  |  Size: 266 B

3
is-yes.svg Normal file
View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" style="fill:#28a745" width="16" height="16" viewBox="0 0 24 24">
<path d="M9 21.035l-9-8.638 2.791-2.87 6.156 5.874 12.21-12.436 2.843 2.817z"/>
</svg>

After

Width:  |  Height:  |  Size: 194 B

View File

@ -30,11 +30,6 @@ pub fn build_cli() -> App<'static, 'static> {
.long("base-url") .long("base-url")
.takes_value(true) .takes_value(true)
.help("Force the base URL to be that value (default to the one in config.toml)"), .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") Arg::with_name("output_dir")
.short("o") .short("o")
.long("output-dir") .long("output-dir")
@ -61,11 +56,6 @@ pub fn build_cli() -> App<'static, 'static> {
.default_value("public") .default_value("public")
.takes_value(true) .takes_value(true)
.help("Outputs the generated site in the given path"), .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") Arg::with_name("base_url")
.short("u") .short("u")
.long("base-url") .long("base-url")

View File

@ -1,19 +1,12 @@
use std::env; use std::env;
use std::path::PathBuf;
use errors::Result; use errors::Result;
use site::Site; use site::Site;
use console; use console;
pub fn build( pub fn build(config_file: &str, base_url: Option<&str>, output_dir: &str) -> Result<()> {
config_file: &str, let mut site = Site::new(env::current_dir().unwrap(), config_file)?;
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); site.set_output_path(output_dir);
if let Some(b) = base_url { if let Some(b) = base_url {
site.set_base_url(b.to_string()); site.set_base_url(b.to_string());

View File

@ -86,8 +86,8 @@ impl<S> Middleware<S> for NotFoundHandler {
} }
} }
fn livereload_handler(_: &HttpRequest) -> &'static str { fn livereload_handler(_: &HttpRequest) -> HttpResponse {
LIVE_RELOAD HttpResponse::Ok().content_type("text/javascript").body(LIVE_RELOAD)
} }
fn rebuild_done_handling(broadcaster: &Option<Sender>, res: Result<()>, reload_path: &str) { fn rebuild_done_handling(broadcaster: &Option<Sender>, res: Result<()>, reload_path: &str) {
@ -114,15 +114,14 @@ fn rebuild_done_handling(broadcaster: &Option<Sender>, res: Result<()>, reload_p
} }
} }
fn create_new_site<P: AsRef<Path>>( fn create_new_site(
interface: &str, interface: &str,
port: u16, port: u16,
output_dir: &str, output_dir: &str,
base_path: P,
base_url: &str, base_url: &str,
config_file: &str, config_file: &str,
) -> Result<(Site, String)> { ) -> Result<(Site, String)> {
let mut site = Site::new(base_path, config_file)?; let mut site = Site::new(env::current_dir().unwrap(), config_file)?;
let base_address = format!("{}:{}", base_url, port); let base_address = format!("{}:{}", base_url, port);
let address = format!("{}:{}", interface, port); let address = format!("{}:{}", interface, port);
@ -167,15 +166,12 @@ pub fn serve(
interface: &str, interface: &str,
port: u16, port: u16,
output_dir: &str, output_dir: &str,
base_path: Option<&str>,
base_url: &str, base_url: &str,
config_file: &str, config_file: &str,
watch_only: bool, watch_only: bool,
) -> Result<()> { ) -> Result<()> {
let start = Instant::now(); let start = Instant::now();
let bp = base_path.map(PathBuf::from).unwrap_or(env::current_dir().unwrap()); let (mut site, address) = create_new_site(interface, port, output_dir, base_url, config_file)?;
let (mut site, address) =
create_new_site(interface, port, output_dir, bp.clone(), base_url, config_file)?;
console::report_elapsed_time(start); console::report_elapsed_time(start);
// Setup watchers // Setup watchers
@ -184,28 +180,28 @@ pub fn serve(
let (tx, rx) = channel(); let (tx, rx) = channel();
let mut watcher = watcher(tx, Duration::from_secs(1)).unwrap(); let mut watcher = watcher(tx, Duration::from_secs(1)).unwrap();
watcher watcher
.watch(bp.join("content/"), RecursiveMode::Recursive) .watch("content/", RecursiveMode::Recursive)
.map_err(|e| ZolaError::chain("Can't watch the `content` folder. Does it exist?", e))?; .map_err(|e| ZolaError::chain("Can't watch the `content` folder. Does it exist?", e))?;
watcher watcher
.watch(bp.join(config_file), RecursiveMode::Recursive) .watch(config_file, RecursiveMode::Recursive)
.map_err(|e| ZolaError::chain("Can't watch the `config` file. Does it exist?", e))?; .map_err(|e| ZolaError::chain("Can't watch the `config` file. Does it exist?", e))?;
if bp.join("static").exists() { if Path::new("static").exists() {
watching_static = true; watching_static = true;
watcher watcher
.watch(bp.join("static/"), RecursiveMode::Recursive) .watch("static/", RecursiveMode::Recursive)
.map_err(|e| ZolaError::chain("Can't watch the `static` folder.", e))?; .map_err(|e| ZolaError::chain("Can't watch the `static` folder.", e))?;
} }
if bp.join("templates").exists() { if Path::new("templates").exists() {
watching_templates = true; watching_templates = true;
watcher watcher
.watch(bp.join("templates/"), RecursiveMode::Recursive) .watch("templates/", RecursiveMode::Recursive)
.map_err(|e| ZolaError::chain("Can't watch the `templates` folder.", e))?; .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 // Sass support is optional so don't make it an error to no have a sass folder
let _ = watcher.watch(bp.join("sass/"), RecursiveMode::Recursive); let _ = watcher.watch("sass/", RecursiveMode::Recursive);
let ws_address = format!("{}:{}", interface, site.live_reload.unwrap()); let ws_address = format!("{}:{}", interface, site.live_reload.unwrap());
let output_path = Path::new(output_dir).to_path_buf(); let output_path = Path::new(output_dir).to_path_buf();
@ -262,6 +258,8 @@ pub fn serve(
None None
}; };
let pwd = env::current_dir().unwrap();
let mut watchers = vec!["content", "config.toml"]; let mut watchers = vec!["content", "config.toml"];
if watching_static { if watching_static {
watchers.push("static"); watchers.push("static");
@ -275,7 +273,7 @@ pub fn serve(
println!( println!(
"Listening for changes in {}{}{{{}}}", "Listening for changes in {}{}{{{}}}",
bp.display(), pwd.display(),
MAIN_SEPARATOR, MAIN_SEPARATOR,
watchers.join(", ") watchers.join(", ")
); );
@ -351,8 +349,7 @@ pub fn serve(
if path.is_file() && is_temp_file(&path) { if path.is_file() && is_temp_file(&path) {
continue; continue;
} }
let (change_kind, partial_path) = let (change_kind, partial_path) = detect_change_kind(&pwd, &path);
detect_change_kind(&bp.canonicalize().unwrap(), &path);
// We only care about changes in non-empty folders // We only care about changes in non-empty folders
if path.is_dir() && is_folder_empty(&path) { if path.is_dir() && is_folder_empty(&path) {
@ -384,7 +381,6 @@ pub fn serve(
interface, interface,
port, port,
output_dir, output_dir,
bp.clone(),
base_url, base_url,
config_file, config_file,
) )
@ -405,7 +401,7 @@ pub fn serve(
); );
let start = Instant::now(); let start = Instant::now();
match detect_change_kind(&bp.canonicalize().unwrap(), &path) { match detect_change_kind(&pwd, &path) {
(ChangeKind::Content, _) => { (ChangeKind::Content, _) => {
console::info(&format!("-> Content changed {}", path.display())); console::info(&format!("-> Content changed {}", path.display()));
// Force refresh // Force refresh
@ -424,7 +420,6 @@ pub fn serve(
interface, interface,
port, port,
output_dir, output_dir,
bp.clone(),
base_url, base_url,
config_file, config_file,
) )

View File

@ -46,12 +46,7 @@ fn main() {
console::info("Building site..."); console::info("Building site...");
let start = Instant::now(); let start = Instant::now();
let output_dir = matches.value_of("output_dir").unwrap(); let output_dir = matches.value_of("output_dir").unwrap();
match cmd::build( match cmd::build(config_file, matches.value_of("base_url"), output_dir) {
config_file,
matches.value_of("base_path"),
matches.value_of("base_url"),
output_dir,
) {
Ok(()) => console::report_elapsed_time(start), Ok(()) => console::report_elapsed_time(start),
Err(e) => { Err(e) => {
console::unravel_errors("Failed to build the site", &e); console::unravel_errors("Failed to build the site", &e);
@ -84,18 +79,9 @@ fn main() {
} }
let watch_only = matches.is_present("watch_only"); let watch_only = matches.is_present("watch_only");
let output_dir = matches.value_of("output_dir").unwrap(); 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(); let base_url = matches.value_of("base_url").unwrap();
console::info("Building site..."); console::info("Building site...");
match cmd::serve( match cmd::serve(interface, port, output_dir, base_url, config_file, watch_only) {
interface,
port,
output_dir,
base_path,
base_url,
config_file,
watch_only,
) {
Ok(()) => (), Ok(()) => (),
Err(e) => { Err(e) => {
console::unravel_errors("", &e); console::unravel_errors("", &e);