You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

107 lines
3.2KB

  1. use std::env;
  2. use std::io::Write;
  3. use std::time::Instant;
  4. use atty;
  5. use chrono::Duration;
  6. use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor};
  7. use errors::Error;
  8. use site::Site;
  9. lazy_static! {
  10. /// Termcolor color choice.
  11. /// We do not rely on ColorChoice::Auto behavior
  12. /// as the check is already performed by has_color.
  13. static ref COLOR_CHOICE: ColorChoice =
  14. if has_color() {
  15. ColorChoice::Always
  16. } else {
  17. ColorChoice::Never
  18. };
  19. }
  20. pub fn info(message: &str) {
  21. colorize(message, ColorSpec::new().set_bold(true));
  22. }
  23. pub fn warn(message: &str) {
  24. colorize(message, ColorSpec::new().set_bold(true).set_fg(Some(Color::Yellow)));
  25. }
  26. pub fn success(message: &str) {
  27. colorize(message, ColorSpec::new().set_bold(true).set_fg(Some(Color::Green)));
  28. }
  29. pub fn error(message: &str) {
  30. colorize(message, ColorSpec::new().set_bold(true).set_fg(Some(Color::Red)));
  31. }
  32. /// Print a colorized message to stdout
  33. fn colorize(message: &str, color: &ColorSpec) {
  34. let mut stdout = StandardStream::stdout(*COLOR_CHOICE);
  35. stdout.set_color(color).unwrap();
  36. writeln!(&mut stdout, "{}", message).unwrap();
  37. }
  38. /// Display in the console the number of pages/sections in the site
  39. pub fn notify_site_size(site: &Site) {
  40. println!(
  41. "-> Creating {} pages ({} orphan), {} sections, and processing {} images",
  42. site.pages.len(),
  43. site.get_all_orphan_pages().len(),
  44. site.sections.len() - 1, // -1 since we do not the index as a section
  45. site.num_img_ops(),
  46. );
  47. }
  48. /// Display a warning in the console if there are ignored pages in the site
  49. pub fn warn_about_ignored_pages(site: &Site) {
  50. let ignored_pages: Vec<_> = site.sections
  51. .values()
  52. .flat_map(|s| s.ignored_pages.iter().map(|p| p.file.path.clone()))
  53. .collect();
  54. if !ignored_pages.is_empty() {
  55. warn(&format!(
  56. "{} page(s) ignored (missing date or weight in a sorted section):",
  57. ignored_pages.len()
  58. ));
  59. for path in ignored_pages {
  60. warn(&format!("- {}", path.display()));
  61. }
  62. }
  63. }
  64. /// Print the time elapsed rounded to 1 decimal
  65. pub fn report_elapsed_time(instant: Instant) {
  66. let duration_ms = Duration::from_std(instant.elapsed()).unwrap().num_milliseconds() as f64;
  67. if duration_ms < 1000.0 {
  68. success(&format!("Done in {}ms.\n", duration_ms));
  69. } else {
  70. let duration_sec = duration_ms / 1000.0;
  71. success(&format!("Done in {:.1}s.\n", ((duration_sec * 10.0).round() / 10.0)));
  72. }
  73. }
  74. /// Display an error message and the actual error(s)
  75. pub fn unravel_errors(message: &str, error: &Error) {
  76. if !message.is_empty() {
  77. self::error(message);
  78. }
  79. self::error(&format!("Error: {}", error));
  80. for e in error.iter().skip(1) {
  81. self::error(&format!("Reason: {}", e));
  82. }
  83. }
  84. /// Check whether to output colors
  85. fn has_color() -> bool {
  86. let use_colors = env::var("CLICOLOR").unwrap_or_else(|_| "1".to_string()) != "0" && env::var("NO_COLOR").is_err();
  87. let force_colors = env::var("CLICOLOR_FORCE").unwrap_or_else(|_|"0".to_string()) != "0";
  88. force_colors || use_colors && atty::is(atty::Stream::Stdout)
  89. }