From 41d045586426dd97d38fa82f28f1087e492dac4c Mon Sep 17 00:00:00 2001 From: askiiart Date: Tue, 12 Nov 2024 15:14:56 -0600 Subject: [PATCH] Add using clap --- assets/using-clap/1.png | Bin 0 -> 38811 bytes blog/benchmarking-dwarfs.html | 4 +- blog/benchmarking-dwarfs.md | 4 +- blog/using-clap.html | 195 ++++++++++++++++++++++++++++++++++ blog/using-clap.md | 170 +++++++++++++++++++++++++++++ feed.xml | 14 ++- glossary.html | 2 + glossary.md | 3 +- sitemap.xml | 2 + style.css | 3 +- 10 files changed, 387 insertions(+), 10 deletions(-) create mode 100644 assets/using-clap/1.png create mode 100644 blog/using-clap.html create mode 100644 blog/using-clap.md diff --git a/assets/using-clap/1.png b/assets/using-clap/1.png new file mode 100644 index 0000000000000000000000000000000000000000..86b3ac39e8fb96e0da1dfb071accc4883aae3d13 GIT binary patch literal 38811 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 BS4jW> literal 0 HcmV?d00001 diff --git a/blog/benchmarking-dwarfs.html b/blog/benchmarking-dwarfs.html index 93931ce..110eea9 100644 --- a/blog/benchmarking-dwarfs.html +++ b/blog/benchmarking-dwarfs.html @@ -20,7 +20,7 @@

The datasets being used for this test will be the following:

diff --git a/blog/benchmarking-dwarfs.md b/blog/benchmarking-dwarfs.md index 1fca903..ec0d102 100644 --- a/blog/benchmarking-dwarfs.md +++ b/blog/benchmarking-dwarfs.md @@ -6,12 +6,12 @@ DwarFS is a filesystem developed by the user mhx on GitHub [1], which is self-de The datasets being used for this test will be the following: -- 25 GB of null data (just `000000000000` in binary) +- 25 GB of null data (just `00000000` in binary) - 25 GB of random data[^1] - Data for a 100 million-sided regular polygon; ~29 GB[^2] - The current Linux longterm release source ([6.6.58](https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.6.58.tar.xz) [2]); ~1.5 GB - For some rough latency testing: - - 1000 4 kilobyte files filled with null data (again, just `0000000` in binary) + - 1000 4 kilobyte files filled with null data (again, just `00000000` in binary) - 1000 4 kilobyte files filled with random data All this data should cover both latency and read speed testing for data that compresses differently - extremely compressible files with null data, decently compressible files, and random data which can't be compressed well. diff --git a/blog/using-clap.html b/blog/using-clap.html new file mode 100644 index 0000000..ab3f202 --- /dev/null +++ b/blog/using-clap.html @@ -0,0 +1,195 @@ + + + + + Using `clap` + + + + +

Using clap

+

Clap stands for Command Line Argument Parser, and put simply, + it's a great library for making command-line stuff with Rust. + Even Cargo, Rust's package manager, depends on it [4], and it's + been downloaded over 300 million times [5].

+

Rather than going over everything clap can do, I'll go over + how I've used it in my disk-read-benchmark program + I'll be using in my next blog post.

+

Basics

+

First off, we need to install clap; make sure to + enable its derive feature as that's what we'll be + using.

+
cargo add clap --features derive
+

First off, we need to get a bit of code just to start + off:

+
use clap::{Parser, Subcommand};
+
+#[derive(Parser)]
+#[command(version, about, long_about = None)]
+pub struct Cli {
+    #[command(subcommand)]
+    pub command: Commands,
+}
+

This has the built-in "version" and "about" options, with the + long "about" option disabled.

+

Next, we need to list all out commands we'll have:

+
#[derive(Subcommand)]
+pub enum Commands {
+    ///Run this thing
+    Run,
+    ///Delete the stuff that thing does
+    Delete,
+}
+

