Browse Source

Merge pull request #450 from FreeMasen/next

add watch command
index-subcmd
Vincent Prouillet GitHub 6 years ago
parent
commit
a799384f38
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 88 additions and 65 deletions
  1. +3
    -0
      docs/content/documentation/getting-started/cli-usage.md
  2. +4
    -0
      src/cli.rs
  3. +79
    -63
      src/cmd/serve.rs
  4. +2
    -2
      src/main.rs

+ 3
- 0
docs/content/documentation/getting-started/cli-usage.md View File

@@ -56,6 +56,8 @@ the interface/port combination to use if you want something different than the d
You can also specify different addresses for the interface and base_url using `-u`/`--base-url`, for example You can also specify different addresses for the interface and base_url using `-u`/`--base-url`, for example
if you are running zola in a Docker container. if you are running zola in a Docker container.


In the event you don't want zola to run a local webserver, you can use the `--watch-only` flag.

```bash ```bash
$ zola serve $ zola serve
$ zola serve --port 2000 $ zola serve --port 2000
@@ -63,6 +65,7 @@ $ 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 --watch-only
``` ```


The serve command will watch all your content and will provide live reload, without The serve command will watch all your content and will provide live reload, without


+ 4
- 0
src/cli.rs View File

@@ -62,6 +62,10 @@ pub fn build_cli() -> App<'static, 'static> {
.default_value("127.0.0.1") .default_value("127.0.0.1")
.takes_value(true) .takes_value(true)
.help("Changes the base_url"), .help("Changes the base_url"),
Arg::with_name("watch_only")
.long("watch-only")
.takes_value(false)
.help("Do not start a server, just re-build project on changes")
]), ]),
]) ])
} }

+ 79
- 63
src/cmd/serve.rs View File

