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

chore(justfile): improve cargo bin installation #241

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions book/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
# generated by mdbook
book
# these are generated by the RFC preprocessor
src/rfcs
src/SUMMARY.md
45 changes: 45 additions & 0 deletions book/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# MnemOS Book

This folder contains long-form documentation for the MnemOS operating system
generated using [mdBook].

See <https://mnemos.dev/mnemosprojectoverview/book/> for a rendered version of the
MnemOS book.

## Contributing to the Book

For details on the mdBook documentation format, see the ["Format"
section of the mdBook documentation][mdbook-format].

## Building the Book

When building the published documentation on <https://mnemos.dev>, the mdBook is
built using [Oranda], rather than the mdBook command-line tool. Therefore,
[Oranda] is the preferred way to build the documentation.

Unlike other mdBook projects, this directory does not contain a SUMMARY.md
file. This is because the SUMMARY.md file is automatically generated, in order
to append the [mnemOS RFCs](../rfcs/) to the mdBook. This is performed
by the [`rfc2book.py`][rfc2book] script in [`scripts/`](../scripts/).

> [!IMPORTANT]
>
> Therefore, **[`scripts/rfc2book.py`][rfc2book] must be run**
> before running any [mdBook] or [Oranda] commands to build the book.

### Just Recipes

