Merge pull request #757 from mattico/improve-argparse
Improve command-line argument parsing
This commit is contained in:
commit
bbe6e324d0
|
@ -14,8 +14,8 @@ convenience. Large books will therefore remain structured when rendered.
|
||||||
|
|
||||||
#### Specify a directory
|
#### Specify a directory
|
||||||
|
|
||||||
Like `init`, the `build` command can take a directory as an argument to use
|
The `build` command can take a directory as an argument to use as the book's
|
||||||
instead of the current working directory.
|
root instead of the current working directory.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
mdbook build path/to/book
|
mdbook build path/to/book
|
||||||
|
@ -23,13 +23,16 @@ mdbook build path/to/book
|
||||||
|
|
||||||
#### --open
|
#### --open
|
||||||
|
|
||||||
When you use the `--open` (`-o`) option, mdbook will open the rendered book in
|
When you use the `--open` (`-o`) flag, mdbook will open the rendered book in
|
||||||
your default web browser after building it.
|
your default web browser after building it.
|
||||||
|
|
||||||
#### --dest-dir
|
#### --dest-dir
|
||||||
|
|
||||||
The `--dest-dir` (`-d`) option allows you to change the output directory for your book.
|
The `--dest-dir` (`-d`) option allows you to change the output directory for
|
||||||
|
the book. If not specified it will default to the value of the
|
||||||
|
`build.build-dir` key in `book.toml`, or to `./book` relative to the book's
|
||||||
|
root directory.
|
||||||
|
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
***note:*** *make sure to run the build command in the root directory and not in the source directory*
|
***Note:*** *Make sure to run the build command in the root directory and not in the source directory*
|
||||||
|
|
|
@ -7,12 +7,21 @@ artifacts.
|
||||||
mdbook clean
|
mdbook clean
|
||||||
```
|
```
|
||||||
|
|
||||||
It will try to delete the built book. If a path is provided, it will be used.
|
|
||||||
|
|
||||||
#### Specify a directory
|
#### Specify a directory
|
||||||
|
|
||||||
Like `init`, the `clean` command can take a directory as an argument to use
|
The `clean` command can take a directory as an argument to use as the book's
|
||||||
instead of the normal build directory.
|
root instead of the current working directory.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mdbook clean path/to/book
|
||||||
|
```
|
||||||
|
|
||||||
|
#### --dest-dir
|
||||||
|
|
||||||
|
The `--dest-dir` (`-d`) option allows you to override the book's output
|
||||||
|
directory, which will be deleted by this command. If not specified it
|
||||||
|
will default to the value of the `build.build-dir` key in `book.toml`, or to
|
||||||
|
`./book` relative to the book's root directory.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
mdbook clean --dest-dir=path/to/book
|
mdbook clean --dest-dir=path/to/book
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
# The init command
|
# The init command
|
||||||
There is some minimal boilerplate that is the same for every new book. It's for this purpose that mdBook includes an `init` command.
|
|
||||||
|
There is some minimal boilerplate that is the same for every new book. It's for this purpose
|
||||||
|
that mdBook includes an `init` command.
|
||||||
|
|
||||||
The `init` command is used like this:
|
The `init` command is used like this:
|
||||||
|
|
||||||
|
@ -22,23 +24,27 @@ configuration files, etc.
|
||||||
- The `book` directory is where your book is rendered. All the output is ready to be uploaded
|
- The `book` directory is where your book is rendered. All the output is ready to be uploaded
|
||||||
to a server to be seen by your audience.
|
to a server to be seen by your audience.
|
||||||
|
|
||||||
- The `SUMMARY.md` file is the most important file, it's the skeleton of your book and is discussed in more detail in another [chapter](../format/summary.md)
|
- The `SUMMARY.md` file is the most important file, it's the skeleton of your book and is
|
||||||
|
discussed in more detail [in another chapter](../format/summary.md)
|
||||||
|
|
||||||
#### Tip & Trick: Hidden Feature
|
#### Tip: Generate chapters from SUMMARY.md
|
||||||
When a `SUMMARY.md` file already exists, the `init` command will first parse it and generate the missing files according to the paths used in the `SUMMARY.md`. This allows you to think and create the whole structure of your book and then let mdBook generate it for you.
|
|
||||||
|
When a `SUMMARY.md` file already exists, the `init` command will first parse it and generate the
|
||||||
|
missing files according to the paths used in the `SUMMARY.md`. This allows you to think and create
|
||||||
|
the whole structure of your book and then let mdBook generate it for you.
|
||||||
|
|
||||||
#### Specify a directory
|
#### Specify a directory
|
||||||
|
|
||||||
When using the `init` command, you can also specify a directory, instead of using the current working directory,
|
The `init` command can take a directory as an argument to use as the book's
|
||||||
by appending a path to the command:
|
root instead of the current working directory.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
mdbook init path/to/book
|
mdbook init path/to/book
|
||||||
```
|
```
|
||||||
|
|
||||||
## --theme
|
#### --theme
|
||||||
|
|
||||||
When you use the `--theme` argument, the default theme will be copied into a directory
|
When you use the `--theme` flag, the default theme will be copied into a directory
|
||||||
called `theme` in your source directory so that you can modify it.
|
called `theme` in your source directory so that you can modify it.
|
||||||
|
|
||||||
The theme is selectively overwritten, this means that if you don't want to overwrite a
|
The theme is selectively overwritten, this means that if you don't want to overwrite a
|
||||||
|
|
|
@ -1,40 +1,50 @@
|
||||||
# The serve command
|
# The serve command
|
||||||
|
|
||||||
The `serve` command is useful when you want to preview your book. It also does hot reloading of the webpage whenever a file changes.
|
The serve command is used to preview a book by serving it over HTTP at
|
||||||
It achieves this by serving the books content over `localhost:3000` (unless otherwise configured, see below) and runs a websocket server on `localhost:3001` which triggers the reloads.
|
`localhost:3000` by default. Additionally it watches the book's directory
|
||||||
This preferred by many for writing books with mdbook because it allows for you to see the result of your work instantly after every file change.
|
for changes, rebuilding the book and refreshing clients for each change.
|
||||||
|
A websocket connection is used to trigger the client-side refresh.
|
||||||
|
|
||||||
#### Specify a directory
|
#### Specify a directory
|
||||||
|
|
||||||
Like `watch`, `serve` can take a directory as an argument to use instead of
|
The `serve` command can take a directory as an argument to use as the book's
|
||||||
the current working directory.
|
root instead of the current working directory.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
mdbook serve path/to/book
|
mdbook serve path/to/book
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
#### Server options
|
#### Server options
|
||||||
|
|
||||||
`serve` has four options: the http port, the websocket port, the interface to serve on, and the public address of the server so that the browser may reach the websocket server.
|
`serve` has four options: the HTTP port, the WebSocket port, the HTTP hostname
|
||||||
|
to listen on, and the hostname for the browser to connect to for WebSockets.
|
||||||
|
|
||||||
For example: suppose you had an nginx server for SSL termination which has a public address of 192.168.1.100 on port 80 and proxied that to 127.0.0.1 on port 8000. To run use the nginx proxy do:
|
For example: suppose you have an nginx server for SSL termination which has a
|
||||||
|
public address of 192.168.1.100 on port 80 and proxied that to 127.0.0.1 on
|
||||||
|
port 8000. To run use the nginx proxy do:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
mdbook serve path/to/book -p 8000 -i 127.0.0.1 -a 192.168.1.100
|
mdbook serve path/to/book -p 8000 -n 127.0.0.1 --websocket-hostname 192.168.1.100
|
||||||
```
|
```
|
||||||
|
|
||||||
If you were to want live reloading for this you would need to proxy the websocket calls through nginx as well from `192.168.1.100:<WS_PORT>` to `127.0.0.1:<WS_PORT>`. The `-w` flag allows for the websocket port to be configured.
|
If you were to want live reloading for this you would need to proxy the
|
||||||
|
websocket calls through nginx as well from `192.168.1.100:<WS_PORT>` to
|
||||||
|
`127.0.0.1:<WS_PORT>`. The `-w` flag allows for the websocket port to be
|
||||||
|
configured.
|
||||||
|
|
||||||
#### --open
|
#### --open
|
||||||
|
|
||||||
When you use the `--open` (`-o`) option, mdbook will open the book in your
|
When you use the `--open` (`-o`) flag, mdbook will open the book in your
|
||||||
your default web browser after starting the server.
|
your default web browser after starting the server.
|
||||||
|
|
||||||
#### --dest-dir
|
#### --dest-dir
|
||||||
|
|
||||||
The `--dest-dir` (`-d`) option allows you to change the output directory for your book.
|
The `--dest-dir` (`-d`) option allows you to change the output directory for
|
||||||
|
the book. If not specified it will default to the value of the
|
||||||
|
`build.build-dir` key in `book.toml`, or to `./book` relative to the book's
|
||||||
|
root directory.
|
||||||
|
|
||||||
-----
|
-----
|
||||||
|
|
||||||
***note:*** *the `serve` command has not gotten a lot of testing yet, there could be some rough edges. If you discover a problem, please report it [on Github](https://github.com/rust-lang-nursery/mdBook/issues)*
|
***Note:*** *The `serve` command is for testing, and is not intended
|
||||||
|
to be a complete HTTP server for a website.*
|
||||||
|
|
|
@ -1,19 +1,53 @@
|
||||||
# The test command
|
# The test command
|
||||||
|
|
||||||
When writing a book, you sometimes need to automate some tests. For example, [The Rust Programming Book](https://doc.rust-lang.org/stable/book/) uses a lot of code examples that could get outdated.
|
When writing a book, you sometimes need to automate some tests. For example,
|
||||||
Therefore it is very important for them to be able to automatically test these code examples.
|
[The Rust Programming Book](https://doc.rust-lang.org/stable/book/) uses a lot
|
||||||
|
of code examples that could get outdated. Therefore it is very important for
|
||||||
|
them to be able to automatically test these code examples.
|
||||||
|
|
||||||
mdBook supports a `test` command that will run all available tests in mdBook. At the moment, only one test is available:
|
mdBook supports a `test` command that will run all available tests in a book.
|
||||||
*"Test Rust code examples using Rustdoc"*, but I hope this will be expanded in the future to include more tests like:
|
At the moment, only rustdoc tests are supported, but this may be expanded upon
|
||||||
|
in the future.
|
||||||
|
|
||||||
- checking for broken links
|
#### Disable tests on a code block
|
||||||
- checking for unused files
|
|
||||||
- ...
|
|
||||||
|
|
||||||
In the future I would like the user to be able to enable / disable test from the `book.toml` configuration file and support custom tests.
|
rustdoc doesn't test code blocks which contain the `ignore` attribute:
|
||||||
|
|
||||||
|
```rust,ignore
|
||||||
|
fn main() {}
|
||||||
|
```
|
||||||
|
|
||||||
|
rustdoc also doesn't test code blocks which specify a language other than Rust:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
**Foo**: _bar_
|
||||||
|
```
|
||||||
|
|
||||||
|
rustdoc *does* test code blocks which have no language specified:
|
||||||
|
|
||||||
|
```
|
||||||
|
This is going to cause an error!
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Specify a directory
|
||||||
|
|
||||||
|
The `test` command can take a directory as an argument to use as the book's
|
||||||
|
root instead of the current working directory.
|
||||||
|
|
||||||
**How to use it:**
|
|
||||||
```bash
|
```bash
|
||||||
$ mdbook test
|
mdbook test path/to/book
|
||||||
[*]: Testing file: "/mdBook/book-example/src/README.md”
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### --library-path
|
||||||
|
|
||||||
|
The `--library-path` (`-L`) option allows you to add directories to the library
|
||||||
|
search path used by `rustdoc` when it builds and tests the examples. Multiple
|
||||||
|
directories can be specified with multiple options (`-L foo -L bar`) or with a
|
||||||
|
comma-delimited list (`-L foo,bar`).
|
||||||
|
|
||||||
|
#### --dest-dir
|
||||||
|
|
||||||
|
The `--dest-dir` (`-d`) option allows you to change the output directory for
|
||||||
|
the book. If not specified it will default to the value of the
|
||||||
|
`build.build-dir` key in `book.toml`, or to `./book` relative to the book's
|
||||||
|
root directory.
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
# The watch command
|
# The watch command
|
||||||
|
|
||||||
The `watch` command is useful when you want your book to be rendered on every file change.
|
The `watch` command is useful when you want your book to be rendered on every
|
||||||
You could repeatedly issue `mdbook build` every time a file is changed. But using `mdbook watch` once will watch your files and will trigger a build automatically whenever you modify a file.
|
file change. You could repeatedly issue `mdbook build` every time a file is
|
||||||
|
changed. But using `mdbook watch` once will watch your files and will trigger
|
||||||
|
a build automatically whenever you modify a file.
|
||||||
|
|
||||||
#### Specify a directory
|
#### Specify a directory
|
||||||
|
|
||||||
Like `init` and `build`, `watch` can take a directory as an argument to use
|
The `watch` command can take a directory as an argument to use as the book's
|
||||||
instead of the current working directory.
|
root instead of the current working directory.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
mdbook watch path/to/book
|
mdbook watch path/to/book
|
||||||
|
@ -19,8 +21,7 @@ your default web browser.
|
||||||
|
|
||||||
#### --dest-dir
|
#### --dest-dir
|
||||||
|
|
||||||
The `--dest-dir` (`-d`) option allows you to change the output directory for your book.
|
The `--dest-dir` (`-d`) option allows you to change the output directory for
|
||||||
|
the book. If not specified it will default to the value of the
|
||||||
-----
|
`build.build-dir` key in `book.toml`, or to `./book` relative to the book's
|
||||||
|
root directory.
|
||||||
***note:*** *the `watch` command has not gotten a lot of testing yet, there could be some rough edges. If you discover a problem, please report it [on Github](https://github.com/rust-lang-nursery/mdBook/issues)*
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ Will render as
|
||||||
With the following syntax, you can include files into your book:
|
With the following syntax, you can include files into your book:
|
||||||
|
|
||||||
```hbs
|
```hbs
|
||||||
\{{#include file.rs}}
|
{{#include file.rs}}
|
||||||
```
|
```
|
||||||
|
|
||||||
The path to the file has to be relative from the current source file.
|
The path to the file has to be relative from the current source file.
|
||||||
|
@ -37,10 +37,10 @@ The path to the file has to be relative from the current source file.
|
||||||
Usually, this command is used for including code snippets and examples. In this case, oftens one would include a specific part of the file e.g. which only contains the relevant lines for the example. We support four different modes of partial includes:
|
Usually, this command is used for including code snippets and examples. In this case, oftens one would include a specific part of the file e.g. which only contains the relevant lines for the example. We support four different modes of partial includes:
|
||||||
|
|
||||||
```hbs
|
```hbs
|
||||||
\{{#include file.rs:2}}
|
{{#include file.rs:2}}
|
||||||
\{{#include file.rs::10}}
|
{{#include file.rs::10}}
|
||||||
\{{#include file.rs:2:}}
|
{{#include file.rs:2:}}
|
||||||
\{{#include file.rs:2:10}}
|
{{#include file.rs:2:10}}
|
||||||
```
|
```
|
||||||
|
|
||||||
The first command only includes the second line from file `file.rs`. The second command includes all lines up to line 10, i.e. the lines from 11 till the end of the file are omitted. The third command includes all lines from line 2, i.e. the first line is omitted. The last command includes the excerpt of `file.rs` consisting of lines 2 to 10.
|
The first command only includes the second line from file `file.rs`. The second command includes all lines up to line 10, i.e. the lines from 11 till the end of the file are omitted. The third command includes all lines from line 2, i.e. the first line is omitted. The last command includes the excerpt of `file.rs` consisting of lines 2 to 10.
|
||||||
|
@ -50,7 +50,7 @@ The first command only includes the second line from file `file.rs`. The second
|
||||||
With the following syntax, you can insert runnable Rust files into your book:
|
With the following syntax, you can insert runnable Rust files into your book:
|
||||||
|
|
||||||
```hbs
|
```hbs
|
||||||
\{{#playpen file.rs}}
|
{{#playpen file.rs}}
|
||||||
```
|
```
|
||||||
|
|
||||||
The path to the Rust file has to be relative from the current source file.
|
The path to the Rust file has to be relative from the current source file.
|
||||||
|
|
|
@ -37,7 +37,7 @@ Since the original directory structure is maintained, it is useful to prepend re
|
||||||
|
|
||||||
In addition to the properties you can access, there are some handlebars helpers at your disposal.
|
In addition to the properties you can access, there are some handlebars helpers at your disposal.
|
||||||
|
|
||||||
1. ### toc
|
### 1. toc
|
||||||
|
|
||||||
The toc helper is used like this
|
The toc helper is used like this
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ In addition to the properties you can access, there are some handlebars helpers
|
||||||
</script>
|
</script>
|
||||||
```
|
```
|
||||||
|
|
||||||
2. ### previous / next
|
### 2. previous / next
|
||||||
|
|
||||||
The previous and next helpers expose a `link` and `name` property to the previous and next chapters.
|
The previous and next helpers expose a `link` and `name` property to the previous and next chapters.
|
||||||
|
|
||||||
|
@ -87,5 +87,4 @@ In addition to the properties you can access, there are some handlebars helpers
|
||||||
|
|
||||||
------
|
------
|
||||||
|
|
||||||
*If you would like me to expose other properties or helpers, please [create a new issue](https://github.com/rust-lang-nursery/mdBook/issues)
|
*If you would like other properties or helpers exposed, please [create a new issue](https://github.com/rust-lang-nursery/mdBook/issues)*
|
||||||
and I will consider it.*
|
|
||||||
|
|
|
@ -1,21 +1,21 @@
|
||||||
use clap::{App, ArgMatches, SubCommand};
|
use clap::{App, ArgMatches, SubCommand};
|
||||||
use mdbook::errors::Result;
|
use mdbook::errors::Result;
|
||||||
use mdbook::MDBook;
|
use mdbook::MDBook;
|
||||||
use std::path::PathBuf;
|
|
||||||
use {get_book_dir, open};
|
use {get_book_dir, open};
|
||||||
|
|
||||||
// Create clap subcommand arguments
|
// Create clap subcommand arguments
|
||||||
pub fn make_subcommand<'a, 'b>() -> App<'a, 'b> {
|
pub fn make_subcommand<'a, 'b>() -> App<'a, 'b> {
|
||||||
SubCommand::with_name("build")
|
SubCommand::with_name("build")
|
||||||
.about("Build the book from the markdown files")
|
.about("Builds a book from its markdown files")
|
||||||
.arg_from_usage("-o, --open 'Open the compiled book in a web browser'")
|
|
||||||
.arg_from_usage(
|
.arg_from_usage(
|
||||||
"-d, --dest-dir=[dest-dir] 'The output directory for your book{n}(Defaults to ./book \
|
"-d, --dest-dir=[dest-dir] 'Output directory for the book{n}\
|
||||||
when omitted)'",
|
(If omitted, uses build.build-dir from book.toml or defaults to ./book)'",
|
||||||
)
|
)
|
||||||
.arg_from_usage(
|
.arg_from_usage(
|
||||||
"[dir] 'A directory for your book{n}(Defaults to Current Directory when omitted)'",
|
"[dir] 'Root directory for the book{n}\
|
||||||
|
(Defaults to the Current Directory when omitted)'",
|
||||||
)
|
)
|
||||||
|
.arg_from_usage("-o, --open 'Opens the compiled book in a web browser'")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build command implementation
|
// Build command implementation
|
||||||
|
@ -24,7 +24,7 @@ pub fn execute(args: &ArgMatches) -> Result<()> {
|
||||||
let mut book = MDBook::load(&book_dir)?;
|
let mut book = MDBook::load(&book_dir)?;
|
||||||
|
|
||||||
if let Some(dest_dir) = args.value_of("dest-dir") {
|
if let Some(dest_dir) = args.value_of("dest-dir") {
|
||||||
book.config.build.build_dir = PathBuf::from(dest_dir);
|
book.config.build.build_dir = dest_dir.into();
|
||||||
}
|
}
|
||||||
|
|
||||||
book.build()?;
|
book.build()?;
|
||||||
|
|
|
@ -3,15 +3,18 @@ use get_book_dir;
|
||||||
use mdbook::errors::*;
|
use mdbook::errors::*;
|
||||||
use mdbook::MDBook;
|
use mdbook::MDBook;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::path::PathBuf;
|
|
||||||
|
|
||||||
// Create clap subcommand arguments
|
// Create clap subcommand arguments
|
||||||
pub fn make_subcommand<'a, 'b>() -> App<'a, 'b> {
|
pub fn make_subcommand<'a, 'b>() -> App<'a, 'b> {
|
||||||
SubCommand::with_name("clean")
|
SubCommand::with_name("clean")
|
||||||
.about("Delete built book")
|
.about("Deletes a built book")
|
||||||
.arg_from_usage(
|
.arg_from_usage(
|
||||||
"-d, --dest-dir=[dest-dir] 'The directory of built book{n}(Defaults to ./book when \
|
"-d, --dest-dir=[dest-dir] 'Output directory for the book{n}\
|
||||||
omitted)'",
|
(If omitted, uses build.build-dir from book.toml or defaults to ./book)'",
|
||||||
|
)
|
||||||
|
.arg_from_usage(
|
||||||
|
"[dir] 'Root directory for the book{n}\
|
||||||
|
(Defaults to the Current Directory when omitted)'",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,7 +24,7 @@ pub fn execute(args: &ArgMatches) -> ::mdbook::errors::Result<()> {
|
||||||
let book = MDBook::load(&book_dir)?;
|
let book = MDBook::load(&book_dir)?;
|
||||||
|
|
||||||
let dir_to_remove = match args.value_of("dest-dir") {
|
let dir_to_remove = match args.value_of("dest-dir") {
|
||||||
Some(dest_dir) => PathBuf::from(dest_dir),
|
Some(dest_dir) => dest_dir.into(),
|
||||||
None => book.root.join(&book.config.build.build_dir),
|
None => book.root.join(&book.config.build.build_dir),
|
||||||
};
|
};
|
||||||
fs::remove_dir_all(&dir_to_remove).chain_err(|| "Unable to remove the build directory")?;
|
fs::remove_dir_all(&dir_to_remove).chain_err(|| "Unable to remove the build directory")?;
|
||||||
|
|
|
@ -10,12 +10,12 @@ use std::process::Command;
|
||||||
// Create clap subcommand arguments
|
// Create clap subcommand arguments
|
||||||
pub fn make_subcommand<'a, 'b>() -> App<'a, 'b> {
|
pub fn make_subcommand<'a, 'b>() -> App<'a, 'b> {
|
||||||
SubCommand::with_name("init")
|
SubCommand::with_name("init")
|
||||||
.about("Create boilerplate structure and files in the directory")
|
.about("Creates the boilerplate structure and files for a new book")
|
||||||
// the {n} denotes a newline which will properly aligned in all help messages
|
// the {n} denotes a newline which will properly aligned in all help messages
|
||||||
.arg_from_usage("[dir] 'A directory for your book{n}(Defaults to Current Directory \
|
.arg_from_usage("[dir] 'Directory to create the book in{n}\
|
||||||
when omitted)'")
|
(Defaults to the Current Directory when omitted)'")
|
||||||
.arg_from_usage("--theme 'Copies the default theme into your source folder'")
|
.arg_from_usage("--theme 'Copies the default theme into your source folder'")
|
||||||
.arg_from_usage("--force 'skip confirmation prompts'")
|
.arg_from_usage("--force 'Skips confirmation prompts'")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init command implementation
|
// Init command implementation
|
||||||
|
|
|
@ -7,7 +7,7 @@ use self::iron::{
|
||||||
};
|
};
|
||||||
#[cfg(feature = "watch")]
|
#[cfg(feature = "watch")]
|
||||||
use super::watch;
|
use super::watch;
|
||||||
use clap::{App, ArgMatches, SubCommand};
|
use clap::{App, Arg, ArgMatches, SubCommand};
|
||||||
use mdbook::errors::*;
|
use mdbook::errors::*;
|
||||||
use mdbook::utils;
|
use mdbook::utils;
|
||||||
use mdbook::MDBook;
|
use mdbook::MDBook;
|
||||||
|
@ -19,23 +19,52 @@ struct ErrorRecover;
|
||||||
// Create clap subcommand arguments
|
// Create clap subcommand arguments
|
||||||
pub fn make_subcommand<'a, 'b>() -> App<'a, 'b> {
|
pub fn make_subcommand<'a, 'b>() -> App<'a, 'b> {
|
||||||
SubCommand::with_name("serve")
|
SubCommand::with_name("serve")
|
||||||
.about("Serve the book at http://localhost:3000. Rebuild and reload on change.")
|
.about("Serves a book at http://localhost:3000, and rebuilds it on changes")
|
||||||
.arg_from_usage(
|
.arg_from_usage(
|
||||||
"[dir] 'A directory for your book{n}(Defaults to Current Directory when omitted)'",
|
"-d, --dest-dir=[dest-dir] 'Output directory for the book{n}\
|
||||||
)
|
(If omitted, uses build.build-dir from book.toml or defaults to ./book)'",
|
||||||
.arg_from_usage("-p, --port=[port] 'Use another port{n}(Defaults to 3000)'")
|
|
||||||
.arg_from_usage(
|
|
||||||
"-w, --websocket-port=[ws-port] 'Use another port for the websocket connection \
|
|
||||||
(livereload){n}(Defaults to 3001)'",
|
|
||||||
)
|
)
|
||||||
.arg_from_usage(
|
.arg_from_usage(
|
||||||
"-i, --interface=[interface] 'Interface to listen on{n}(Defaults to localhost)'",
|
"[dir] 'Root directory for the book{n}\
|
||||||
|
(Defaults to the Current Directory when omitted)'",
|
||||||
)
|
)
|
||||||
.arg_from_usage(
|
.arg(
|
||||||
"-a, --address=[address] 'Address that the browser can reach the websocket server \
|
Arg::with_name("hostname")
|
||||||
from{n}(Defaults to the interface address)'",
|
.short("n")
|
||||||
|
.long("hostname")
|
||||||
|
.takes_value(true)
|
||||||
|
.default_value("localhost")
|
||||||
|
.empty_values(false)
|
||||||
|
.help("Hostname to listen on for HTTP connections"),
|
||||||
)
|
)
|
||||||
.arg_from_usage("-o, --open 'Open the book server in a web browser'")
|
.arg(
|
||||||
|
Arg::with_name("port")
|
||||||
|
.short("p")
|
||||||
|
.long("port")
|
||||||
|
.takes_value(true)
|
||||||
|
.default_value("3000")
|
||||||
|
.empty_values(false)
|
||||||
|
.help("Port to use for HTTP connections"),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("websocket-hostname")
|
||||||
|
.long("websocket-hostname")
|
||||||
|
.takes_value(true)
|
||||||
|
.empty_values(false)
|
||||||
|
.help(
|
||||||
|
"Hostname to connect to for WebSockets connections (Defaults to the HTTP hostname)",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("websocket-port")
|
||||||
|
.short("w")
|
||||||
|
.long("websocket-port")
|
||||||
|
.takes_value(true)
|
||||||
|
.default_value("3001")
|
||||||
|
.empty_values(false)
|
||||||
|
.help("Port to use for WebSockets livereload connections"),
|
||||||
|
)
|
||||||
|
.arg_from_usage("-o, --open 'Opens the book server in a web browser'")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Watch command implementation
|
// Watch command implementation
|
||||||
|
@ -43,19 +72,23 @@ pub fn execute(args: &ArgMatches) -> Result<()> {
|
||||||
let book_dir = get_book_dir(args);
|
let book_dir = get_book_dir(args);
|
||||||
let mut book = MDBook::load(&book_dir)?;
|
let mut book = MDBook::load(&book_dir)?;
|
||||||
|
|
||||||
let port = args.value_of("port").unwrap_or("3000");
|
let port = args.value_of("port").unwrap();
|
||||||
let ws_port = args.value_of("websocket-port").unwrap_or("3001");
|
let ws_port = args.value_of("websocket-port").unwrap();
|
||||||
let interface = args.value_of("interface").unwrap_or("localhost");
|
let hostname = args.value_of("hostname").unwrap();
|
||||||
let public_address = args.value_of("address").unwrap_or(interface);
|
let public_address = args.value_of("websocket-address").unwrap_or(hostname);
|
||||||
let open_browser = args.is_present("open");
|
let open_browser = args.is_present("open");
|
||||||
|
|
||||||
let address = format!("{}:{}", interface, port);
|
let address = format!("{}:{}", hostname, port);
|
||||||
let ws_address = format!("{}:{}", interface, ws_port);
|
let ws_address = format!("{}:{}", hostname, ws_port);
|
||||||
|
|
||||||
let livereload_url = format!("ws://{}:{}", public_address, ws_port);
|
let livereload_url = format!("ws://{}:{}", public_address, ws_port);
|
||||||
book.config
|
book.config
|
||||||
.set("output.html.livereload-url", &livereload_url)?;
|
.set("output.html.livereload-url", &livereload_url)?;
|
||||||
|
|
||||||
|
if let Some(dest_dir) = args.value_of("dest-dir") {
|
||||||
|
book.config.build.build_dir = dest_dir.into();
|
||||||
|
}
|
||||||
|
|
||||||
book.build()?;
|
book.build()?;
|
||||||
|
|
||||||
let mut chain = Chain::new(staticfile::Static::new(book.build_dir_for("html")));
|
let mut chain = Chain::new(staticfile::Static::new(book.build_dir_for("html")));
|
||||||
|
@ -87,10 +120,8 @@ pub fn execute(args: &ArgMatches) -> Result<()> {
|
||||||
|
|
||||||
// FIXME: This area is really ugly because we need to re-set livereload :(
|
// FIXME: This area is really ugly because we need to re-set livereload :(
|
||||||
|
|
||||||
let livereload_url = livereload_url.clone();
|
|
||||||
|
|
||||||
let result = MDBook::load(&book_dir)
|
let result = MDBook::load(&book_dir)
|
||||||
.and_then(move |mut b| {
|
.and_then(|mut b| {
|
||||||
b.config.set("output.html.livereload-url", &livereload_url)?;
|
b.config.set("output.html.livereload-url", &livereload_url)?;
|
||||||
Ok(b)
|
Ok(b)
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use clap::{App, ArgMatches, SubCommand};
|
use clap::{App, Arg, ArgMatches, SubCommand};
|
||||||
use get_book_dir;
|
use get_book_dir;
|
||||||
use mdbook::errors::Result;
|
use mdbook::errors::Result;
|
||||||
use mdbook::MDBook;
|
use mdbook::MDBook;
|
||||||
|
@ -6,11 +6,24 @@ use mdbook::MDBook;
|
||||||
// Create clap subcommand arguments
|
// Create clap subcommand arguments
|
||||||
pub fn make_subcommand<'a, 'b>() -> App<'a, 'b> {
|
pub fn make_subcommand<'a, 'b>() -> App<'a, 'b> {
|
||||||
SubCommand::with_name("test")
|
SubCommand::with_name("test")
|
||||||
.about("Test that code samples compile")
|
.about("Tests that a book's Rust code samples compile")
|
||||||
.arg_from_usage("-L, --library-path [DIR]... 'directories to add to crate search path'")
|
|
||||||
.arg_from_usage(
|
.arg_from_usage(
|
||||||
"[dir] 'A directory for your book{n}(Defaults to Current Directory when omitted)'",
|
"-d, --dest-dir=[dest-dir] 'Output directory for the book{n}\
|
||||||
|
(If omitted, uses build.build-dir from book.toml or defaults to ./book)'",
|
||||||
)
|
)
|
||||||
|
.arg_from_usage(
|
||||||
|
"[dir] 'Root directory for the book{n}\
|
||||||
|
(Defaults to the Current Directory when omitted)'",
|
||||||
|
)
|
||||||
|
.arg(Arg::with_name("library-path")
|
||||||
|
.short("L")
|
||||||
|
.long("library-path")
|
||||||
|
.value_name("dir")
|
||||||
|
.takes_value(true)
|
||||||
|
.require_delimiter(true)
|
||||||
|
.multiple(true)
|
||||||
|
.empty_values(false)
|
||||||
|
.help("A comma-separated list of directories to add to {n}the crate search path when building tests"))
|
||||||
}
|
}
|
||||||
|
|
||||||
// test command implementation
|
// test command implementation
|
||||||
|
@ -21,6 +34,10 @@ pub fn execute(args: &ArgMatches) -> Result<()> {
|
||||||
let book_dir = get_book_dir(args);
|
let book_dir = get_book_dir(args);
|
||||||
let mut book = MDBook::load(&book_dir)?;
|
let mut book = MDBook::load(&book_dir)?;
|
||||||
|
|
||||||
|
if let Some(dest_dir) = args.value_of("dest-dir") {
|
||||||
|
book.config.build.build_dir = dest_dir.into();
|
||||||
|
}
|
||||||
|
|
||||||
book.test(library_paths)?;
|
book.test(library_paths)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -13,11 +13,16 @@ use {get_book_dir, open};
|
||||||
// Create clap subcommand arguments
|
// Create clap subcommand arguments
|
||||||
pub fn make_subcommand<'a, 'b>() -> App<'a, 'b> {
|
pub fn make_subcommand<'a, 'b>() -> App<'a, 'b> {
|
||||||
SubCommand::with_name("watch")
|
SubCommand::with_name("watch")
|
||||||
.about("Watch the files for changes")
|
.about("Watches a book's files and rebuilds it on changes")
|
||||||
.arg_from_usage("-o, --open 'Open the compiled book in a web browser'")
|
|
||||||
.arg_from_usage(
|
.arg_from_usage(
|
||||||
"[dir] 'A directory for your book{n}(Defaults to Current Directory when omitted)'",
|
"-d, --dest-dir=[dest-dir] 'Output directory for the book{n}\
|
||||||
|
(If omitted, uses build.build-dir from book.toml or defaults to ./book)'",
|
||||||
)
|
)
|
||||||
|
.arg_from_usage(
|
||||||
|
"[dir] 'Root directory for the book{n}\
|
||||||
|
(Defaults to the Current Directory when omitted)'",
|
||||||
|
)
|
||||||
|
.arg_from_usage("-o, --open 'Open the compiled book in a web browser'")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Watch command implementation
|
// Watch command implementation
|
||||||
|
|
29
src/main.rs
29
src/main.rs
|
@ -20,26 +20,27 @@ use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
mod cmd;
|
mod cmd;
|
||||||
|
|
||||||
const NAME: &'static str = "mdbook";
|
const NAME: &'static str = "mdBook";
|
||||||
|
const VERSION: &'static str = concat!("v", crate_version!());
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
init_logger();
|
init_logger();
|
||||||
|
|
||||||
// Create a list of valid arguments and sub-commands
|
// Create a list of valid arguments and sub-commands
|
||||||
let app = App::new(NAME)
|
let app = App::new(NAME)
|
||||||
.about("Create a book in form of a static website from markdown files")
|
.about("Creates a book from markdown files")
|
||||||
.author("Mathieu David <mathieudavid@mathieudavid.org>")
|
.author("Mathieu David <mathieudavid@mathieudavid.org>")
|
||||||
// Get the version from our Cargo.toml using clap's crate_version!() macro
|
.version(VERSION)
|
||||||
.version(concat!("v",crate_version!()))
|
.setting(AppSettings::GlobalVersion)
|
||||||
.setting(AppSettings::ArgRequiredElseHelp)
|
.setting(AppSettings::ArgRequiredElseHelp)
|
||||||
.after_help("For more information about a specific command, \
|
.after_help(
|
||||||
try `mdbook <command> --help`\n\
|
"For more information about a specific command, try `mdbook <command> --help`\n\
|
||||||
Source code for mdbook available \
|
The source code for mdBook is available at: https://github.com/rust-lang-nursery/mdBook",
|
||||||
at: https://github.com/rust-lang-nursery/mdBook")
|
)
|
||||||
.subcommand(cmd::init::make_subcommand())
|
.subcommand(cmd::init::make_subcommand())
|
||||||
.subcommand(cmd::build::make_subcommand())
|
.subcommand(cmd::build::make_subcommand())
|
||||||
.subcommand(cmd::test::make_subcommand())
|
.subcommand(cmd::test::make_subcommand())
|
||||||
.subcommand(cmd::clean::make_subcommand());
|
.subcommand(cmd::clean::make_subcommand());
|
||||||
|
|
||||||
#[cfg(feature = "watch")]
|
#[cfg(feature = "watch")]
|
||||||
let app = app.subcommand(cmd::watch::make_subcommand());
|
let app = app.subcommand(cmd::watch::make_subcommand());
|
||||||
|
|
Loading…
Reference in New Issue