-
Notifications
You must be signed in to change notification settings - Fork 18
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
setup xtask infra for cheatsheets #159
base: main
Are you sure you want to change the base?
Changes from all commits
328a963
1357aea
ead0e8f
5c04043
1a4b33e
3d9c2de
0bcc288
fbe4766
33e8014
4d34c0f
ddd8c18
ce4e707
54067a4
ab2ef80
d85c40f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
[alias] | ||
xtask = "run --manifest-path xtask/Cargo.toml --" |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
[workspace] | ||
members = [ | ||
"xtask", | ||
] | ||
exclude = ["example-code/"] | ||
|
||
resolver = "2" | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
[package] | ||
name = "xtask" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
[dependencies] | ||
color-eyre = "0.6.3" | ||
eyre = "0.6.12" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
# Cheatsheets | ||
|
||
## Why | ||
|
||
Teaching Rust can be hard, and it's harder when trainees we teach come from different programming language backgrounds. | ||
|
||
A person in Python might have more questions about memory safety in general, since the GC allows them not to worry about that, but a person from C++ would be confused by the keyword `move` in a closure. | ||
|
||
To alleviate this, we've created some cheatsheets of the form | ||
|
||
``` | ||
# Applied Rust | ||
|
||
## Methods and Traits | ||
... | ||
## Rust I/O Traits | ||
... | ||
## Generics | ||
... | ||
``` | ||
|
||
per programming language that match each slide we have in our normal syllabus with an entry on the second header (`## Methods and Traits`, for example) level. | ||
|
||
## How | ||
|
||
As `training-material` grows and changes, maintenance could be a nightmare. We basically don't want to be in the business of remembering that a certain slide got reordered or moved from one section to another and thus needs changing in all the cheatsheets as well. Therefore, this tool seeks to alleviate that with the following workflow: | ||
|
||
* call `cargo xtask make-cheatsheet python` at the root folder | ||
* scrape Markdown headers in `SUMMARY.md` and segment topics by `Rust Fundamentals`, `Applied Rust` and `Advanced Rust` | ||
* write out to `src/python-cheatsheet.md` if it doesn't exist | ||
* if it does exist, check that it in sync: all headers in `python-cheatsheet.md` are in the appropriate sections, in order, and none are missing. | ||
|
||
Specifically, `make-cheatsheet` and `test-cheatsheet` are defined in `xtask/src/tasks.rs` with utility functions to take our `SUMMARY.md` | ||
|
||
``` | ||
# Rust Fundamentals | ||
* [Overview](./src/overview.md) | ||
* [Installation](.src/installation.md) | ||
* [Basic Types](./src/basic-types.md) | ||
... | ||
# Applied Rust | ||
* [Methods and Traits](./src/methods-and-traits.md) | ||
* [Rust I/O Traits](./src/rust-io-traits.md) | ||
* [Generics](./src/generics.md) | ||
``` | ||
|
||
and convert it into a `Vec<SlidesSection>`: | ||
|
||
```rust | ||
vec![SlideSection {header: "Rust Fundamentals", | ||
slide_titles: vec!["Overview", "Installation", "Basic Types"]}, | ||
SlideSection {header: "Applied Rust", | ||
slide_titles: vec!["Methods and Traits", "Rust I/O Traits", "Generics"]}] | ||
``` | ||
|
||
From there we can | ||
|
||
* create the cheatsheet for Python and have it written out to `training-slides/src/python-cheatsheet.md` by just iterating over `Vec<SlideSection>` and prefixing with the appropriate header level before printing | ||
* test that the cheathseet is in sync by scraping for all the lines that start with `#` in `python-cheatsheet.md` and check that they match, in order, those we scraped from `SUMMARY.md`. | ||
|
||
Note: some languages will warrant some special entries - any headers after the last `SlideSection` header will be ignored, | ||
so that we can add additional relevant information without having to conform to the slides. | ||
|
||
Concretely, this is allowed: | ||
|
||
```md | ||
|
||
# Applied Rust | ||
## Methods and Traits | ||
## Rust I/O Traits | ||
## Generics | ||
# FAQ | ||
## How to do... | ||
# Syntax Clashes | ||
## Operator overloading | ||
... | ||
``` | ||
|
||
but the code will signal if `# FAQ` or `# Syntax Clashes` appear before `# Applied Rust`. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
//#![deny(warnings)] | ||
|
||
mod tasks; | ||
|
||
use std::env; | ||
|
||
// Code adapted from the xtask workflow in rust-exercises | ||
fn main() -> color_eyre::Result<()> { | ||
color_eyre::install()?; | ||
|
||
// first arg is the name of the executable; skip it | ||
let args = env::args().skip(1).collect::<Vec<_>>(); | ||
let args = args.iter().map(|arg| &arg[..]).collect::<Vec<_>>(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is this line for? |
||
|
||
let langs = vec!["python", "go", "cpp", "swift", "java", "julia", "c"]; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could be an array? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yup! |
||
|
||
if !langs.contains(&args[1]) { | ||
panic!("{} is not a valid language name. \nExpected one of: python, go, cpp, swift, java, julia, c", &args[1]); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd print the lang list in the panic so it doesn't get out of sync. |
||
} | ||
|
||
match &args[..] { | ||
["make-cheatsheet", lang] => tasks::make_cheatsheet(lang), | ||
["test-cheatsheet", lang] => tasks::test_cheatsheet(lang), | ||
_ => { | ||
eprintln!( | ||
"cargo xtask | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Perhaps move to a |
||
|
||
USAGE: | ||
cargo xtask [COMMAND] | ||
|
||
COMMANDS: | ||
make-cheatsheet [LANG] make LANG cheatsheet by scraping slides names in `SUMMARY.md` | ||
test-cheatsheet [LANG] test LANG's cheatsheet (all `SUMMARY.md` items are in sheet and viceversa) | ||
|
||
LANG: | ||
Valid values are `python, go, cpp, swift, java, julia, c` | ||
", | ||
); | ||
|
||
Ok(()) | ||
} | ||
} | ||
} |
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.
Who does this - the user or the tool? Because step 1 in this list is something the user has to do.