The `just oranda` [Just recipe] will automatically run [`rfc2book.py]` prior
to running an [Oranda] command. This is the recommended way to build the book
locally.

Similarly, mdBook CLI commands can also be run using the `just mdbook` [Just
recipe], which will run [`rfc2book.py`][rfc2book] beforehand. Both of these
commands will also offer to install [mdBook] and [Oranda] if they are not
already present on the system.

[mdBook]: https://rust-lang.github.io/mdBook/
[mdbook-format]: https://rust-lang.github.io/mdBook/format/index.html
[Oranda]: https://opensource.axo.dev/oranda/
[rfc2book]: ../scripts/rfc2book.py
[Just recipe]: ../justfile
2 changes: 1 addition & 1 deletion book/book.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ authors = ["James Munns"]
language = "en"
multilingual = false
src = "src"
title = "mnemOS Book"
title = "mnemOS Book"
9 changes: 9 additions & 0 deletions book/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,12 @@
- [the drivers](./components/drivers.md)
- [user applications](./components/userspace.md)



# RFCs

- [Introduction](rfcs/README.md)
- [0025-driver-registry](rfcs/0025-driver-registry.md)
- [0041-a-forth-userspace](rfcs/0041-a-forth-userspace.md)
- [0196-wifi-buddy-interface](rfcs/0196-wifi-buddy-interface.md)
- [0199-basic-config](rfcs/0199-basic-config.md)
8 changes: 8 additions & 0 deletions book/src/summary.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Summary

- [introduction](./intro.md)
- [parts of mnemOS](./components/intro.md)
- [the kernel](./components/kernel.md)
- [the drivers](./components/drivers.md)
- [user applications](./components/userspace.md)

38 changes: 29 additions & 9 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,15 @@ _fmt_check_doc := if env_var_or_default("GITHUB_ACTIONS", "") != "true" { "" } e
```
}

# if `cargo binstall` is found, prefer it when installing binaries.
_cargo_install := ```
if {{ _cargo }} --list | grep -q binstall; then
echo "binstall"
else
echo "install"
fi
```

_d1_start_addr := "0x40000000"
_d1_bin_path := "target/riscv64imac-unknown-none-elf"
_d1_pkg := "mnemos-d1"
Expand Down Expand Up @@ -109,7 +118,7 @@ clippy-crate crate *ARGS:
{{ _fmt_clippy }}

# test all packages, across workspaces
test: (_get-cargo-command "nextest" "cargo-nextest" no-nextest)
test: (_get-cargo-bin "cargo-nextest" no-nextest)
{{ _cargo }} nextest run --all-features

# run rustfmt for all crates, across workspaces
Expand All @@ -121,7 +130,7 @@ fmt:
{{ _cargo }} fmt --package {{ _x86_bootloader_pkg }}

# build a Mnemos binary for the Allwinner D1
build-d1 board='mq-pro': (_get-cargo-command "objcopy" "cargo-binutils")
build-d1 board='mq-pro': (_get-cargo-bin "cargo-binutils")
{{ _cargo }} build \
--profile {{ profile }} \
--package {{ _d1_pkg }} \
Expand All @@ -147,7 +156,7 @@ build-c3 board:
--bin {{ board }}

# flash an ESP32-C3 with the MnemOS WiFi Buddy firmware
flash-c3 board *espflash-args: (_get-cargo-command "espflash" "cargo-espflash") (build-c3 board)
flash-c3 board *espflash-args: (_get-cargo-bin "cargo-espflash") (build-c3 board)
{{ _cargo }} espflash flash \
--profile {{ profile }} \
--package {{ _espbuddy_pkg }} \
Expand Down Expand Up @@ -181,22 +190,33 @@ docs *FLAGS:
{{ FLAGS }} \
{{ _fmt_check_doc }}

_get-cargo-command name pkg skip='':
# run a mdBook command, generating the book's RFC section first.
mdbook CMD="build --open": (_get-cargo-bin "mdbook")
./scripts/rfc2book.py
cd book && mdbook {{ CMD }}


# run an Oranda command, generating the book's RFC section first.
oranda CMD="dev": (_get-cargo-bin "oranda")
./scripts/rfc2book.py
oranda {{ CMD }}

_get-cargo-bin name skip='':
#!/usr/bin/env bash
set -euo pipefail
source "./scripts/_util.sh"

if [ -n "{{ skip }}" ]; then
status "Configured" "not to use cargo-{{ name }}"
status "Configured" "not to use {{ name }}"
exit 0
fi

if {{ _cargo }} --list | grep -q {{ name }}; then
status "Found" "cargo-{{ name }}"
if command -v {{ name }} >/dev/null 2>&1; then
status "Found" "{{ name }}"
exit 0
fi

err "missing cargo-{{ name }} executable"
err "missing {{ name }} executable"
if confirm " install it?"; then
cargo install {{ pkg }}
{{ _cargo }} {{ _cargo_install }} {{ name }}
fi
1 change: 1 addition & 0 deletions rfcs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# MnemOS RFCs
77 changes: 77 additions & 0 deletions scripts/rfc2book.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
#!/usr/bin/env python3
# This script is based on the `generate-book.py` script from the Rust RFCs
# repository: https://github.com/rust-lang/rfcs/blob/2b78d7bd05f718dc7e5023372f8a692d3b448600/generate-book.py

"""
This auto-generates the mdBook SUMMARY.md file based on the layout on the filesystem.

This generates the `src` directory based on the contents of the `text` directory.

Most RFCs should be kept to a single chapter. However, in some rare cases it
may be necessary to spread across multiple pages. In that case, place them in
a subdirectory with the same name as the RFC. For example:

0123-my-awesome-feature.md
0123-my-awesome-feature/extra-material.md

It is recommended that if you have static content like images that you use a similar layout:

0123-my-awesome-feature.md
0123-my-awesome-feature/diagram.svg

The chapters are presented in sorted-order.
"""

import os
import shutil
import subprocess



def main():
src_path = None
rfc_path = None
cwd = os.getcwd()
if cwd.endswith('book'):
src_path = 'src'
rfc_path = '../rfcs'
elif cwd.endswith('mnemos'):
src_path = 'book/src'
rfc_path = 'rfcs'
else:
raise Exception('rfc2book must be run either in the repo root (mnemos/) or in the mdbook (mnemos/book/) directory')

book_rfcs = f'{src_path}/rfcs'

if os.path.exists(book_rfcs):
# Clear out src to remove stale links in case you switch branches.
shutil.rmtree(book_rfcs)
os.mkdir(book_rfcs)

with open(f'{src_path}/summary.md', 'r') as summary_in:
summary = summary_in.read()
with open(f'{src_path}/SUMMARY.md', 'w') as summary_out:
summary_out.write(summary)
summary_out.write('\n\n# RFCs\n\n- [Introduction](rfcs/README.md)\n')
collect(summary_out, rfc_path, src_path, 0)

def collect(summary, path, srcpath, depth):
entries = [e for e in os.scandir(path) if e.name.endswith('.md')]
entries.sort(key=lambda e: e.name)
for entry in entries:
symlink(f'../../../{path}/{entry.name}', f'{srcpath}/rfcs/{entry.name}')
indent = ' '*depth
name = entry.name[:-3]
if name != 'README':
link_path = entry.path[5:]
summary.write(f'- {indent}[{name}](rfcs/{link_path})\n')
maybe_subdir = os.path.join(path, name)
if os.path.isdir(maybe_subdir):
collect(summary, maybe_subdir, srcpath, depth+1)

def symlink(src, dst):
if not os.path.exists(dst):
os.symlink(src, dst)

if __name__ == '__main__':
main()
3 changes: 3 additions & 0 deletions scripts/run-ci-build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ rm -rf ./target/ci-publish || :
mkdir -p ./target/ci-publish/
cp -r ./target/doc ./target/ci-publish/

# Add RFCs to the mdbook before building the Oranda site
./scripts/rfc2book.py

# Build with oranda
oranda build

Expand Down