Skip to content
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

Open
wants to merge 15 commits into
base: main
Choose a base branch
from
Open

setup xtask infra for cheatsheets #159

wants to merge 15 commits into from

Conversation

miguelraz
Copy link
Contributor

@miguelraz miguelraz commented Jun 10, 2024

Problem:

Making cheatsheets like "From Python to Rust" and friends is going to be a maintainability nightmare as training-materials grows, changes ownership, etc., over time. This was raised as a concern in #148 and this PR seeks to fix that.

Proposed solution:

Setup a xtask style workflow where we

  • 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.

The code is (I think) defensive to spare future pain for someone else looking at this code (myself in a few months).

This PR only sets up the infrastructure but doesn't add any cheatsheets themselves - I'll file a separate PR with a basic Julia cheatsheet once this lands to separate concerns.


Current functionality:
❯ cargo xtask make-cheatsheet python
   Compiling xtask v0.1.0 (C:\Users\mrg\work\rust-training\xtask)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 1.10s
     Running `target\debug\xtask.exe make-cheatsheet python`
Cheatsheat for python written at ./training-slides/src/python-cheatsheet.md

❯ cat .\training-slides\src\python-cheatsheet.md
# Rust Fundamentals
## Overview
## Installation
## Basic Types
## Control Flow
## Compound Types
## Ownership and Borrowing
## Error Handling
## Collections
## Iterators
## Imports and Modules
## Good Design Practices

# Applied Rust
## Methods and Traits
## Rust I/O Traits
## Generics
## Lifetimes
## Cargo Workspaces
## Heap Allocation (Box and Rc)
## Shared Mutability (Cell, RefCell)
## Thread Safety (Send/Sync, Arc, Mutex)
## Closures and the Fn/FnOnce/FnMut traits
## Spawning Threads and Scoped Threads

# Advanced Rust
## Advanced Strings
## Debugging Rust
## Dependency Management with Cargo
## Deref Coercions
## Design Patterns
## Documentation
## Drop, Panic and Abort
## Dynamic Dispatch
## Macros
## Property Testing
## Rust Projects Build Time
## Send and Sync
## Serde
## Testing
## The stdlib
## Using Cargo
## Using Types to encode State
## WASM

❯ cargo xtask make-cheatsheet python
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.04s
     Running `target\debug\xtask.exe make-cheatsheet python`
File python-cheatsheet.md already exists - checking it's in sync
Neat! python-cheatsheet.md is in sync

rust-training on  xtask-cheatsheet [$?] via 🦀 v1.78.0
❯ cargo xtask test-cheatsheet python
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.04s
     Running `target\debug\xtask.exe test-cheatsheet python`
Neat! python-cheatsheet.md is in sync

Copy link

cloudflare-workers-and-pages bot commented Jun 13, 2024

Deploying ferrous-systems-rust-training with  Cloudflare Pages  Cloudflare Pages

Latest commit: d85c40f
Status: ✅  Deploy successful!
Preview URL: https://84f9496e.ferrous-systems-rust-training.pages.dev
Branch Preview URL: https://xtask-cheatsheet.ferrous-systems-rust-training.pages.dev

View logs

@miguelraz miguelraz marked this pull request as ready for review June 13, 2024 01:41
@jonathanpallant
Copy link
Member

Could we add a few words (here, or in a README) about how the cheatsheets work - to save having to read and understand the source code?

@jonathanpallant
Copy link
Member

Also, it needs a rebase on main to fix the CloudFlare CI failure, and some thought about the workspaces to fix the GHA CI failure.

@miguelraz
Copy link
Contributor Author

@jonathanpallant

  • added a README.md
  • rebased to main to have Cloudflare deploy passing
  • fixed workspace issue by adding a exclude = ["examples/"] array to the Cargo.toml and CI is happy

xtask/README.md Outdated Show resolved Hide resolved
As `training-material` grows and changes, maintenance could be a nightmare. We basically don't want to be in the business of remember that a certain slide got reordered or moved from one section to another and thus needs changing in all the cheathseets 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`
Copy link
Member

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.


// 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<_>>();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this line for? args is already a Vec<String> right?

let args = env::args().skip(1).collect::<Vec<_>>();
let args = args.iter().map(|arg| &arg[..]).collect::<Vec<_>>();

let langs = vec!["python", "go", "cpp", "swift", "java", "julia", "c"];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could be an array?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup!

let langs = vec!["python", "go", "cpp", "swift", "java", "julia", "c"];

if !langs.contains(&args[1]) {
panic!("{} is not a valid language name. \nExpected one of: python, go, cpp, swift, java, julia, c", &args[1]);
Copy link
Member

Choose a reason for hiding this comment

The 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.

["test-cheatsheet", lang] => tasks::test_cheatsheet(lang),
_ => {
eprintln!(
"cargo xtask
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps move to a static HELP_TEXT: &'static str = "..." so it doesn't confuse the formatting of the match expression.

}

#[test]
fn test_get_slide_name() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tests should go in a #[cfg(test)] mod test { ... }

panic!("YOUR LAST_HEADER is not part of the text input. CHECK your `SUMMARY.md` for {LAST_HEADER}");
}

let first_header = text.find(INITIAL_HEADER).unwrap();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can handle the error here rather than having a separate contains check which might get isolated from this line.

let Some(first_header) = text.find(INITIAL_HEADER) else {
    panic!("Could not find the initial header {INITIAL_HEADER:?}. Check your `SUMMARY.md`");
}

}

#[test]
fn test_focus_regions() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tests should go in a #[cfg(test)] mod test { ... }

}

#[test]
fn test_extract_slides() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tests should go in a #[cfg(test)] mod test { ... }

@jonathanpallant
Copy link
Member

OK, I think this tool makes sense. I had some minor points about the program itself, but I also think we should be running the unit tests in CI, and testing our cheat-sheets in CI.

Co-authored-by: Jonathan Pallant <[email protected]>
@jonathanpallant
Copy link
Member

re-assign to me when you're ready, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants