mirror of
https://github.com/Noratrieb/target-tier-docs-experiment.git
synced 2026-01-14 16:35:09 +01:00
start with tables
This commit is contained in:
parent
f6cef8ab1f
commit
f4493e17b2
3 changed files with 127 additions and 18 deletions
74
src/main.rs
74
src/main.rs
|
|
@ -17,6 +17,15 @@ struct TargetDocs {
|
|||
maintainers: Vec<String>,
|
||||
sections: Vec<(String, String)>,
|
||||
tier: String,
|
||||
// TODO: Make this mandatory.
|
||||
metadata: Option<TargetMetadata>,
|
||||
}
|
||||
|
||||
/// Metadata for the table
|
||||
struct TargetMetadata {
|
||||
notes: String,
|
||||
std: String,
|
||||
host: String,
|
||||
}
|
||||
|
||||
const SECTIONS: &[&str] = &[
|
||||
|
|
@ -57,7 +66,14 @@ fn main() -> Result<()> {
|
|||
let mut info_patterns = parse::load_target_infos(Path::new(input_dir))
|
||||
.unwrap()
|
||||
.into_iter()
|
||||
.map(|info| TargetPatternEntry { info, used: false })
|
||||
.map(|info| {
|
||||
let metadata_used = vec![false; info.metadata.len()];
|
||||
TargetPatternEntry {
|
||||
info,
|
||||
used: false,
|
||||
metadata_used,
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
eprintln!("Collecting rustc information");
|
||||
|
|
@ -66,16 +82,21 @@ fn main() -> Result<()> {
|
|||
.map(|target| rustc_target_info(&rustc, target))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let targets = targets
|
||||
.into_iter()
|
||||
.map(|target| target_doc_info(&mut info_patterns, target))
|
||||
.zip(rustc_infos)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
eprintln!("Rendering targets");
|
||||
for (target, rustc_info) in std::iter::zip(&targets, rustc_infos) {
|
||||
let info = target_info(&mut info_patterns, target);
|
||||
let doc = render::render_target_md(&info, &rustc_info);
|
||||
for (info, rustc_info) in &targets {
|
||||
let doc = render::render_target_md(info, rustc_info);
|
||||
|
||||
std::fs::write(
|
||||
Path::new(output_src)
|
||||
.join("platform-support")
|
||||
.join("targets")
|
||||
.join(format!("{target}.md")),
|
||||
.join(format!("{}.md", info.name)),
|
||||
doc,
|
||||
)
|
||||
.wrap_err("writing target file")?;
|
||||
|
|
@ -88,9 +109,21 @@ fn main() -> Result<()> {
|
|||
target_pattern.info.pattern
|
||||
);
|
||||
}
|
||||
|
||||
for (used, meta) in
|
||||
std::iter::zip(target_pattern.metadata_used, target_pattern.info.metadata)
|
||||
{
|
||||
if !used {
|
||||
bail!(
|
||||
"in target pattern `{}`, the metadata pattern `{}` was never used",
|
||||
target_pattern.info.pattern,
|
||||
meta.pattern
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
render::render_static(&Path::new(output_src).join("platform-support"), &targets)?;
|
||||
render::render_static(Path::new(output_src), &targets)?;
|
||||
|
||||
eprintln!("Finished generating target docs");
|
||||
Ok(())
|
||||
|
|
@ -99,18 +132,20 @@ fn main() -> Result<()> {
|
|||
struct TargetPatternEntry {
|
||||
info: ParsedTargetInfoFile,
|
||||
used: bool,
|
||||
metadata_used: Vec<bool>,
|
||||
}
|
||||
|
||||
/// Gets the target information from `target_info.toml` by applying all patterns that match.
|
||||
fn target_info(info_patterns: &mut [TargetPatternEntry], target: &str) -> TargetDocs {
|
||||
fn target_doc_info(info_patterns: &mut [TargetPatternEntry], target: &str) -> TargetDocs {
|
||||
let mut tier = None;
|
||||
let mut maintainers = Vec::new();
|
||||
let mut sections = Vec::new();
|
||||
|
||||
for target_pattern in info_patterns {
|
||||
if glob_match::glob_match(&target_pattern.info.pattern, target) {
|
||||
target_pattern.used = true;
|
||||
let target_pattern = &target_pattern.info;
|
||||
let mut metadata = None;
|
||||
|
||||
for target_pattern_entry in info_patterns {
|
||||
if glob_match::glob_match(&target_pattern_entry.info.pattern, target) {
|
||||
target_pattern_entry.used = true;
|
||||
let target_pattern = &target_pattern_entry.info;
|
||||
|
||||
maintainers.extend_from_slice(&target_pattern.maintainers);
|
||||
|
||||
|
|
@ -127,6 +162,20 @@ fn target_info(info_patterns: &mut [TargetPatternEntry], target: &str) -> Target
|
|||
}
|
||||
sections.push((section_name.clone(), content.clone()));
|
||||
}
|
||||
|
||||
for (i, metadata_pattern) in target_pattern.metadata.iter().enumerate() {
|
||||
if glob_match::glob_match(&metadata_pattern.pattern, target) {
|
||||
target_pattern_entry.metadata_used[i] = true;
|
||||
if metadata.is_some() {
|
||||
panic!("target {target} is assigned metadata from more than one pattern");
|
||||
}
|
||||
metadata = Some(TargetMetadata {
|
||||
notes: metadata_pattern.notes.clone(),
|
||||
host: metadata_pattern.host.clone(),
|
||||
std: metadata_pattern.std.clone(),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -136,6 +185,7 @@ fn target_info(info_patterns: &mut [TargetPatternEntry], target: &str) -> Target
|
|||
// tier: tier.expect(&format!("no tier found for target {target}")),
|
||||
tier: tier.unwrap_or("UNKNOWN".to_owned()),
|
||||
sections,
|
||||
metadata,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
16
src/parse.rs
16
src/parse.rs
|
|
@ -3,19 +3,32 @@
|
|||
use eyre::{bail, OptionExt, Result, WrapErr};
|
||||
use std::{fs::DirEntry, path::Path};
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
#[derive(Debug)]
|
||||
pub struct ParsedTargetInfoFile {
|
||||
pub pattern: String,
|
||||
pub tier: Option<String>,
|
||||
pub maintainers: Vec<String>,
|
||||
pub sections: Vec<(String, String)>,
|
||||
pub metadata: Vec<ParsedTargetMetadata>,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
struct Frontmatter {
|
||||
tier: Option<String>,
|
||||
#[serde(default)]
|
||||
maintainers: Vec<String>,
|
||||
#[serde(default)]
|
||||
metadata: Vec<ParsedTargetMetadata>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, serde::Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct ParsedTargetMetadata {
|
||||
pub pattern: String,
|
||||
pub notes: String,
|
||||
pub std: String,
|
||||
pub host: String,
|
||||
}
|
||||
|
||||
pub fn load_target_infos(directory: &Path) -> Result<Vec<ParsedTargetInfoFile>> {
|
||||
|
|
@ -93,6 +106,7 @@ fn parse_file(name: &str, content: &str) -> Result<ParsedTargetInfoFile> {
|
|||
maintainers: frontmatter.maintainers,
|
||||
tier: frontmatter.tier,
|
||||
sections,
|
||||
metadata: frontmatter.metadata,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use eyre::{Context, OptionExt, Result};
|
||||
use eyre::{bail, Context, OptionExt, Result};
|
||||
use std::{fs, path::Path};
|
||||
|
||||
use crate::{is_in_rust_lang_rust, RustcTargetInfo, TargetDocs};
|
||||
|
|
@ -91,13 +91,13 @@ fn replace_section(prev_content: &str, section_name: &str, replacement: &str) ->
|
|||
}
|
||||
|
||||
/// Renders the non-target files like `SUMMARY.md` that depend on the target.
|
||||
pub fn render_static(platform_support: &Path, targets: &[&str]) -> Result<()> {
|
||||
let targets_file = platform_support.join("targets.md");
|
||||
pub fn render_static(src_output: &Path, targets: &[(TargetDocs, RustcTargetInfo)]) -> Result<()> {
|
||||
let targets_file = src_output.join("platform-support").join("targets.md");
|
||||
let old_targets = fs::read_to_string(&targets_file).wrap_err("reading summary file")?;
|
||||
|
||||
let target_list = targets
|
||||
.iter()
|
||||
.map(|target| format!("- [{0}](targets/{0}.md)", target))
|
||||
.map(|(target, _)| format!("- [{0}](targets/{0}.md)", target.name))
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n");
|
||||
|
||||
|
|
@ -127,6 +127,51 @@ pub fn render_static(platform_support: &Path, targets: &[&str]) -> Result<()> {
|
|||
}
|
||||
|
||||
// TODO: Render the nice table showing off all targets and their tier.
|
||||
let platform_support_main = src_output.join("platform-support.md");
|
||||
let platform_support_main_old =
|
||||
fs::read_to_string(&platform_support_main).wrap_err("reading platform-support.md")?;
|
||||
|
||||
let tier3_table =
|
||||
render_table_with_host(targets.into_iter().filter(|target| target.0.tier == "3"))
|
||||
.wrap_err("rendering tier 3 table")?;
|
||||
|
||||
let platform_support_main_new =
|
||||
replace_section(&platform_support_main_old, "TIER3", &tier3_table)
|
||||
.wrap_err("replacing platform support.md")?;
|
||||
|
||||
fs::write(platform_support_main, platform_support_main_new)
|
||||
.wrap_err("writing platform-support.md")?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn render_table_with_host<'a>(
|
||||
targets: impl IntoIterator<Item = &'a (TargetDocs, RustcTargetInfo)>,
|
||||
) -> Result<String> {
|
||||
let mut rows = Vec::new();
|
||||
|
||||
for (target, _) in targets {
|
||||
let meta = target.metadata.as_ref();
|
||||
let std = match meta.map(|meta| meta.std.as_str()) {
|
||||
Some("true") => "✓",
|
||||
Some("unknown") => "?",
|
||||
Some("false") => " ",
|
||||
None => "?",
|
||||
_ => bail!("invalid value for std todo parse early"),
|
||||
};
|
||||
let host = match meta.map(|meta| meta.host.as_str()) {
|
||||
Some("true") => "✓",
|
||||
Some("unknown") => "?",
|
||||
Some("false") => " ",
|
||||
None => "?",
|
||||
_ => bail!("invalid value for host todo parse early"),
|
||||
};
|
||||
let notes = meta.map(|meta| meta.notes.as_str()).unwrap_or("unknown");
|
||||
rows.push(format!(
|
||||
"[`{0}`](platform-support/targets/{0}.md) | {std} | {host} | {notes}",
|
||||
target.name
|
||||
));
|
||||
}
|
||||
|
||||
Ok(rows.join("\n"))
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue