@@ -15,6 +15,13 @@ use utils::fs::read_file_with_error; | |||||
// We want a default base url for tests | // We want a default base url for tests | ||||
static DEFAULT_BASE_URL: &'static str = "http://a-website.com"; | static DEFAULT_BASE_URL: &'static str = "http://a-website.com"; | ||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] | |||||
pub enum Mode { | |||||
Build, | |||||
Serve, | |||||
Check, | |||||
} | |||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] | #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] | ||||
#[serde(default)] | #[serde(default)] | ||||
pub struct Language { | pub struct Language { | ||||
@@ -122,8 +129,10 @@ pub struct Config { | |||||
#[serde(skip_serializing, skip_deserializing)] // not a typo, 2 are needed | #[serde(skip_serializing, skip_deserializing)] // not a typo, 2 are needed | ||||
pub ignored_content_globset: Option<GlobSet>, | pub ignored_content_globset: Option<GlobSet>, | ||||
/// Whether to check all external links for validity | |||||
pub check_external_links: bool, | |||||
/// The mode Zola is currently being ran on. Some logging/feature can differ depending on the | |||||
/// command being used. | |||||
#[serde(skip_serializing)] | |||||
pub mode: Mode, | |||||
/// A list of directories to search for additional `.sublime-syntax` files in. | /// A list of directories to search for additional `.sublime-syntax` files in. | ||||
pub extra_syntaxes: Vec<String>, | pub extra_syntaxes: Vec<String>, | ||||
@@ -267,6 +276,29 @@ impl Config { | |||||
pub fn languages_codes(&self) -> Vec<&str> { | pub fn languages_codes(&self) -> Vec<&str> { | ||||
self.languages.iter().map(|l| l.code.as_ref()).collect() | self.languages.iter().map(|l| l.code.as_ref()).collect() | ||||
} | } | ||||
pub fn is_in_build_mode(&self) -> bool { | |||||
self.mode == Mode::Build | |||||
} | |||||
pub fn is_in_serve_mode(&self) -> bool { | |||||
self.mode == Mode::Serve | |||||
} | |||||
pub fn is_in_check_mode(&self) -> bool { | |||||
self.mode == Mode::Check | |||||
} | |||||
pub fn enable_serve_mode(&mut self) { | |||||
self.mode = Mode::Serve; | |||||
} | |||||
pub fn enable_check_mode(&mut self) { | |||||
self.mode = Mode::Check; | |||||
// Disable syntax highlighting since the results won't be used | |||||
// and this operation can be expensive. | |||||
self.highlight_code = false; | |||||
} | |||||
} | } | ||||
impl Default for Config { | impl Default for Config { | ||||
@@ -285,7 +317,7 @@ impl Default for Config { | |||||
hard_link_static: false, | hard_link_static: false, | ||||
taxonomies: Vec::new(), | taxonomies: Vec::new(), | ||||
compile_sass: false, | compile_sass: false, | ||||
check_external_links: false, | |||||
mode: Mode::Build, | |||||
build_search_index: false, | build_search_index: false, | ||||
ignored_content: Vec::new(), | ignored_content: Vec::new(), | ||||
ignored_content_globset: None, | ignored_content_globset: None, | ||||
@@ -250,7 +250,7 @@ impl Site { | |||||
// Needs to be done after rendering markdown as we only get the anchors at that point | // Needs to be done after rendering markdown as we only get the anchors at that point | ||||
self.check_internal_links_with_anchors()?; | self.check_internal_links_with_anchors()?; | ||||
if self.config.check_external_links { | |||||
if self.config.is_in_check_mode() { | |||||
self.check_external_links()?; | self.check_external_links()?; | ||||
} | } | ||||
@@ -278,6 +278,15 @@ impl Site { | |||||
}) | }) | ||||
.flatten(); | .flatten(); | ||||
let all_links = page_links.chain(section_links).collect::<Vec<_>>(); | let all_links = page_links.chain(section_links).collect::<Vec<_>>(); | ||||
if self.config.is_in_check_mode() { | |||||
println!("Checking {} internal link(s) with an anchor.", all_links.len()); | |||||
} | |||||
if all_links.is_empty() { | |||||
return Ok(()); | |||||
} | |||||
let mut full_path = self.base_path.clone(); | let mut full_path = self.base_path.clone(); | ||||
full_path.push("content"); | full_path.push("content"); | ||||
@@ -311,9 +320,15 @@ impl Site { | |||||
} | } | ||||
}) | }) | ||||
.collect(); | .collect(); | ||||
if self.config.is_in_check_mode() { | |||||
println!("> Checked {} internal link(s) with an anchor: {} error(s) found.", all_links.len(), errors.len()); | |||||
} | |||||
if errors.is_empty() { | if errors.is_empty() { | ||||
return Ok(()); | return Ok(()); | ||||
} | } | ||||
let msg = errors | let msg = errors | ||||
.into_iter() | .into_iter() | ||||
.map(|(page_path, md_path, anchor)| { | .map(|(page_path, md_path, anchor)| { | ||||
@@ -348,6 +363,11 @@ impl Site { | |||||
}) | }) | ||||
.flatten(); | .flatten(); | ||||
let all_links = page_links.chain(section_links).collect::<Vec<_>>(); | let all_links = page_links.chain(section_links).collect::<Vec<_>>(); | ||||
println!("Checking {} external link(s).", all_links.len()); | |||||
if all_links.is_empty() { | |||||
return Ok(()); | |||||
} | |||||
// create thread pool with lots of threads so we can fetch | // create thread pool with lots of threads so we can fetch | ||||
// (almost) all pages simultaneously | // (almost) all pages simultaneously | ||||
@@ -371,9 +391,12 @@ impl Site { | |||||
.collect() | .collect() | ||||
}); | }); | ||||
println!("> Checked {} external link(s): {} error(s) found.", all_links.len(), errors.len()); | |||||
if errors.is_empty() { | if errors.is_empty() { | ||||
return Ok(()); | return Ok(()); | ||||
} | } | ||||
let msg = errors | let msg = errors | ||||
.into_iter() | .into_iter() | ||||
.map(|(page_path, link, check_res)| { | .map(|(page_path, link, check_res)| { | ||||
@@ -10,15 +10,12 @@ pub fn check(config_file: &str, base_path: Option<&str>, base_url: Option<&str>) | |||||
let bp = base_path.map(PathBuf::from).unwrap_or_else(|| env::current_dir().unwrap()); | let bp = base_path.map(PathBuf::from).unwrap_or_else(|| env::current_dir().unwrap()); | ||||
let mut site = Site::new(bp, config_file)?; | let mut site = Site::new(bp, config_file)?; | ||||
// Force the checking of external links | // Force the checking of external links | ||||
site.config.check_external_links = true; | |||||
// Disable syntax highlighting since the results won't be used | |||||
// and this operation can be expensive. | |||||
site.config.highlight_code = false; | |||||
site.config.enable_check_mode(); | |||||
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()); | ||||
} | } | ||||
site.load()?; | site.load()?; | ||||
console::notify_site_size(&site); | |||||
console::notify_site_size_simple(&site); | |||||
console::warn_about_ignored_pages(&site); | console::warn_about_ignored_pages(&site); | ||||
Ok(()) | Ok(()) | ||||
} | } |
@@ -46,7 +46,7 @@ fn colorize(message: &str, color: &ColorSpec) { | |||||
stdout.set_color(&ColorSpec::new()).unwrap(); | stdout.set_color(&ColorSpec::new()).unwrap(); | ||||
} | } | ||||
/// Display in the console the number of pages/sections in the site | |||||
/// Display in the console the number of pages/sections in the site, and number of images to process | |||||
pub fn notify_site_size(site: &Site) { | pub fn notify_site_size(site: &Site) { | ||||
let library = site.library.read().unwrap(); | let library = site.library.read().unwrap(); | ||||
println!( | println!( | ||||
@@ -58,6 +58,17 @@ pub fn notify_site_size(site: &Site) { | |||||
); | ); | ||||
} | } | ||||
/// Display in the console only the number of pages/sections in the site | |||||
pub fn notify_site_size_simple(site: &Site) { | |||||
let library = site.library.read().unwrap(); | |||||
println!( | |||||
"-> {} pages ({} orphan), {} sections", | |||||
library.pages().len(), | |||||
site.get_number_orphan_pages(), | |||||
library.sections().len() - 1, // -1 since we do not count the index as a section there | |||||
); | |||||
} | |||||
/// Display a warning in the console if there are ignored pages in the site | /// Display a warning in the console if there are ignored pages in the site | ||||
pub fn warn_about_ignored_pages(site: &Site) { | pub fn warn_about_ignored_pages(site: &Site) { | ||||
let library = site.library.read().unwrap(); | let library = site.library.read().unwrap(); | ||||