The documentation comments (///) should + not have a space after the slashes, as otherwise the + program will have an extra space where it shouldn't.

+

Finally, we create the main() function. First it + parses everything, then checks what command was run and runs the + relevant code.

+
fn main() {
+    let cli = Cli::parse();
+
+    match cli.command {
+        Commands::Run {
+            run();
+        }
+        Commands::Delete {
+            delete();
+        }
+    }
+}
+

That's all you need to know to use clap at a + very basic level; for more details, check out the docs [1]. But, + you probably don't want to have to type in the entire command + automatically, autocomplete would be nice. So I'll also go over + how to use clap_complete as well.

+

clap_complete

+

Searching through the documentation [2], you'll notice that + the docs don't cover how to use it with clap's derive at all. + Instead, after some Googling, I found an example script in + clap's repository [3], which I then adapted and played + around with a bit until I got it figured out.

+

Anyways, again, we need to install clap_complete + first:

+
cargo add clap_complete
+

Then, add the relevant imports. We'll just being doing it for + the fish shell since that's what I use, so we'll only import + Fish; Bash, Zsh, PowerShell, and Elvish are also + supported.

+
use clap_complete::aot::{generate, Fish};
+

Then, we need to add a command to generate the + completion:

+
#[derive(Subcommand)]
+pub enum Commands {
+    ///Run this thing
+    Run,
+    ///Delete the stuff that thing does
+    Delete,
+    ///Generate fish completions
+    FishCompletions,
+}
+

Next, we actually generate the completion, adding it like + it's another command:

+
    match cli.command {
+        Commands::Run {
+            run();
+        }
+        Commands::Delete {
+            delete();
+        }
+        Commands::GenerateFishCompletions => {
+            generate(
+                Fish,
+                &mut Cli::command(),
+                "example-program",
+                &mut stdout(),
+            );
+        }
+    }
+

To explain the options for generate():

+
    +
  • Fish: The shell we're using.
  • +
  • &mut Cli::command(): I don't actually know + what this does, but understanding ths library fully this is + beyond my pay grade, especially given the somewhat lacking + docs.
  • +
  • "example-program": The name of our program
  • +
  • &mut stdout(): stdout, so that + it can print the completions. Why does it do it this way? I + don't know, it doesn't make sense to me. Why doesn't it just + return it as a String? I don't know. But it works, I + suppose.
  • +
+

As an example of all this, here's my + disk-read-benchmark program, running using all + this. The commands have formatting I can't do, so it looks even + better than I can even show here.

+
~> disk-read-benchmark
+Usage: disk-read-benchmark <COMMAND>
+
+Commands:
+  generate-bash-completions  Generate bash completions
+  generate-zsh-completions   Generate zsh completions
+  generate-fish-completions  Generate fish completions
+  grab-data                  Grabs the datasets used for benchmarking
+  benchmark                  Runs the benchmark
+  prep-dirs                  Prepares the directories so other programs can prepare their datasets
+  run                        Runs it all
+  help                       Print this message or the help of the given subcommand(s)
+
+Options:
+  -h, --help     Print help
+  -V, --version  Print version
+~> disk-read-benchmark generate-fish-completions | source
+~> disk-read-benchmark benchmark --help
+Runs the benchmark
+
+Usage: disk-read-benchmark benchmark
+
+Options:
+  -h, --help  Print help
+

To better see how great it looks, here's a screenshot:

+ The same output, but with very nice formatting - underlining and bolding for headers and the tables +

Pressing tab twice after entering + disk-read-benchmark displays the completions, which + I can select and use like any other program's.

+
~> disk-read-benchmark
+benchmark                         (Runs the benchmark)  grab-data                               (Grabs the datasets used for benchmarking)
+generate-bash-completions  (Generate bash completions)  help                   (Print this message or the help of the given subcommand(s))
+generate-fish-completions  (Generate fish completions)  prep-dirs  (Prepares the directories so other programs can prepare their datasets)
+generate-zsh-completions    (Generate zsh completions)  run                                                                  (Runs it all)
+

Sources

+
    +
  1. https://docs.rs/clap/latest/clap/
  2. +
  3. https://docs.rs/clap_complete/latest/clap_complete/
  4. +
  5. https://github.com/clap-rs/clap/blob/master/clap_complete/examples/completion-derive.rs
  6. +
  7. https://github.com/rust-lang/cargo/blob/master/Cargo.toml
  8. +
  9. https://crates.io/crates/clap
  10. +
+ + + +
+

Source code | RSS | Glossary | About

+ Image captions are the same as the alt text; assuming you're sighted, you can most likely ignore them. +
+ diff --git a/blog/using-clap.md b/blog/using-clap.md new file mode 100644 index 0000000..d029366 --- /dev/null +++ b/blog/using-clap.md @@ -0,0 +1,170 @@ +# Using `clap` + +Clap stands for Command Line Argument Parser, and put simply, it's a great library for making command-line stuff with Rust. Even Cargo, Rust's package manager, depends on it [4], and it's been downloaded over 300 million times [5]. + +Rather than going over everything clap can do, I'll go over how I've used it in my `disk-read-benchmark` program I'll be using in my next blog post. + +## Basics + +First off, we need to install `clap`; make sure to enable its `derive` feature as that's what we'll be using. + +```sh +cargo add clap --features derive +``` + +First off, we need to get a bit of code just to start off: + +```rust +use clap::{Parser, Subcommand}; + +#[derive(Parser)] +#[command(version, about, long_about = None)] +pub struct Cli { + #[command(subcommand)] + pub command: Commands, +} +``` + +This has the built-in "version" and "about" options, with the long "about" option disabled. + +Next, we need to list all out commands we'll have: + +```rust +#[derive(Subcommand)] +pub enum Commands { + ///Run this thing + Run, + ///Delete the stuff that thing does + Delete, +} +``` + +The documentation comments (`///`) should *not* have a space after the slashes, as otherwise the program will have an extra space where it shouldn't. + +Finally, we create the `main()` function. First it parses everything, then checks what command was run and runs the relevant code. + +```rust +fn main() { + let cli = Cli::parse(); + + match cli.command { + Commands::Run { + run(); + } + Commands::Delete { + delete(); + } + } +} +``` + +That's all you need to know to use `clap` at a very basic level; for more details, check out the docs [1]. But, you probably don't want to have to type in the entire command automatically, autocomplete would be nice. So I'll also go over how to use `clap_complete` as well. + +## `clap_complete` + +Searching through the documentation [2], you'll notice that the docs don't cover how to use it with clap's derive at all. Instead, after some Googling, I found an example script in *clap*'s repository [3], which I then adapted and played around with a bit until I got it figured out. + +Anyways, again, we need to install `clap_complete` first: + +```sh +cargo add clap_complete +``` + +Then, add the relevant imports. We'll just being doing it for the fish shell since that's what I use, so we'll only import `Fish`; Bash, Zsh, PowerShell, and Elvish are also supported. + +```rust +use clap_complete::aot::{generate, Fish}; +``` + +Then, we need to add a command to generate the completion: + +```rust +#[derive(Subcommand)] +pub enum Commands { + ///Run this thing + Run, + ///Delete the stuff that thing does + Delete, + ///Generate fish completions + FishCompletions, +} +``` + +Next, we actually generate the completion, adding it like it's another command: + +```rust + match cli.command { + Commands::Run { + run(); + } + Commands::Delete { + delete(); + } + Commands::GenerateFishCompletions => { + generate( + Fish, + &mut Cli::command(), + "example-program", + &mut stdout(), + ); + } + } +``` + +To explain the options for `generate()`: + +- `Fish`: The shell we're using. +- `&mut Cli::command()`: I don't actually know what this does, but understanding ths library fully this is beyond my pay grade, especially given the somewhat lacking docs. +- `"example-program"`: The name of our program +- `&mut stdout()`: `stdout`, so that it can print the completions. Why does it do it this way? I don't know, it doesn't make sense to me. Why doesn't it just return it as a String? I don't know. But it works, I suppose. + +As an example of all this, here's my `disk-read-benchmark` program, running using all this. The commands have formatting I can't do, so it looks even better than I can even show here. + +```txt +~> disk-read-benchmark +Usage: disk-read-benchmark + +Commands: + generate-bash-completions Generate bash completions + generate-zsh-completions Generate zsh completions + generate-fish-completions Generate fish completions + grab-data Grabs the datasets used for benchmarking + benchmark Runs the benchmark + prep-dirs Prepares the directories so other programs can prepare their datasets + run Runs it all + help Print this message or the help of the given subcommand(s) + +Options: + -h, --help Print help + -V, --version Print version +~> disk-read-benchmark generate-fish-completions | source +~> disk-read-benchmark benchmark --help +Runs the benchmark + +Usage: disk-read-benchmark benchmark + +Options: + -h, --help Print help +``` + +To better see how great it looks, here's a screenshot: + +![The same output, but with very nice formatting - underlining and bolding for headers and the tables](/assets/using-clap/1.png) + +Pressing tab twice after entering `disk-read-benchmark` displays the completions, which I can select and use like any other program's. + +```txt +~> disk-read-benchmark +benchmark (Runs the benchmark) grab-data (Grabs the datasets used for benchmarking) +generate-bash-completions (Generate bash completions) help (Print this message or the help of the given subcommand(s)) +generate-fish-completions (Generate fish completions) prep-dirs (Prepares the directories so other programs can prepare their datasets) +generate-zsh-completions (Generate zsh completions) run (Runs it all) +``` + +## Sources + +1. +2. +3. +4. +5. diff --git a/feed.xml b/feed.xml index f906c91..4bd2990 100644 --- a/feed.xml +++ b/feed.xml @@ -5,10 +5,10 @@ eng.askiiart.net This is the feed for engl.askiiart.net, I guess https://askiiart.net - Fri, 04 Oct 2024 00:34:32 +0000 + Tue, 12 Nov 2024 21:14:09 +0000 - Checking out blendOS - https://engl.askiiart.net/blog/blendos.html + Benchmarking and comparing DwarFS + https://engl.askiiart.net/blog/benchmarking-dwarfs.html Building blendOS (and its packages) @@ -18,6 +18,14 @@ OCI Images as a "Filesystem": Vanilla OS https://engl.askiiart.net/blog/vanilla-os.html + + Checking out blendOS + https://engl.askiiart.net/blog/blendos.html + + + Using `clap` + https://engl.askiiart.net/blog/using-clap.html + Glossary https://engl.askiiart.net/glossary.html diff --git a/glossary.html b/glossary.html index 25390ae..d9f804e 100644 --- a/glossary.html +++ b/glossary.html @@ -98,6 +98,8 @@ using FUSE). On Linux, device drivers are usually in the kernel directly, rather than being installed separately like on Windows. +
  • Shell: The program which is the command-line + interface.
  • diff --git a/glossary.md b/glossary.md index ff33e4f..749462d 100644 --- a/glossary.md +++ b/glossary.md @@ -30,4 +30,5 @@ - `PKGBUILD`: A file defining how to build a package which can be install by `pacman`. - `iso` file: A disk image file, can be "burned" to a USB flash drive (or any other disk) and booted off of, often used for Linux installers and/or live images. - FUSE: A filesystem interface used for running filesystems in userspace (i.e. not in the kernel) -- Kernel: The very core of an operating system, with all its most essential functions, like filesystems (aside from those using FUSE). On Linux, device drivers are usually in the kernel directly, rather than being installed separately like on Windows. \ No newline at end of file +- Kernel: The very core of an operating system, with all its most essential functions, like filesystems (aside from those using FUSE). On Linux, device drivers are usually in the kernel directly, rather than being installed separately like on Windows. +- Shell: The program which *is* the command-line interface. diff --git a/sitemap.xml b/sitemap.xml index f782624..9366855 100644 --- a/sitemap.xml +++ b/sitemap.xml @@ -1,7 +1,9 @@ +https://engl.askiiart.net/blog/using-clap.html https://engl.askiiart.net/blog/blendos.html https://engl.askiiart.net/blog/building-blendos.html https://engl.askiiart.net/blog/vanilla-os.html +https://engl.askiiart.net/blog/benchmarking-dwarfs.html https://engl.askiiart.net/glossary.html https://engl.askiiart.net/index.html https://engl.askiiart.net/about.html diff --git a/style.css b/style.css index 535171c..53d9b9b 100644 --- a/style.css +++ b/style.css @@ -34,8 +34,7 @@ body { } li { - font-family: 'Atkinson Hyperlegible'; -} + font: 18px/1.35 'Atkinson Hyperlegible', sans-serif;} p, footer {