parent
502dd92cc6
commit
0f23a40e3f
93
Cargo.lock
generated
93
Cargo.lock
generated
@ -291,12 +291,51 @@ dependencies = [
|
||||
"ansi_term",
|
||||
"atty",
|
||||
"bitflags",
|
||||
"strsim",
|
||||
"textwrap",
|
||||
"strsim 0.8.0",
|
||||
"textwrap 0.11.0",
|
||||
"unicode-width",
|
||||
"vec_map",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "3.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d17bf219fcd37199b9a29e00ba65dfb8cd5b2688b7297ec14ff829c40ac50ca9"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"bitflags",
|
||||
"clap_derive",
|
||||
"indexmap",
|
||||
"lazy_static",
|
||||
"os_str_bytes",
|
||||
"strsim 0.10.0",
|
||||
"termcolor",
|
||||
"textwrap 0.14.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_complete"
|
||||
version = "3.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0e3cb395a9ef3c4ddabee9d6a0d0419b107cccf3e431fc0015df90f24849386c"
|
||||
dependencies = [
|
||||
"clap 3.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_derive"
|
||||
version = "3.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e1b9752c030a14235a0bd5ef3ad60a1dcac8468c30921327fc8af36b20c790b9"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro-error",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "color_quant"
|
||||
version = "1.1.0"
|
||||
@ -1350,7 +1389,7 @@ dependencies = [
|
||||
"anyhow",
|
||||
"bincode",
|
||||
"byteorder",
|
||||
"clap",
|
||||
"clap 2.34.0",
|
||||
"encoding",
|
||||
"glob",
|
||||
"lindera-core",
|
||||
@ -1892,6 +1931,15 @@ dependencies = [
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "os_str_bytes"
|
||||
version = "6.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e22443d1643a904602595ba1cd8f7d896afe56d26712531c5ff73a15b2fbf64"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.11.2"
|
||||
@ -2120,6 +2168,30 @@ version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
|
||||
dependencies = [
|
||||
"proc-macro-error-attr",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error-attr"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.36"
|
||||
@ -2754,6 +2826,12 @@ version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
||||
|
||||
[[package]]
|
||||
name = "strum"
|
||||
version = "0.21.0"
|
||||
@ -2933,6 +3011,12 @@ dependencies = [
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "textwrap"
|
||||
version = "0.14.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0066c8d12af8b5acd21e00547c3797fde4e8677254a7ee429176ccebbe93dd80"
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.30"
|
||||
@ -3590,7 +3674,8 @@ version = "0.16.0"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"chrono",
|
||||
"clap",
|
||||
"clap 3.0.0",
|
||||
"clap_complete",
|
||||
"ctrlc",
|
||||
"errors",
|
||||
"front_matter",
|
||||
|
||||
@ -13,14 +13,15 @@ keywords = ["static", "site", "generator", "blog"]
|
||||
include = ["src/**/*", "LICENSE", "README.md"]
|
||||
|
||||
[build-dependencies]
|
||||
clap = "2"
|
||||
clap = "3"
|
||||
clap_complete = "3"
|
||||
|
||||
[[bin]]
|
||||
name = "zola"
|
||||
|
||||
[dependencies]
|
||||
atty = "0.2.11"
|
||||
clap = { version = "2", default-features = false }
|
||||
clap = { version = "3", features = ["derive"] }
|
||||
chrono = "0.4"
|
||||
lazy_static = "1.1"
|
||||
termcolor = "1.0.4"
|
||||
|
||||
@ -21,7 +21,7 @@ stages:
|
||||
rustup_toolchain: stable
|
||||
linux-pinned:
|
||||
imageName: 'ubuntu-20.04'
|
||||
rustup_toolchain: 1.53.0
|
||||
rustup_toolchain: 1.54.0
|
||||
pool:
|
||||
vmImage: $(imageName)
|
||||
steps:
|
||||
|
||||
184
src/cli.rs
184
src/cli.rs
@ -1,102 +1,86 @@
|
||||
use clap::{crate_authors, crate_description, crate_version, App, AppSettings, Arg, SubCommand};
|
||||
use std::path::PathBuf;
|
||||
|
||||
pub fn build_cli() -> App<'static, 'static> {
|
||||
App::new("zola")
|
||||
.version(crate_version!())
|
||||
.author(crate_authors!())
|
||||
.about(crate_description!())
|
||||
.setting(AppSettings::SubcommandRequiredElseHelp)
|
||||
.arg(
|
||||
Arg::with_name("root")
|
||||
.short("r")
|
||||
.long("root")
|
||||
.takes_value(true)
|
||||
.default_value(".")
|
||||
.help("Directory to use as root of project")
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("config")
|
||||
.short("c")
|
||||
.long("config")
|
||||
.takes_value(true)
|
||||
.help("Path to a config file other than config.toml in the root of project")
|
||||
)
|
||||
.subcommands(vec![
|
||||
SubCommand::with_name("init")
|
||||
.about("Create a new Zola project")
|
||||
.args(&[
|
||||
Arg::with_name("name")
|
||||
.default_value(".")
|
||||
.help("Name of the project. Will create a new directory with that name in the current directory"),
|
||||
Arg::with_name("force")
|
||||
.short("f")
|
||||
.long("force")
|
||||
.takes_value(false)
|
||||
.help("Force creation of project even if directory is non-empty")
|
||||
]),
|
||||
SubCommand::with_name("build")
|
||||
.about("Deletes the output directory if there is one and builds the site")
|
||||
.args(&[
|
||||
Arg::with_name("base_url")
|
||||
.short("u")
|
||||
.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("output_dir")
|
||||
.short("o")
|
||||
.long("output-dir")
|
||||
.takes_value(true)
|
||||
.help("Outputs the generated site in the given path (by default 'public' dir in project root)"),
|
||||
Arg::with_name("drafts")
|
||||
.long("drafts")
|
||||
.takes_value(false)
|
||||
.help("Include drafts when loading the site"),
|
||||
]),
|
||||
SubCommand::with_name("serve")
|
||||
.about("Serve the site. Rebuild and reload on change automatically")
|
||||
.args(&[
|
||||
Arg::with_name("interface")
|
||||
.short("i")
|
||||
.long("interface")
|
||||
.takes_value(true)
|
||||
.help("Interface to bind on (default: 127.0.0.1)"),
|
||||
Arg::with_name("port")
|
||||
.short("p")
|
||||
.long("port")
|
||||
.takes_value(true)
|
||||
.help("Which port to use (default: 1111)"),
|
||||
Arg::with_name("output_dir")
|
||||
.short("o")
|
||||
.long("output-dir")
|
||||
.takes_value(true)
|
||||
.help("Outputs assets of the generated site in the given path (by default 'public' dir in project root). HTML/XML will be stored in memory."),
|
||||
Arg::with_name("base_url")
|
||||
.short("u")
|
||||
.long("base-url")
|
||||
.takes_value(true)
|
||||
.help("Changes the base_url (default: 127.0.0.1)"),
|
||||
Arg::with_name("drafts")
|
||||
.long("drafts")
|
||||
.takes_value(false)
|
||||
.help("Include drafts when loading the site"),
|
||||
Arg::with_name("open")
|
||||
.short("O")
|
||||
.long("open")
|
||||
.takes_value(false)
|
||||
.help("Open site in the default browser"),
|
||||
Arg::with_name("fast")
|
||||
.short("f")
|
||||
.long("fast")
|
||||
.takes_value(false)
|
||||
.help("Only rebuild the minimum on change - useful when working on a specific page/section"),
|
||||
]),
|
||||
SubCommand::with_name("check")
|
||||
.about("Try building the project without rendering it. Checks links")
|
||||
.args(&[
|
||||
Arg::with_name("drafts")
|
||||
.long("drafts")
|
||||
.takes_value(false)
|
||||
.help("Include drafts when loading the site"),
|
||||
])
|
||||
])
|
||||
use clap::{Parser, Subcommand};
|
||||
|
||||
#[derive(Parser)]
|
||||
#[clap(version, author, about)]
|
||||
pub struct Cli {
|
||||
/// Directory to use as root of project
|
||||
#[clap(short = 'r', long, default_value = ".")]
|
||||
pub root: PathBuf,
|
||||
|
||||
/// Path to a config file other than config.toml in the root of project
|
||||
#[clap(short = 'c', long)]
|
||||
pub config: Option<PathBuf>,
|
||||
|
||||
#[clap(subcommand)]
|
||||
pub command: Command,
|
||||
}
|
||||
|
||||
#[derive(Subcommand)]
|
||||
pub enum Command {
|
||||
/// Create a new Zola project
|
||||
Init {
|
||||
/// Name of the project. Will create a new directory with that name in the current directory
|
||||
#[clap(default_value = ".")]
|
||||
name: String,
|
||||
|
||||
/// Force creation of project even if directory is non-empty
|
||||
#[clap(short = 'f', long)]
|
||||
force: bool,
|
||||
},
|
||||
|
||||
/// Deletes the output directory if there is one and builds the site
|
||||
Build {
|
||||
/// Force the base URL to be that value (defaults to the one in config.toml)
|
||||
#[clap(short = 'u', long)]
|
||||
base_url: Option<String>,
|
||||
|
||||
/// Outputs the generated site in the given path (by default 'public' dir in project root)
|
||||
#[clap(short = 'o', long)]
|
||||
output_dir: Option<PathBuf>,
|
||||
|
||||
/// Include drafts when loading the site
|
||||
#[clap(long)]
|
||||
drafts: bool,
|
||||
},
|
||||
|
||||
/// Serve the site. Rebuild and reload on change automatically
|
||||
Serve {
|
||||
/// Interface to bind on
|
||||
#[clap(short = 'i', long, default_value = "127.0.0.1")]
|
||||
interface: String,
|
||||
|
||||
/// Which port to use
|
||||
#[clap(short = 'p', long, default_value_t = 1111)]
|
||||
port: u16,
|
||||
|
||||
/// Outputs assets of the generated site in the given path (by default 'public' dir in project root).
|
||||
/// HTML/XML will be stored in memory.
|
||||
#[clap(short = 'o', long)]
|
||||
output_dir: Option<PathBuf>,
|
||||
|
||||
/// Changes the base_url
|
||||
#[clap(short = 'u', long, default_value = "127.0.0.1")]
|
||||
base_url: String,
|
||||
|
||||
/// Include drafts when loading the site
|
||||
#[clap(long)]
|
||||
drafts: bool,
|
||||
|
||||
/// Open site in the default browser
|
||||
#[clap(short = 'O', long)]
|
||||
open: bool,
|
||||
|
||||
/// Only rebuild the minimum on change - useful when working on a specific page/section
|
||||
#[clap(short = 'f', long)]
|
||||
fast: bool,
|
||||
},
|
||||
|
||||
/// Try to build the project without rendering it. Checks links
|
||||
Check {
|
||||
/// Include drafts when loading the site
|
||||
#[clap(long)]
|
||||
drafts: bool,
|
||||
},
|
||||
}
|
||||
|
||||
124
src/main.rs
124
src/main.rs
@ -1,124 +1,92 @@
|
||||
use std::env;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::time::Instant;
|
||||
|
||||
use cli::{Cli, Command};
|
||||
use utils::net::{get_available_port, port_is_available};
|
||||
|
||||
use clap::Parser;
|
||||
|
||||
mod cli;
|
||||
mod cmd;
|
||||
mod console;
|
||||
mod prompt;
|
||||
|
||||
fn main() {
|
||||
let matches = cli::build_cli().get_matches();
|
||||
let cli = Cli::parse();
|
||||
let root_dir = cli
|
||||
.root
|
||||
.canonicalize()
|
||||
.unwrap_or_else(|_| panic!("Cannot find root directory: {}", cli.root.display()));
|
||||
let config_file = cli
|
||||
.config
|
||||
.map(|path| {
|
||||
path.canonicalize()
|
||||
.unwrap_or_else(|_| panic!("Cannot find config file: {}", path.display()))
|
||||
})
|
||||
.unwrap_or_else(|| root_dir.join("config.toml"));
|
||||
|
||||
let root_dir = match matches.value_of("root").unwrap() {
|
||||
"." => env::current_dir().unwrap(),
|
||||
path => PathBuf::from(path)
|
||||
.canonicalize()
|
||||
.unwrap_or_else(|_| panic!("Cannot find root directory: {}", path)),
|
||||
};
|
||||
let config_file = match matches.value_of("config") {
|
||||
Some(path) => PathBuf::from(path)
|
||||
.canonicalize()
|
||||
.unwrap_or_else(|_| panic!("Cannot find config file: {}", path)),
|
||||
None => root_dir.join("config.toml"),
|
||||
};
|
||||
|
||||
match matches.subcommand() {
|
||||
("init", Some(matches)) => {
|
||||
let force = matches.is_present("force");
|
||||
match cmd::create_new_project(matches.value_of("name").unwrap(), force) {
|
||||
Ok(()) => (),
|
||||
Err(e) => {
|
||||
console::unravel_errors("Failed to create the project", &e);
|
||||
::std::process::exit(1);
|
||||
}
|
||||
};
|
||||
match cli.command {
|
||||
Command::Init { name, force } => {
|
||||
if let Err(e) = cmd::create_new_project(&name, force) {
|
||||
console::unravel_errors("Failed to create the proejct", &e);
|
||||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
("build", Some(matches)) => {
|
||||
Command::Build { base_url, output_dir, drafts } => {
|
||||
console::info("Building site...");
|
||||
let start = Instant::now();
|
||||
let output_dir = matches.value_of("output_dir").map(|output_dir| Path::new(output_dir));
|
||||
match cmd::build(
|
||||
&root_dir,
|
||||
&config_file,
|
||||
matches.value_of("base_url"),
|
||||
output_dir,
|
||||
matches.is_present("drafts"),
|
||||
base_url.as_deref(),
|
||||
output_dir.as_deref(),
|
||||
drafts,
|
||||
) {
|
||||
Ok(()) => console::report_elapsed_time(start),
|
||||
Err(e) => {
|
||||
console::unravel_errors("Failed to build the site", &e);
|
||||
::std::process::exit(1);
|
||||
std::process::exit(1);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
("serve", Some(matches)) => {
|
||||
let interface = matches.value_of("interface").unwrap_or("127.0.0.1");
|
||||
let mut port: u16 = match matches.value_of("port").unwrap_or("1111").parse() {
|
||||
Ok(x) => x,
|
||||
Err(_) => {
|
||||
console::error("The request port needs to be an integer");
|
||||
::std::process::exit(1);
|
||||
}
|
||||
};
|
||||
let open = matches.is_present("open");
|
||||
let include_drafts = matches.is_present("drafts");
|
||||
let fast = matches.is_present("fast");
|
||||
|
||||
// Default one
|
||||
Command::Serve { interface, mut port, output_dir, base_url, drafts, open, fast } => {
|
||||
if port != 1111 && !port_is_available(port) {
|
||||
console::error("The requested port is not available");
|
||||
::std::process::exit(1);
|
||||
std::process::exit(1);
|
||||
}
|
||||
|
||||
if !port_is_available(port) {
|
||||
port = if let Some(p) = get_available_port(1111) {
|
||||
p
|
||||
} else {
|
||||
console::error("No port available.");
|
||||
::std::process::exit(1);
|
||||
}
|
||||
port = get_available_port(1111).unwrap_or_else(|| {
|
||||
console::error("No port available");
|
||||
std::process::exit(1);
|
||||
});
|
||||
}
|
||||
let output_dir = matches.value_of("output_dir").map(|output_dir| Path::new(output_dir));
|
||||
let base_url = matches.value_of("base_url").unwrap_or("127.0.0.1");
|
||||
|
||||
console::info("Building site...");
|
||||
match cmd::serve(
|
||||
if let Err(e) = cmd::serve(
|
||||
&root_dir,
|
||||
interface,
|
||||
&interface,
|
||||
port,
|
||||
output_dir,
|
||||
base_url,
|
||||
output_dir.as_deref(),
|
||||
&base_url,
|
||||
&config_file,
|
||||
open,
|
||||
include_drafts,
|
||||
drafts,
|
||||
fast,
|
||||
) {
|
||||
Ok(()) => (),
|
||||
Err(e) => {
|
||||
console::unravel_errors("", &e);
|
||||
::std::process::exit(1);
|
||||
}
|
||||
};
|
||||
console::unravel_errors("Failed to serve the site", &e);
|
||||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
("check", Some(matches)) => {
|
||||
Command::Check { drafts } => {
|
||||
console::info("Checking site...");
|
||||
let start = Instant::now();
|
||||
match cmd::check(
|
||||
&root_dir,
|
||||
&config_file,
|
||||
matches.value_of("base_path"),
|
||||
matches.value_of("base_url"),
|
||||
matches.is_present("drafts"),
|
||||
) {
|
||||
match cmd::check(&root_dir, &config_file, None, None, drafts) {
|
||||
Ok(()) => console::report_elapsed_time(start),
|
||||
Err(e) => {
|
||||
console::unravel_errors("Failed to check the site", &e);
|
||||
::std::process::exit(1);
|
||||
std::process::exit(1);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user