-
Notifications
You must be signed in to change notification settings - Fork 34
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
mdbook setup and draft of tutorial #47
Merged
Merged
Changes from 10 commits
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
67a829e
Setup mdbook
killercup 0fc39c0
Add draft of tutorial
killercup 1ef40a6
Split tutorial into chapters
killercup 8dacf31
Add editorconfig file
killercup 1e5e639
Highlight TODOs
killercup bd31247
Rewrite Getting Started with parts of Intro
killercup ba3b1ff
Add travis config
killercup f4a39ac
Add empty "in-depth" chapters
killercup ca48858
Automatically generate nice quotes
killercup fb4edd0
Highlight asides and todos
killercup 5edcea2
fix typo
killercup File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
# EditorConfig helps developers define and maintain consistent | ||
# coding styles between different editors and IDEs | ||
# editorconfig.org | ||
|
||
root = true | ||
|
||
|
||
[*] | ||
end_of_line = lf | ||
charset = utf-8 | ||
trim_trailing_whitespace = true | ||
insert_final_newline = true | ||
indent_style = space | ||
indent_size = 4 | ||
|
||
[*.rs] | ||
indent_style = space | ||
indent_size = 4 | ||
|
||
[*.toml] | ||
indent_style = space | ||
indent_size = 4 | ||
|
||
[*.md] | ||
trim_trailing_whitespace = false |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
book |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
sudo: false | ||
dist: trusty | ||
language: rust | ||
|
||
before_install: | ||
- cargo install mdbook --vers '0.1.8' --debug --force | ||
|
||
script: | ||
- mdbook build | ||
|
||
deploy: | ||
provider: pages | ||
skip-cleanup: true | ||
github-token: $GITHUB_TOKEN # Set in travis-ci.org dashboard, marked secure | ||
local-dir: book | ||
keep-history: false | ||
on: | ||
branch: master |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
[book] | ||
authors = ["The Rust CLI Working Group"] | ||
multilingual = false | ||
src = "src" | ||
title = "Rust CLI WG" | ||
|
||
[output.html] | ||
curly-quotes = true | ||
additional-css = ["src/special-content.css"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
# Summary | ||
|
||
[Getting started](./getting_started.md) | ||
|
||
- [A command line app in 15 minutes](./tutorial/intro.md) | ||
- [Project setup](./tutorial/setup.md) | ||
- [Parsing command line arguments](./tutorial/cli-args.md) | ||
- [First implementation of our example tool](./tutorial/impl-draft.md) | ||
- [Nicer error reporting](./tutorial/errors.md) | ||
- [Output for humans and machines](./tutorial/output.md) | ||
- [Testing](./tutorial/testing.md) | ||
- [Packaging and documentation](./tutorial/packaging.md) | ||
- [In-depth topics](./in-depth/intro.md) | ||
- [Signal handling](./in-depth/signals.md) | ||
- [Using config files](./in-depth/config-files.md) | ||
- [Exit codes](./in-depth/exit-code.md) | ||
- [Communicating with humans](./in-depth/human-communication.md) | ||
- [Communicating with machines](./in-depth/machine-communication.md) | ||
- [Rendering documentation for you CLI apps](./in-depth/docs.md) | ||
- [Packaging apps and distributing them for different platforms](./in-depth/packaging-distribution.md) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
# Command line apps in Rust | ||
|
||
Rust is a statically compiled, fast language with great tooling and a rapidly growing ecosystem. | ||
That makes it a great fit for writing command line applications: | ||
They should be small, portable, and quick to run. | ||
Command line applications are also a great way to get started with learning Rust; | ||
or if you want to introduce Rust to your team! | ||
|
||
Writing a program with a simple command line interface (CLI) | ||
is great a exercise for a beginner | ||
who is new to the language and wants to get a feel for it. | ||
There are many aspects to this topic, though, | ||
that often only reveal themselves later on. | ||
|
||
This book is structure like this: | ||
We start with a quick tutorial, | ||
after which you'll end up with a working CLI tool. | ||
You'll be exposed to a few of the core concepts of Rust | ||
as well as the main aspects of CLI applications. | ||
What follows are chapters that go into more detail | ||
on some of these aspects. | ||
|
||
One last thing before we dive right into CLI applications: | ||
If you found an error in this book | ||
or want to help us write more content for it, | ||
you can find its source [in the CLI WG repository][book-src]. | ||
We'd love to year your feedback! | ||
Thank you! | ||
|
||
[book-src]: https://github.com/rust-lang-nursery/cli-wg |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
# Using config files |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
# Rendering documentation for you CLI apps |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
# Exit codes |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
# Communicating with humans |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
# In-depth topics |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
# Communicating with machines |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
# Packaging apps and distributing them for different platforms |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
# Signal handling |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
.content aside { | ||
padding-top: 0.1em; | ||
margin-left: 0.1em; | ||
padding-left: 1em; | ||
border-left: 3px solid #ccc; | ||
padding-bottom: 0.1em; | ||
margin-bottom: 0.6em; | ||
} | ||
|
||
.content aside *:first-child { | ||
margin-top: 0.2em; | ||
} | ||
|
||
.content aside *:last-child { | ||
margin-bottom: 0.2em; | ||
} | ||
|
||
.content aside.todo { | ||
border-left-color: yellow; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
## Parsing command line arguments | ||
|
||
A typical invocation of our CLI tool will look like this: | ||
`grrs foobar test.txt`. | ||
You can think of CLI arguments as a data type. | ||
In our case, we have two fields, | ||
`pattern` (the string to look for), | ||
and `path` (the file to look in). | ||
In Rust, it is very common to try and structure programs around the data they deal with. | ||
This is a good start: | ||
|
||
```rust | ||
struct Cli { | ||
pattern: String, | ||
path: std::path::PathBuf, | ||
} | ||
``` | ||
|
||
<aside> | ||
|
||
**Aside:** `PathBuf` is like a `String` but for file system paths that works cross-platform. | ||
|
||
</aside> | ||
|
||
Now, we still need to actually get the arguments the user passed into this form. | ||
One option would be manually parse the list of strings we get from the operating system, | ||
but a much nicer way is to use one of the many available libraries. | ||
As you can see in the `src/main.rs` file, | ||
our templates already contains some code using `clap`, | ||
and in particular use it’s “derive” feature. | ||
This is quite nice: | ||
All we have to do is annotate a struct and it’ll generate the code that parses the arguments into the fields. | ||
Let’s add our fields to the `Cli` struct in the template | ||
and also some documentation comments along the way. | ||
It’ll look like this: | ||
|
||
```rust | ||
/// Search for a pattern in a file and display the lines that contain it. | ||
#[derive(Clap)] | ||
struct Cli { | ||
/// The pattern to look for | ||
pattern: String, | ||
/// The path to the file to read | ||
path: std::path::PathBuf, | ||
} | ||
``` | ||
|
||
Right below the `Cli` struct our template contains its `main` function. | ||
When the program starts, it will call this function. | ||
The first line is | ||
|
||
```rust | ||
let args = Cli::parse(); | ||
``` | ||
|
||
This will try to parse the arguments the user gave when executing the program into our `Cli` struct. | ||
You might be wondering what happens if this fails. | ||
Give it a try! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
## Nicer error reporting | ||
|
||
<aside class="todo"> | ||
|
||
**TODO:** Replace `?` with `.with_context(|_| format!("could not read file {}", args.path))` | ||
|
||
</aside> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
## First implementation of `grrs` | ||
|
||
Right, now that we have our input data, | ||
we can start to write our actual tool. | ||
Let’s start by opening the file: | ||
|
||
```rust | ||
let content = std::fs::read_to_string(&args.path)?; | ||
``` | ||
|
||
<aside> | ||
|
||
**Aside:** If the File can’t be read, the `?` will propagate the error and stop the function. | ||
|
||
</aside> | ||
|
||
Now, let’s iterate over the lines and print each one that contains our pattern: | ||
|
||
```rust | ||
for line in content.lines() { | ||
if line.contains(args.pattern) { | ||
println!("{}", line); | ||
} | ||
} | ||
``` | ||
|
||
Give it a try: `cargo run -- main src/main.rs` should work now! | ||
|
||
<aside> | ||
|
||
**Aside:** This is not the most performant implementation, and will read the whole file into memory. | ||
Feel free to optimize it! | ||
(One idea might be to use a `[BufReader](https://doc.rust-lang.org/1.27.0/std/io/struct.BufReader.html)` instead of `read_to_string()`.) | ||
|
||
</aside> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
# Learning Rust by Writing a Command Line App in 15 Minutes | ||
|
||
This short tutorial will guide you through writing | ||
a CLI (command line interface) application | ||
in [Rust]. | ||
It will take you roughly fifteen minutes; | ||
but feel free to skip parts you don't need to know right now | ||
or jump in at any point. | ||
You’ll learn all the essentials about how to get going, | ||
and where to find more information. | ||
|
||
[Rust]: https://rust-lang.org/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
## Output | ||
|
||
### Logging | ||
|
||
To make it easier to understand what is happening in our program, | ||
we might want to add some log statements. | ||
This is usually easy while writing your application. | ||
But it will become super helpful when running this program again in half a year. | ||
|
||
<aside> | ||
|
||
**Aside:** Experience has shown that even mildly useful CLI programs can end up being used for years to come. | ||
Especially if they were meant as a temporary solution. | ||
|
||
</aside> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
## Packaging and rendering documentation | ||
|
||
If you feel confident that your program is ready to for other people to use, | ||
it is time to package it! | ||
|
||
<aside class="todo"> | ||
|
||
**TODO:** Talk about packaging on CI | ||
|
||
</aside> | ||
<aside class="todo"> | ||
|
||
**TODO:** Talk about automatically generating Man pages in a build script | ||
|
||
</aside> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
## Project setup | ||
|
||
If you haven’t already, | ||
[install Rust](https://www.rust-lang.org/install.html) on your computer (it should only take a few minutes). | ||
After that, open a terminal and navigate to the directory you want to put your application code into. | ||
|
||
What kind of project to you want to write? | ||
How about we start with something simple: | ||
Let’s write a small `grep` clone. | ||
That is a tool that we can give a string and a path and it’ll tell us which lines contain the string. | ||
Let’s call it `grrs` (pronounced “grass”). | ||
|
||
If you’ve already seen the basic Rust tutorials, | ||
you might be inclined to start with `cargo new --bin my-cool-app`. | ||
To save us some time, | ||
we’ll instead start with a CLI-specific template: | ||
`cargo generate --git https://github.com/rust-clique/cargo-template-cli`. | ||
When you run this, it’ll ask you for a project name. | ||
|
||
If look at the newly created `grrs` directory, | ||
you’ll find a typical setup for a Rust project: | ||
|
||
- A `Cargo.toml` file that contains metadata for our project, incl. a list of dependencies/external libraries we use. | ||
- A `src/main.rs` file that is the entry point for our (main) binary. | ||
- A `tests/` directory that will contain integration tests for our tool. | ||
|
||
If you can execute `cargo run` in the `grrs` directory and see it greet you, you’re all set up. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
## Testing | ||
|
||
<aside class="todo"> | ||
|
||
**TODO:** Talk about using assert_cli’s features to quickly run cargo binaries with different inputs and assert their outputs. | ||
|
||
</aside> | ||
<aside class="todo"> | ||
|
||
**TODO:** Talk about generating temp dirs with demo files. | ||
|
||
</aside> |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
to
->do