@@ -166,6 +166,7 @@ pub fn serve(
output_dir: &str, output_dir: &str,
base_url: &str, base_url: &str,
config_file: &str, config_file: &str,
watch_only: bool,
) -> Result<()> { ) -> Result<()> {
let start = Instant::now(); let start = Instant::now();
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, base_url, config_file)?;
@@ -206,49 +207,56 @@ pub fn serve(
// output path is going to need to be moved later on, so clone it for the // output path is going to need to be moved later on, so clone it for the
// http closure to avoid contention. // http closure to avoid contention.
let static_root = output_path.clone(); let static_root = output_path.clone();
thread::spawn(move || {
let s = server::new(move || {
App::new()
.middleware(NotFoundHandler { rendered_template: static_root.join("404.html") })
.resource(r"/livereload.js", |r| r.f(livereload_handler))
// Start a webserver that serves the `output_dir` directory
.handler(
r"/",
fs::StaticFiles::new(&static_root)
.unwrap()
.show_files_listing()
.files_listing_renderer(handle_directory),
)
})
.bind(&address)
.expect("Can't start the webserver")
.shutdown_timeout(20);
println!("Web server is available at http://{}", &address);
s.run();
});

// The websocket for livereload
let ws_server = WebSocket::new(|output: Sender| {
move |msg: Message| {
if msg.into_text().unwrap().contains("\"hello\"") {
return output.send(Message::text(
r#"
{
"command": "hello",
"protocols": [ "http://livereload.com/protocols/official-7" ],
"serverName": "Zola"
}
"#,
));
let broadcaster = if !watch_only {

thread::spawn(move || {
let s = server::new(move || {
App::new()
.middleware(NotFoundHandler { rendered_template: static_root.join("404.html") })
.resource(r"/livereload.js", |r| r.f(livereload_handler))
// Start a webserver that serves the `output_dir` directory
.handler(
r"/",
fs::StaticFiles::new(&static_root)
.unwrap()
.show_files_listing()
.files_listing_renderer(handle_directory),
)
})
.bind(&address)
.expect("Can't start the webserver")
.shutdown_timeout(20);
println!("Web server is available at http://{}", &address);
s.run();
});
// The websocket for livereload
let ws_server = WebSocket::new(|output: Sender| {
move |msg: Message| {
if msg.into_text().unwrap().contains("\"hello\"") {
return output.send(Message::text(
r#"
{
"command": "hello",
"protocols": [ "http://livereload.com/protocols/official-7" ],
"serverName": "Zola"
}
"#,
));
}
Ok(())
} }
Ok(())
}
})
.unwrap();
let broadcaster = ws_server.broadcaster();
thread::spawn(move || {
ws_server.listen(&*ws_address).unwrap();
});
})
.unwrap();
let broadcaster = ws_server.broadcaster();
thread::spawn(move || {
ws_server.listen(&*ws_address).unwrap();
});
Some(broadcaster)
} else {
println!("Watching in watch only mode, no web server will be started");
None
};



let pwd = env::current_dir().unwrap(); let pwd = env::current_dir().unwrap();


@@ -297,21 +305,25 @@ pub fn serve(
match detect_change_kind(&pwd, &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
rebuild_done_handling(
&broadcaster,
rebuild::after_content_change(&mut site, &path),
"/x.js",
);
if let Some(ref broadcaster) = broadcaster {
// Force refresh
rebuild_done_handling(
broadcaster,
rebuild::after_content_change(&mut site, &path),
"/x.js",
);
}
} }
(ChangeKind::Templates, _) => { (ChangeKind::Templates, _) => {
console::info(&format!("-> Template changed {}", path.display())); console::info(&format!("-> Template changed {}", path.display()));
// Force refresh
rebuild_done_handling(
&broadcaster,
rebuild::after_template_change(&mut site, &path),
"/x.js",
);
if let Some(ref broadcaster) = broadcaster {
// Force refresh
rebuild_done_handling(
broadcaster,
rebuild::after_template_change(&mut site, &path),
"/x.js",
);
}
} }
(ChangeKind::StaticFiles, p) => { (ChangeKind::StaticFiles, p) => {
if path.is_file() { if path.is_file() {
@@ -319,21 +331,25 @@ pub fn serve(
"-> Static file changes detected {}", "-> Static file changes detected {}",
path.display() path.display()
)); ));
if let Some(ref broadcaster) = broadcaster {
rebuild_done_handling(
broadcaster,
copy_file(&path, &site.output_path, &site.static_path),
&p.to_string_lossy(),
);
}
}
}
(ChangeKind::Sass, p) => {
console::info(&format!("-> Sass file changed {}", path.display()));
if let Some(ref broadcaster) = broadcaster {
rebuild_done_handling( rebuild_done_handling(
&broadcaster, &broadcaster,
copy_file(&path, &site.output_path, &site.static_path),
site.compile_sass(&site.base_path),
&p.to_string_lossy(), &p.to_string_lossy(),
); );
} }
} }
(ChangeKind::Sass, p) => {
console::info(&format!("-> Sass file changed {}", path.display()));
rebuild_done_handling(
&broadcaster,
site.compile_sass(&site.base_path),
&p.to_string_lossy(),
);
}
(ChangeKind::Config, _) => { (ChangeKind::Config, _) => {
console::info("-> Config changed. The whole site will be reloaded. The browser needs to be refreshed to make the changes visible."); console::info("-> Config changed. The whole site will be reloaded. The browser needs to be refreshed to make the changes visible.");
site = create_new_site( site = create_new_site(


+ 2
- 2
src/main.rs View File

@@ -77,11 +77,11 @@ fn main() {
::std::process::exit(1); ::std::process::exit(1);
} }
} }
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_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(interface, port, output_dir, base_url, config_file) {
match cmd::serve(interface, port, output_dir, base_url, config_file, watch_only) {
Ok(()) => (), Ok(()) => (),
Err(e) => { Err(e) => {
console::unravel_errors("", &e); console::unravel_errors("", &e);


Loading…
Cancel
Save