Add BEP support table to readme

Also adds `bin/bin/generate-bep-table.rs`, which generates and updates
the table from a collection of BEPs.

type: documentation
This commit is contained in:
Casey Rodarmor 2020-01-16 20:35:23 -08:00
parent d1f8f24d8e
commit 66d44155f0
No known key found for this signature in database
GPG Key ID: 556186B153EC6FE0
5 changed files with 300 additions and 9 deletions

21
Cargo.lock generated
View File

@ -79,7 +79,7 @@ dependencies = [
"atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
"humantime 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"termcolor 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -93,6 +93,11 @@ dependencies = [
"wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "glob"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "heck"
version = "0.3.1"
@ -134,9 +139,10 @@ dependencies = [
"ansi_term 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
"atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
"md5 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_bencode 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_bytes 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)",
@ -281,13 +287,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "regex"
version = "1.3.1"
version = "1.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
"thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"thread_local 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -475,7 +481,7 @@ dependencies = [
[[package]]
name = "thread_local"
version = "0.3.6"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -581,6 +587,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum doc-comment 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "923dea538cea0aa3025e8685b20d6ee21ef99c4f77e954a30febbaac5ec73a97"
"checksum env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36"
"checksum getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb"
"checksum glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
"checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205"
"checksum hermit-abi 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "eff2656d88f158ce120947499e971d743c05dbcbed62e5bd2f38f1698bbc3772"
"checksum humantime 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f"
@ -603,7 +610,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
"checksum rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
"checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84"
"checksum regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dc220bd33bdce8f093101afe22a037b8eb0e5af33592e6a9caafff0d4cb81cbd"
"checksum regex 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b5508c1941e4e7cb19965abef075d35a9a8b5cdf0846f30b4050e9b55dc55e87"
"checksum regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "11a7e20d1cce64ef2fed88b66d347f88bd9babb82845b2b858f3edbf59a4f716"
"checksum remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e"
"checksum rustversion 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3a0538bd897e17257b0128d2fd95c2ed6df939374073a36166051a79e2eb7986"
@ -626,7 +633,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9"
"checksum termcolor 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb6bfa289a4d7c5766392812c0a1f4c1ba45afa1ad47803c11e1f407d846d75f"
"checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b"
"checksum thread_local 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14"
"checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5"
"checksum unicode-normalization 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b561e267b2326bb4cebfc0ef9e68355c7abe6c6f522aeac2f5bf95d56c59bdcf"
"checksum unicode-segmentation 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0"

View File

@ -10,6 +10,7 @@ categories = ["command-line-utilities"]
homepage = "https://github.com/casey/intermodal"
repository = "https://github.com/casey/intermodal"
edition = "2018"
default-run = "imdl"
[dependencies]
ansi_term = "0.12"
@ -31,3 +32,14 @@ walkdir = "2"
[dependencies.serde]
version = "1"
features = ["derive"]
[dev-dependencies]
glob = "0.3.0"
regex = "1.3.3"
# generates the table of supported BEPs in README.md
# not an example, but included as an example and not
# a binary because examples can use dev dependencies
[[example]]
name = "generate-bep-table"
path = "bin/generate-bep-table.rs"

View File

@ -1,6 +1,76 @@
# intermodal: a 40' shipping container for the Internet
## Colored Output
## Bittorrent
### BEP Support
| Symbol | Meaning |
|--------------------|----------------|
| :white_check_mark: | Supported |
| :x: | Unsupported |
| :heavy_minus_sign: | Not Applicable |
| BEP | Status | Title |
|:----------------------------------------------:|:------------------:|:-----------------------------------------------------------------|
| [00](http://bittorrent.org/beps/bep_0000.html) | :heavy_minus_sign: | Index of BitTorrent Enhancement Proposals |
| [01](http://bittorrent.org/beps/bep_0001.html) | :heavy_minus_sign: | The BitTorrent Enhancement Proposal Process |
| [02](http://bittorrent.org/beps/bep_0002.html) | :heavy_minus_sign: | Sample reStructured Text BEP Template |
| [03](http://bittorrent.org/beps/bep_0003.html) | :x: | The BitTorrent Protocol Specification |
| [04](http://bittorrent.org/beps/bep_0004.html) | :heavy_minus_sign: | Assigned Numbers |
| [05](http://bittorrent.org/beps/bep_0005.html) | :x: | DHT Protocol |
| [06](http://bittorrent.org/beps/bep_0006.html) | :heavy_minus_sign: | Fast Extension |
| [07](http://bittorrent.org/beps/bep_0007.html) | :heavy_minus_sign: | IPv6 Tracker Extension |
| [08](http://bittorrent.org/beps/bep_0008.html) | :heavy_minus_sign: | Tracker Peer Obfuscation |
| [09](http://bittorrent.org/beps/bep_0009.html) | :x: | Extension for Peers to Send Metadata Files |
| [10](http://bittorrent.org/beps/bep_0010.html) | :heavy_minus_sign: | Extension Protocol |
| [11](http://bittorrent.org/beps/bep_0011.html) | :heavy_minus_sign: | Peer Exchange (PEX) |
| [12](http://bittorrent.org/beps/bep_0012.html) | :white_check_mark: | Multitracker Metadata Extension |
| [14](http://bittorrent.org/beps/bep_0014.html) | :heavy_minus_sign: | Local Service Discovery |
| [15](http://bittorrent.org/beps/bep_0015.html) | :heavy_minus_sign: | UDP Tracker Protocol for BitTorrent |
| [16](http://bittorrent.org/beps/bep_0016.html) | :heavy_minus_sign: | Superseeding |
| [17](http://bittorrent.org/beps/bep_0017.html) | :x: | HTTP Seeding |
| [18](http://bittorrent.org/beps/bep_0018.html) | :heavy_minus_sign: | Search Engine Specificiation |
| [19](http://bittorrent.org/beps/bep_0019.html) | :x: | WebSeed - HTTP/FTP Seeding (GetRight style) |
| [20](http://bittorrent.org/beps/bep_0020.html) | :heavy_minus_sign: | Peer ID Conventions |
| [21](http://bittorrent.org/beps/bep_0021.html) | :heavy_minus_sign: | Extension for partial seeds |
| [22](http://bittorrent.org/beps/bep_0022.html) | :heavy_minus_sign: | BitTorrent Local Tracker Discovery Protocol |
| [23](http://bittorrent.org/beps/bep_0023.html) | :heavy_minus_sign: | Tracker Returns Compact Peer Lists |
| [24](http://bittorrent.org/beps/bep_0024.html) | :heavy_minus_sign: | Tracker Returns External IP |
| [25](http://bittorrent.org/beps/bep_0025.html) | :heavy_minus_sign: | An Alternate BitTorrent Cache Discovery Protocol |
| [26](http://bittorrent.org/beps/bep_0026.html) | :heavy_minus_sign: | Zeroconf Peer Advertising and Discovery |
| [27](http://bittorrent.org/beps/bep_0027.html) | :white_check_mark: | Private Torrents |
| [28](http://bittorrent.org/beps/bep_0028.html) | :heavy_minus_sign: | Tracker exchange extension |
| [29](http://bittorrent.org/beps/bep_0029.html) | :heavy_minus_sign: | uTorrent transport protocol |
| [30](http://bittorrent.org/beps/bep_0030.html) | :x: | Merkle hash torrent extension |
| [31](http://bittorrent.org/beps/bep_0031.html) | :heavy_minus_sign: | Failure Retry Extension |
| [32](http://bittorrent.org/beps/bep_0032.html) | :heavy_minus_sign: | BitTorrent DHT Extensions for IPv6 |
| [33](http://bittorrent.org/beps/bep_0033.html) | :heavy_minus_sign: | DHT Scrapes |
| [34](http://bittorrent.org/beps/bep_0034.html) | :x: | DNS Tracker Preferences |
| [35](http://bittorrent.org/beps/bep_0035.html) | :x: | Torrent Signing |
| [36](http://bittorrent.org/beps/bep_0036.html) | :x: | Torrent RSS feeds |
| [37](http://bittorrent.org/beps/bep_0037.html) | :heavy_minus_sign: | Anonymous BitTorrent over proxies |
| [38](http://bittorrent.org/beps/bep_0038.html) | :x: | Finding Local Data Via Torrent File Hints |
| [39](http://bittorrent.org/beps/bep_0039.html) | :x: | Updating Torrents Via Feed URL |
| [40](http://bittorrent.org/beps/bep_0040.html) | :heavy_minus_sign: | Canonical Peer Priority |
| [41](http://bittorrent.org/beps/bep_0041.html) | :x: | UDP Tracker Protocol Extensions |
| [42](http://bittorrent.org/beps/bep_0042.html) | :heavy_minus_sign: | DHT Security extension |
| [43](http://bittorrent.org/beps/bep_0043.html) | :heavy_minus_sign: | Read-only DHT Nodes |
| [44](http://bittorrent.org/beps/bep_0044.html) | :x: | Storing arbitrary data in the DHT |
| [45](http://bittorrent.org/beps/bep_0045.html) | :x: | Multiple-address operation for the BitTorrent DHT |
| [46](http://bittorrent.org/beps/bep_0046.html) | :x: | Updating Torrents Via DHT Mutable Items |
| [47](http://bittorrent.org/beps/bep_0047.html) | :x: | Padding files and extended file attributes |
| [48](http://bittorrent.org/beps/bep_0048.html) | :x: | Tracker Protocol Extension: Scrape |
| [49](http://bittorrent.org/beps/bep_0049.html) | :x: | Distributed Torrent Feeds |
| [50](http://bittorrent.org/beps/bep_0050.html) | :heavy_minus_sign: | Publish/Subscribe Protocol |
| [51](http://bittorrent.org/beps/bep_0051.html) | :heavy_minus_sign: | DHT Infohash Indexing |
| [52](http://bittorrent.org/beps/bep_0052.html) | :x: | The BitTorrent Protocol Specification v2 |
| [53](http://bittorrent.org/beps/bep_0053.html) | :x: | Magnet URI extension - Select specific file indices for download |
| [54](http://bittorrent.org/beps/bep_0054.html) | :heavy_minus_sign: | The lt_donthave extension |
| [55](http://bittorrent.org/beps/bep_0055.html) | :heavy_minus_sign: | Holepunch extension |
## General Functionality
### Colored Output
Intermodal features colored help, error, and informational output. Colored
output is disabled if Intermodal detects that it is not printing to a TTY.

190
bin/generate-bep-table.rs Normal file
View File

@ -0,0 +1,190 @@
use std::{
error::Error,
fmt::{self, Display, Formatter},
fs,
str::FromStr,
};
use glob::glob;
use regex::Regex;
const README: &str = "README.md";
struct Bep {
number: usize,
title: String,
status: Status,
}
enum Status {
Unknown,
NotApplicable,
Supported,
NotSupported,
}
impl FromStr for Status {
type Err = String;
fn from_str(text: &str) -> Result<Self, Self::Err> {
match text {
"x" => Ok(Self::NotSupported),
"+" => Ok(Self::Supported),
"-" => Ok(Self::NotApplicable),
"?" => Ok(Self::Unknown),
":x:" => Ok(Self::NotSupported),
":white_check_mark:" => Ok(Self::Supported),
":heavy_minus_sign:" => Ok(Self::NotApplicable),
":grey_question:" => Ok(Self::Unknown),
_ => Err(format!("invalid status: {}", text)),
}
}
}
impl Display for Status {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
match self {
Self::Unknown => write!(f, ":grey_question:"),
Self::NotApplicable => write!(f, ":heavy_minus_sign:"),
Self::Supported => write!(f, ":white_check_mark:"),
Self::NotSupported => write!(f, ":x:"),
}
}
}
fn main() -> Result<(), Box<dyn Error>> {
let title_re = Regex::new("(?m)^:Title: (?P<title>.*)$")?;
let mut beps = Vec::new();
for result in glob("tmp/bittorrent.org/beps/bep_*.rst")? {
let path = result?;
let number = path
.file_stem()
.unwrap()
.to_string_lossy()
.split('_')
.nth(1)
.unwrap()
.parse::<usize>()?;
if number == 1000 {
continue;
}
let rst = fs::read_to_string(path)?;
let title = title_re
.captures(&rst)
.unwrap()
.name("title")
.unwrap()
.as_str()
.trim()
.to_owned();
beps.push(Bep {
status: Status::Unknown,
number,
title,
});
}
beps.sort_by_key(|bep| bep.number);
let table_re = Regex::new(
r"(?mx)
^[|]\ BEP.*
(
\n
[|]
.*
)*
",
)?;
let readme = fs::read_to_string(README)?;
let parts = table_re.split(&readme).into_iter().collect::<Vec<&str>>();
assert_eq!(parts.len(), 2);
let before = parts[0];
let after = parts[1];
let original = table_re
.captures(&readme)
.unwrap()
.get(0)
.unwrap()
.as_str()
.trim();
let row_re = Regex::new(
r"(?x)
^
\|
\s*
\[
(?P<number>[0-9]+)
\]
.*
\s*
\|
(?P<status>.*)
\|
(?P<title>.*)
\|
$
",
)?;
let mut originals = Vec::new();
for row in original.lines().skip(2) {
let captures = row_re.captures(row).unwrap();
originals.push(Bep {
number: captures.name("number").unwrap().as_str().parse()?,
status: captures.name("status").unwrap().as_str().trim().parse()?,
title: captures.name("title").unwrap().as_str().to_owned(),
});
}
assert_eq!(originals.len(), beps.len());
let mut lines = Vec::new();
let width = beps.iter().map(|bep| bep.title.len()).max().unwrap_or(0);
lines.push(format!(
"| BEP | Status | {:width$} |",
"Title",
width = width
));
lines.push(format!(
"|:----------------------------------------------:|:------------------:|:{:-<width$}-|",
"",
width = width
));
for (bep, original) in beps.into_iter().zip(originals) {
assert_eq!(bep.number, original.number);
lines.push(format!(
"| [{:02}](http://bittorrent.org/beps/bep_{:04}.html) | {:18} | {:width$} |",
bep.number,
bep.number,
original.status.to_string(),
bep.title,
width = width
));
}
let table = lines.join("\n");
let readme = &[before.trim(), "", &table, "", after.trim(), ""].join("\n");
fs::write(README, readme)?;
Ok(())
}

View File

@ -20,13 +20,25 @@ done BRANCH:
test:
cargo test
# lint code
lint:
cargo clippy
preview-readme:
grip -b README.md
dev-deps:
brew install grip
generate-bep-table:
cargo run --example generate-bep-table
# retrieve large collection of torrents from the Internet Archive
get-torrents:
aria2c \
-d dat \
-x 10 \
'https://ia802701.us.archive.org/21/items/2014_torrent_archive_organized/torrent_archive_organized.zip'
# download bittorrent.org repository
get-beps:
git clone git@github.com:bittorrent/bittorrent.org.git tmp/bittorrent.org