Skip to content

Commit

Permalink
Split features.toml into many small files
Browse files Browse the repository at this point in the history
  • Loading branch information
jplatte committed Mar 21, 2020
1 parent 7755f68 commit a407f82
Show file tree
Hide file tree
Showing 321 changed files with 1,852 additions and 1,973 deletions.
119 changes: 98 additions & 21 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,23 @@ use std::{
env,
fmt::Debug,
fs::{self, File},
io::{self, BufWriter, Write},
io::{self, BufRead, BufReader, BufWriter, Write},
path::Path,
};

use anyhow::Context as _;
use anyhow::{bail, Context as _};
use proc_macro2::{Ident, Span, TokenStream};
use quote::{quote, ToTokens};
use serde::{Deserialize, Serialize};
use tera::{Context, Tera};

#[derive(Clone, Debug, Deserialize, Serialize)]
struct FeatureToml {
#[derive(Serialize)]
struct Data {
versions: Vec<FeatureList>,
unstable: FeatureList,
}

#[derive(Clone, Debug, Deserialize, Serialize)]
#[derive(Deserialize, Serialize)]
struct VersionData {
/// Rust version number, e.g. "1.0.0"
number: String,
Expand All @@ -33,19 +33,17 @@ struct VersionData {
gh_milestone_id: Option<u64>,
}

#[derive(Clone, Debug, Deserialize, Serialize)]
#[derive(Serialize)]
struct FeatureList {
#[serde(flatten)]
version: Option<VersionData>,
/// List of features (to be) stabilized in this release
#[serde(default)]
features: Vec<FeatureData>,
}

/// A "feature", as tracked by this app. Can be a nightly Rust feature, a
/// stabilized API, or anything else that one version of Rust (deliberately)
/// supports while a previous one didn't support it.
#[derive(Clone, Debug, Deserialize, Serialize)]
#[derive(Deserialize, Serialize)]
struct FeatureData {
/// Short description to identify the feature
title: String,
Expand All @@ -54,7 +52,8 @@ struct FeatureData {
flag: Option<String>,
/// Feature slug, used for the permalink. If a feature flag exists, this
/// can be omitted, then the flag is used for the permalink.
slug: Option<String>,
#[serde(skip_deserializing)] // filled from filename or flag
slug: String,
/// RFC id (https://github.com/rust-lang/rfcs/pull/{id})
rfc_id: Option<u64>,
/// Implementation PR id (https://github.com/rust-lang/rust/pull/{id})
Expand Down Expand Up @@ -95,13 +94,11 @@ impl Default for Channel {
}

fn main() -> anyhow::Result<()> {
println!("cargo:rerun-if-changed=features.toml");
println!("cargo:rerun-if-changed=templates/index.html");
println!("cargo:rerun-if-changed=templates/nightly.html");
println!("cargo:rerun-if-changed=templates/skel.html");

let features_raw = fs::read("features.toml")?;
let feature_toml: FeatureToml = toml::from_slice(&features_raw)?;
let data = collect_data()?;

// TODO: Add a filter that replaces `` by <code></code>
let tera = Tera::new("templates/*").context("loading templates")?;
Expand All @@ -111,7 +108,7 @@ fn main() -> anyhow::Result<()> {
.or_else(|e| if e.kind() == io::ErrorKind::AlreadyExists { Ok(()) } else { Err(e) })
.context("creating dir public")?;

let ctx = Context::from_serialize(&feature_toml)?;
let ctx = Context::from_serialize(&data)?;
fs::write(
"public/index.html",
tera.render("index.html", &ctx).context("rendering index.html")?,
Expand All @@ -127,12 +124,96 @@ fn main() -> anyhow::Result<()> {
let out_path = Path::new(&out_dir).join("features.rs");
let mut out = BufWriter::new(File::create(out_path).context("creating $OUT_DIR/features.rs")?);

write!(out, "{}", generate_data(feature_toml)).context("writing features.rs")?;
write!(out, "{}", generate_output(data)).context("writing features.rs")?;

Ok(())
}

fn generate_data(feature_toml: FeatureToml) -> TokenStream {
fn collect_data() -> anyhow::Result<Data> {
let mut data = Data {
versions: Vec::new(),
unstable: FeatureList { version: None, features: Vec::new() },
};

for entry in fs::read_dir("data").context("opening data/")? {
let dir = entry?;
assert!(dir.file_type()?.is_dir(), "expected only directories in data/");

let dir_name = dir.file_name().into_string().unwrap();
println!("cargo:rerun-if-changed=data/{}", dir_name);

let features = match dir_name.as_str() {
"unstable" => &mut data.unstable.features,
_ => {
let version_data_raw = fs::read(dir.path().join("version.toml"))?;
let version_data = toml::from_slice(&version_data_raw)?;
data.versions
.push(FeatureList { version: Some(version_data), features: Vec::new() });
&mut data.versions.last_mut().unwrap().features
}
};

for entry in
fs::read_dir(dir.path()).with_context(|| format!("opening data/{}", dir_name))?
{
let file = entry?;
let file_name = file.file_name().into_string().unwrap();
println!("cargo:rerun-if-changed=data/{}/{}", dir_name, file_name);

if file_name == "version.toml" {
continue;
}

assert!(
file_name.ends_with(".md"),
"expected only .md files and version.toml in data/*"
);
let feature_file = BufReader::new(
File::open(file.path())
.with_context(|| format!("opening data/{}/{}", dir_name, file_name))?,
);

let mut feature_file_lines = feature_file.lines();
let mut feature_file_frontmatter = String::new();
assert_eq!(
match feature_file_lines.next() {
Some(Ok(s)) => s,
_ => bail!("reading first line of data/{}/{} failed", dir_name, file_name),
},
"+++",
"expected frontmatter at the beginning of data/{}/{}",
dir_name,
file_name
);

loop {
match feature_file_lines.next() {
Some(Ok(s)) if s == "+++" => break,
Some(Ok(s)) => {
feature_file_frontmatter += s.as_str();
feature_file_frontmatter.push('\n');
}
_ => bail!("reading frontmatter of data/{}/{} failed", dir_name, file_name),
}
}

// TODO: Read file contents after frontmatter

let mut feature: FeatureData =
toml::from_str(&feature_file_frontmatter).with_context(|| {
format!("deserializing frontmatter of data/{}/{}", dir_name, file_name)
})?;

// [ file_name without '.md' ]
feature.slug = file_name[..file_name.len() - 3].to_owned();
features.push(feature);
}
}

Ok(data)
}

fn generate_output(feature_toml: Data) -> TokenStream {
let mut monogram_index = BTreeMap::new();
let mut bigram_index = BTreeMap::new();
let mut trigram_index = BTreeMap::new();
Expand Down Expand Up @@ -173,11 +254,7 @@ fn generate_data(feature_toml: FeatureToml) -> TokenStream {

let title = &f.title;
let flag = option_literal(&f.flag);
let slug = f
.slug
.as_ref()
.or_else(|| f.flag.as_ref())
.unwrap_or_else(|| panic!("feature '{}' needs a feature flag or slug", title));
let slug = f.slug;
let rfc_id = option_literal(&f.rfc_id);
let impl_pr_id = option_literal(&f.impl_pr_id);
let tracking_issue_id = option_literal(&f.tracking_issue_id);
Expand Down
4 changes: 4 additions & 0 deletions data/1.0/associated_types.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
+++
title = "associated types in traits"
flag = "associated_types"
+++
4 changes: 4 additions & 0 deletions data/1.0/default_type_params.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
+++
title = "type parameter defaults"
flag = "default_type_params"
+++
4 changes: 4 additions & 0 deletions data/1.0/if_let.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
+++
title = "`if let` expressions"
flag = "if_let"
+++
4 changes: 4 additions & 0 deletions data/1.0/macro_rules.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
+++
title = "`macro_rules!`"
flag = "macro_rules"
+++
4 changes: 4 additions & 0 deletions data/1.0/slicing_syntax.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
+++
title = "`&foo[a..b]` as slicing syntax"
flag = "slicing_syntax"
+++
4 changes: 4 additions & 0 deletions data/1.0/struct_variant.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
+++
title = "struct variants in enums"
flag = "struct_variant"
+++
4 changes: 4 additions & 0 deletions data/1.0/tuple_indexing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
+++
title = "tuple indexing"
flag = "tuple_indexing"
+++
3 changes: 3 additions & 0 deletions data/1.0/version.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
number = "1.0"
gh_milestone_id = 20
blog_post_path = "2015/05/15/Rust-1.0.html"
4 changes: 4 additions & 0 deletions data/1.0/while_let.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
+++
title = "`while let` expressions"
flag = "while_let"
+++
2 changes: 2 additions & 0 deletions data/1.1/version.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
number = "1.1"
blog_post_path = "2015/06/25/Rust-1.1.html"
2 changes: 2 additions & 0 deletions data/1.10/version.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
number = "1.10"
blog_post_path = "2016/07/07/Rust-1.10.html"
2 changes: 2 additions & 0 deletions data/1.11/version.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
number = "1.11"
blog_post_path = "2016/08/18/Rust-1.11.html"
2 changes: 2 additions & 0 deletions data/1.12/version.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
number = "1.12"
blog_post_path = "2016/09/29/Rust-1.12.html"
6 changes: 6 additions & 0 deletions data/1.13/assert_ne.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
+++
title = "`assert_ne!`"
rfc_id = 1653
impl_pr_id = 35074
tracking_issue_id = 35073
+++
6 changes: 6 additions & 0 deletions data/1.13/debug_assert_ne.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
+++
title = "`debug_assert_ne!`"
rfc_id = 1653
impl_pr_id = 35074
tracking_issue_id = 35073
+++
9 changes: 9 additions & 0 deletions data/1.13/question_mark.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
+++
title = "the `?` operator"
flag = "question_mark"
rfc_id = 243
impl_pr_id = 31954
tracking_issue_id = 31436
stabilization_pr_id = 36995
edition_guide_path = "rust-2018/error-handling-and-panics/the-question-mark-operator-for-easier-error-handling.html"
+++
5 changes: 5 additions & 0 deletions data/1.13/type_macros.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
+++
title = "`macro_rules!` macros in type position"
flag = "type_macros"
tracking_issue_id = 27245
+++
2 changes: 2 additions & 0 deletions data/1.13/version.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
number = "1.13"
blog_post_path = "2016/11/10/Rust-1.13.html"
7 changes: 7 additions & 0 deletions data/1.14/dotdot_in_tuple_patterns.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
+++
title = "`..` in tuple (struct) patterns"
flag = "dotdot_in_tuple_patterns"
rfc_id = 1492
tracking_issue_id = 33627
stabilization_pr_id = 36843
+++
4 changes: 4 additions & 0 deletions data/1.14/fn_ptr_to_unsafe_fn_ptr.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
+++
title = "`fn` pointer to `unsafe fn` pointer coercion"
impl_pr_id = 37389
+++
4 changes: 4 additions & 0 deletions data/1.14/println_no_args.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
+++
title = "`println!` without arguments"
impl_pr_id = 36825
+++
2 changes: 2 additions & 0 deletions data/1.14/version.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
number = "1.14"
blog_post_path = "2016/12/22/Rust-1.14.html"
6 changes: 6 additions & 0 deletions data/1.15/proc_macro_derive.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
+++
title = "procedural derive macros (macros 1.1)"
flag = "proc_macro"
rfc_id = 1681
tracking_issue_id = 35900
+++
2 changes: 2 additions & 0 deletions data/1.15/version.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
number = "1.15"
blog_post_path = "2017/02/02/Rust-1.15.html"
5 changes: 5 additions & 0 deletions data/1.16/assoc_ty_struct_expr_pat.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
+++
title = "associated types in struct expressions and patterns"
tracking_issue_id = 37544
stabilization_pr_id = 39282
+++
5 changes: 5 additions & 0 deletions data/1.16/self_struct_expr_pat.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
+++
title = "`Self` in struct expressions and patterns"
tracking_issue_id = 37544
stabilization_pr_id = 39282
+++
3 changes: 3 additions & 0 deletions data/1.16/version.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
number = "1.16"
gh_milestone_id = 33
blog_post_path = "2017/03/16/Rust-1.16.html"
4 changes: 4 additions & 0 deletions data/1.16/writeln_no_args.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
+++
title = "`writeln!` without arguments"
impl_pr_id = 38469
+++
6 changes: 6 additions & 0 deletions data/1.17/cell_non_copy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
+++
title = "`Cell` with non-`Copy` types"
flag = "cell_non_copy"
rfc_id = 1651
impl_pr_id = 39793
+++
8 changes: 8 additions & 0 deletions data/1.17/field_init_shorthand.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
+++
title = "field init shorthands (`x` for `x: x` in struct initializers)"
flag = "field_init_shorthand"
rfc_id = 1682
tracking_issue_id = 37340
stabilization_pr_id = 39761
edition_guide_path = "rust-2018/data-types/field-init-shorthand.html"
+++
8 changes: 8 additions & 0 deletions data/1.17/static_in_const.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
+++
title = "elision of `'static` lifetimes in `static`s and `const`s"
flag = "static_in_const"
rfc_id = 1623
tracking_issue_id = 35897
stabilization_pr_id = 39265
edition_guide_path = "rust-2018/ownership-and-lifetimes/simpler-lifetimes-in-static-and-const.html"
+++
6 changes: 6 additions & 0 deletions data/1.17/static_recursion.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
+++
title = "recursive static items"
flag = "static_recursion"
tracking_issue_id = 29719
stabilization_pr_id = 40027
+++
3 changes: 3 additions & 0 deletions data/1.17/version.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
number = "1.17"
gh_milestone_id = 34
blog_post_path = "2017/04/27/Rust-1.17.html"
5 changes: 5 additions & 0 deletions data/1.17/where_clauses_with_self.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
+++
title = "`Self` in the where clause of trait impl's"
rfc_id = 1647
tracking_issue_id = 38864
+++
13 changes: 13 additions & 0 deletions data/1.18/pub_restricted.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
+++
title = "`pub(restricted)` visibilities"
flag = "pub_restricted"
rfc_id = 1422
tracking_issue_id = 32409
stabilization_pr_id = 40556
edition_guide_path = "rust-2018/module-system/more-visibility-modifiers.html"
items = [
"pub(crate)",
"pub(super)",
"pub(in m)",
]
+++
3 changes: 3 additions & 0 deletions data/1.18/version.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
number = "1.18"
gh_milestone_id = 35
blog_post_path = "2017/06/08/Rust-1.18.html"
Loading

0 comments on commit a407f82

Please sign in to comment.