Skip to content

Commit

Permalink
Use Diff2Html everywhere.
Browse files Browse the repository at this point in the history
  • Loading branch information
Gohla committed Sep 20, 2023
1 parent f8bbff8 commit 3dd525d
Show file tree
Hide file tree
Showing 13 changed files with 74 additions and 104 deletions.
4 changes: 2 additions & 2 deletions tutorial/book.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ title = "Build your own Programmatic Incremental Build System"
create-missing = false

[output.html]
additional-js = ["src/diff2html-ui-base.min.js", "src/diff.js"]
additional-css = ["src/diff2html.min.css", "src/mdbook-admonish.css", "src/custom.css"]
additional-js = ["src/diff2html-ui-base.min.js"]
additional-css = ["src/diff2html.min.css", "src/mdbook-admonish.css"]
git-repository-url = "https://github.com/Gohla/pie/"
edit-url-template = "https://github.com/Gohla/pie/edit/master/tutorial/{path}"

Expand Down
16 changes: 8 additions & 8 deletions tutorial/src/1_programmability/2_non_incremental/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ However, incrementality is *hard*, so let's start with an extremely simple non-i
Since we will be implementing three different contexts in this tutorial, we will separate them in different modules.
Create the `context` module by adding a module to `pie/src/lib.rs`:

```rust,customdiff
{{#include ../../gen/1_programmability/2_non_incremental/a_context_module.rs.diff:4:}}
```diff2html fromfile
../../gen/1_programmability/2_non_incremental/a_context_module.rs.diff
```

This is a diff over `pie/src/lib.rs` where lines with a green background are additions, lines with a red background are removals, and lines with a grey background are context on where to add/remove lines, similar to diffs on source code hubs like GitHub.
Expand Down Expand Up @@ -119,8 +119,8 @@ This macro is typically [used in tests](https://doc.rust-lang.org/book/ch11-01-w
Our first test only tests a single task that does not use the context, so let's write a test with two tasks where one requires the other to increase our test coverage.
Add the following test:

```rust,customdiff
{{#include ../../gen/1_programmability/2_non_incremental/e_test_problematic.rs.diff:4:}}
```diff2html fromfile
../../gen/1_programmability/2_non_incremental/e_test_problematic.rs.diff
```

We use the same `ReturnHelloWorld` task as before, but now also have a `ToLowerCase` task which requires `ReturnHelloWorld` and then turn its string lowercase.
Expand All @@ -136,8 +136,8 @@ This doesn't work as `Context<ToLowerCase>::require_task` only takes a `&ToLower

We could change `execute` of `ToLowerCase` to take `Context<ReturnHelloWorld>`:

```rust,customdiff
{{#include ../../gen/1_programmability/2_non_incremental/f_test_incompatible.rs.diff:4:}}
```diff2html fromfile
../../gen/1_programmability/2_non_incremental/f_test_incompatible.rs.diff
```

But that is not allowed:
Expand Down Expand Up @@ -176,8 +176,8 @@ Therefore, in this tutorial we will keep it simple.
For now, we will solve this by just using a single task type which is an enumeration of the different possible tasks.
Replace the test with the following:

```rust,customdiff
{{#include g_test_correct.rs.diff:4:}}
```diff2html fromfile
g_test_correct.rs.diff
```

Here, we instead define a single task `Test` which is an `enum` with two variants.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ pub trait Context<T: Task> {
/// - `Ok(None)` if no file exists at given `path` (but a directory could exist at given `path`),
/// - `Err(e)` if there was an error getting the metadata for given `path`, or if there was an error opening the file.
fn require_file<P: AsRef<Path>>(&mut self, path: P) -> Result<Option<File>, io::Error>;

/// Requires given `task`, recording a dependency and selectively executing it. Returns its up-to-date output.
fn require_task(&mut self, task: &T) -> T::Output;
}
16 changes: 8 additions & 8 deletions tutorial/src/2_incrementality/1_require_file/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ Therefore, we will extend the `Context` API with methods to *require files*, ena

Add a method to the `Context` trait in `pie/src/lib.rs`:

```rust,customdiff
{{#include ../../gen/2_incrementality/1_require_file/a_context.rs.diff:4:}}
```diff2html fromfile
../../gen/2_incrementality/1_require_file/a_context.rs.diff
```

`require_file` is similar to requiring a task, but instead takes a `path` to a file or directory on the filesystem as input.
Expand Down Expand Up @@ -38,8 +38,8 @@ However, because we will be performing similar file system operations in the inc

Add the `fs` module to `pie/src/lib.rs`:

```rust,customdiff
{{#include ../../gen/2_incrementality/1_require_file/b_fs_module.rs.diff:4:}}
```diff2html fromfile
../../gen/2_incrementality/1_require_file/b_fs_module.rs.diff
```

Create file `pie/src/fs.rs` with:
Expand Down Expand Up @@ -96,8 +96,8 @@ Your directory structure should now look like this:

To access these utility functions in the `pie` crate, add a dependency to `dev_shared` in `pie/Cargo.toml` along with another create that will help testing:

```toml,customdiff,
{{#include ../../gen/2_incrementality/1_require_file/f_Cargo.toml.diff:4:}}
```diff2html fromfile
../../gen/2_incrementality/1_require_file/f_Cargo.toml.diff
```

We've also added the [assert_matches](https://crates.io/crates/assert_matches) crate, which is a handy library for asserting that a value matches a pattern.
Expand Down Expand Up @@ -129,8 +129,8 @@ This allows us to write more concise tests using error propagation.
Now we are done unwinding our stack and have filesystem and testing utilities.
Make the non-incremental context compatible by changing `pie/src/context/non_incremental.rs`:

```rust,customdiff
{{#include ../../gen/2_incrementality/1_require_file/h_non_incremental_context.rs.diff:4:}}
```diff2html fromfile
../../gen/2_incrementality/1_require_file/h_non_incremental_context.rs.diff
```

Since the non-incremental context does not track anything, we only try to open the file and return it, matching the contract in the documentation comment of the `Context::require_file` trait method.
Expand Down
24 changes: 12 additions & 12 deletions tutorial/src/2_incrementality/2_stamp/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ Therefore, we will implement a `FileStamper` that stamps files and produces a `F

Add the `stamp` module to `pie/src/lib.rs`:

```rust,customdiff
{{#include ../../gen/2_incrementality/2_stamp/a_module.rs.diff:4:}}
```diff2html fromfile
../../gen/2_incrementality/2_stamp/a_module.rs.diff
```

This module is public as users of the library will construct stampers.
Expand Down Expand Up @@ -88,15 +88,15 @@ Even worse, our test can be flaky, sometimes succeeding if we write in between t
To solve this, add a function to the filesystem testing utility crate.
Change `dev_shared/src/lib.rs`:

```rust,customdiff,
{{#include ../../gen/2_incrementality/2_stamp/d2_test_utilities.rs.diff:4:}}
```diff2html fromfile
../../gen/2_incrementality/2_stamp/d2_test_utilities.rs.diff
```

The `write_until_modified` function writes to the file, but ensures its modified time will change.
Now change the tests in `pie/src/stamp.rs` to use this function:

```rust,customdiff,
{{#include ../../gen/2_incrementality/2_stamp/d3_test_correct.rs.diff:4:}}
```diff2html fromfile
../../gen/2_incrementality/2_stamp/d3_test_correct.rs.diff
```

Now we use `write_until_modified` to write to the file, ensuring its modified time will change, ensuring the stamp will change when it should.
Expand All @@ -110,8 +110,8 @@ Therefore, we need to update the `Context` trait to allow passing in these stamp

Change `Context` in `pie/src/lib.rs`:

```rust,customdiff
{{#include ../../gen/2_incrementality/2_stamp/e_context_file.rs.diff:4:}}
```diff2html fromfile
../../gen/2_incrementality/2_stamp/e_context_file.rs.diff
```

We add the `require_file_with_stamper` method which allow passing in a stamper.
Expand All @@ -120,14 +120,14 @@ The default is provided by `default_require_file_stamper` which can be overridde

Now apply the same to tasks, changing `Context` again in `pie/src/lib.rs`:

```rust,customdiff
{{#include ../../gen/2_incrementality/2_stamp/f_context_task.rs.diff:4:}}
```diff2html fromfile
../../gen/2_incrementality/2_stamp/f_context_task.rs.diff
```

Update `NonIncrementalContext` in `src/context/non_incremental.rs` to implement the new methods:

```rust,customdiff
{{#include ../../gen/2_incrementality/2_stamp/g_non_incremental_context.rs.diff:4:}}
```diff2html fromfile
../../gen/2_incrementality/2_stamp/g_non_incremental_context.rs.diff
```

We just ignore the stampers in `NonIncrementalContext`, as they are only needed for incrementality.
Expand Down
4 changes: 2 additions & 2 deletions tutorial/src/2_incrementality/3_dependency/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ We will also implement a `Dependency` type that abstracts over `FileDependency`

Add the `dependency` module to `pie/src/lib.rs`:

```rust,customdiff
{{#include ../../gen/2_incrementality/3_dependency/a_module.rs.diff:4:}}
```diff2html fromfile
../../gen/2_incrementality/3_dependency/a_module.rs.diff
```

This module is private, as users of the library should not construct dependencies.
Expand Down
16 changes: 8 additions & 8 deletions tutorial/src/2_incrementality/4_store/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,16 @@ The implementation in the `incremental-topo` library is based on a [paper by D.

Add the `pie_graph` dependency to `pie/Cargo.toml`:

```rust,customdiff
{{#include ../../gen/2_incrementality/4_store/a_Cargo.toml.diff:4:}}
```diff2html fromfile
../../gen/2_incrementality/4_store/a_Cargo.toml.diff
```

## Store basics

Add the `store` module to `pie/src/lib.rs`:

```rust,customdiff
{{#include ../../gen/2_incrementality/4_store/b_module.rs.diff:4:}}
```diff2html fromfile
../../gen/2_incrementality/4_store/b_module.rs.diff
```

This module is private, as users of the library should not interact with the store.
Expand Down Expand Up @@ -73,14 +73,14 @@ This is also the reason for the `Eq` and `Hash` trait bounds on the `Task` trait

Change `pie/src/store.rs` to add hash maps to map between these things:

```rust,customdiff
{{#include ../../gen/2_incrementality/4_store/d1_mapping_diff.rs.diff:4:}}
```diff2html fromfile
../../gen/2_incrementality/4_store/d1_mapping_diff.rs.diff
```

To prevent accidentally using a file node as a task node, and vice versa, change `pie/src/store.rs` to add specific types of nodes:

```rust,customdiff
{{#include ../../gen/2_incrementality/4_store/d2_mapping_diff.rs.diff:4:}}
```diff2html fromfile
../../gen/2_incrementality/4_store/d2_mapping_diff.rs.diff
```

The `FileNode` and `TaskNode` types are [newtypes](https://rust-unofficial.github.io/patterns/patterns/behavioural/newtype.html) that wrap a `Node` into a specific type of node.
Expand Down
34 changes: 17 additions & 17 deletions tutorial/src/2_incrementality/5_context/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ Now we will create the `TopDownContext` type which implements the `Context` trai

Add the `top_down` module to `pie/src/context/mod.rs`:

```rust,customdiff
{{#include ../../gen/2_incrementality/5_context/a_module.rs.diff:4:}}
```diff2html fromfile
../../gen/2_incrementality/5_context/a_module.rs.diff
```

Create the `pie/src/context/top_down.rs` file and add the following to get started:
Expand All @@ -30,8 +30,8 @@ Therefore, we will need to keep track of the current executing task.

Change `pie/src/context/mod.rs` to add a field for tracking the current executing task, and use it in `require_file_with_stamper`:

```rust,customdiff
{{#include ../../gen/2_incrementality/5_context/c_current.rs.diff:4:}}
```diff2html fromfile
../../gen/2_incrementality/5_context/c_current.rs.diff
```

We're not setting `current_executing_task` yet, as that is the responsibility of `require_task_with_stamper` which we will implement later.
Expand All @@ -40,8 +40,8 @@ If there is no current executing task, which only happens if a user directly cal

Now we need to add the file dependency, change `pie/src/context/mod.rs` to do this:

```rust,customdiff
{{#include ../../gen/2_incrementality/5_context/d_file.rs.diff:4:}}
```diff2html fromfile
../../gen/2_incrementality/5_context/d_file.rs.diff
```

We simply create or get an existing file node, create a file dependency, and add the file require dependency to the graph via `store`.
Expand All @@ -55,8 +55,8 @@ If we don't execute it, then it must have an output value and all its dependenci

Change `pie/src/context/mod.rs` to implement this logic:

```rust,customdiff
{{#include ../../gen/2_incrementality/5_context/e_task.rs.diff:4:}}
```diff2html fromfile
../../gen/2_incrementality/5_context/e_task.rs.diff
```

We first create or get an existing file node.
Expand All @@ -68,8 +68,8 @@ Finally, we return the output.

We still need to create a task dependency. Change `pie/src/context/mod.rs` to add the dependency:

```rust,customdiff
{{#include ../../gen/2_incrementality/5_context/f_task_dep.rs.diff:4:}}
```diff2html fromfile
../../gen/2_incrementality/5_context/f_task_dep.rs.diff
```

If there is no current executing task, which occurs when a user requires the initial task, we skip creating a dependency.
Expand Down Expand Up @@ -129,10 +129,10 @@ A final note is that care must be taken when [unwiding panics across foreign fun

The final piece to our puzzle is the `should_execute_task` implementation.

Add the following code to `pie/src/context/mod.rs`:
Add the following code to `pie/src/context/top_down.rs`:

```rust,customdiff,
{{#include ../../gen/2_incrementality/5_context/g_check.rs.diff:4:}}
```diff2html fromfile
../../gen/2_incrementality/5_context/g_check.rs.diff
```

The premise of `should_execute_task` is simple: go over the dependencies of a task until `dependency.is_inconsistent` is true, at which we return true.
Expand Down Expand Up @@ -208,14 +208,14 @@ When dependency checking result in an error, we should store the error for the u

Change `pie/src/context/mod.rs` to store dependency check errors and give users access to it:

```rust,customdiff
{{#include ../../gen/2_incrementality/5_context/h_error_field.rs.diff:4:}}
```diff2html fromfile
../../gen/2_incrementality/5_context/h_error_field.rs.diff
```

And then change `pie/src/context/mod.rs` to store these errors:

```rust,customdiff
{{#include ../../gen/2_incrementality/5_context/i_error_store.rs.diff:4:}}
```diff2html fromfile
../../gen/2_incrementality/5_context/i_error_store.rs.diff
```

It took us a while, but now we've implemented an incremental build system with dynamic dependencies 🎉.
Expand Down
28 changes: 14 additions & 14 deletions tutorial/src/3_min_sound/1_session/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ We will implement the `Session` type to hold all session data, and the `Pie` typ

Change the imports in `pie/src/lib.rs`:

```rust,customdiff,
{{#include ../../gen/3_min_sound/1_session/a_lib_import.rs.diff:4:}}
```diff2html fromfile
../../gen/3_min_sound/1_session/a_lib_import.rs.diff
```

Now add the `Pie` and `Session` types to `pie/src/lib.rs`:
Expand Down Expand Up @@ -51,8 +51,8 @@ Now we need to modify `TopDownContext` to work with `Session`.

Change `TopDownContext` to only contain a mutable reference to `Session` in `pie/src/context/top_down.rs`:

```rust,customdiff,
{{#include ../../gen/3_min_sound/1_session/c_top_down_new.rs.diff:4:}}
```diff2html fromfile
../../gen/3_min_sound/1_session/c_top_down_new.rs.diff
```

Here, we use lifetime `'s` to denote the lifetime of a session, and make `TopDownContext` generic over it.
Expand All @@ -65,8 +65,8 @@ You could do this with the following find-replace regex: `self\.([\w\d_]+)\.` ->

Change `pie/src/context/top_down.rs`:

```rust,customdiff,
{{#include ../../gen/3_min_sound/1_session/d_top_down_fix.rs.diff:4:}}
```diff2html fromfile
../../gen/3_min_sound/1_session/d_top_down_fix.rs.diff
```

Now we change `Session` to use `TopDownContext`.
Expand All @@ -75,8 +75,8 @@ Now we change `Session` to use `TopDownContext`.

Change `pie/src/lib.rs`:

```rust,customdiff,
{{#include ../../gen/3_min_sound/1_session/e_lib_require.rs.diff:4:}}
```diff2html fromfile
../../gen/3_min_sound/1_session/e_lib_require.rs.diff
```

We reset the `current_executing_task` to `None`, to be sure that we start a build without an executing task.
Expand All @@ -85,8 +85,8 @@ Then, we just create a `TopDownContext` and call `require_initial`.
Finally, we can now make the `context` module private, as users of the library run builds using `Session`, instead of having to create a context implementation.
Change `pie/src/lib.rs`:

```rust,customdiff,
{{#include ../../gen/3_min_sound/1_session/f_lib_private_module.rs.diff:4:}}
```diff2html fromfile
../../gen/3_min_sound/1_session/f_lib_private_module.rs.diff
```

Check that the code compiles with `cargo check --lib`.
Expand All @@ -97,14 +97,14 @@ We need to update the incrementality example to work with these changes.

First change some imports in `pie/examples/incremental.rs`:

```rust,customdiff,
{{#include ../../gen/3_min_sound/1_session/g_example_import.rs.diff:4:}}
```diff2html fromfile
../../gen/3_min_sound/1_session/g_example_import.rs.diff
```

Then, change `pie/examples/incremental.rs` to use sessions:

```rust,customdiff,
{{#include ../../gen/3_min_sound/1_session/h_example.rs.diff:4:}}
```diff2html fromfile
../../gen/3_min_sound/1_session/h_example.rs.diff
```

When we only require one task, we replace `context.require_task` with `pie.new_session().require`.
Expand Down
3 changes: 0 additions & 3 deletions tutorial/src/custom.css

This file was deleted.

Loading

0 comments on commit 3dd525d

Please sign in to comment.