This commit is contained in:
nora 2024-03-16 14:09:27 +01:00
parent 135c9bbbb1
commit 9b03329260
5 changed files with 58 additions and 100 deletions

View file

@ -1,25 +0,0 @@
name: Deploy mdBook
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Setup mdBook
uses: peaceiris/actions-mdbook@v1
with:
mdbook-version: '0.4.35'
- uses: dtolnay/rust-toolchain@stable
- name: Build docs
run: |
export RUSTC=$(rustup which rustc)
cargo run
- run: |
cd targets && mdbook build
- name: Deploy
uses: peaceiris/actions-gh-pages@v3
# the build has been made rust-lang/rust specific
if: ${{ false && github.ref == 'refs/heads/master' }}
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./targets/book

View file

@ -58,24 +58,15 @@ fn main() -> Result<()> {
.wrap_err("failed loading target_info")? .wrap_err("failed loading target_info")?
.into_iter() .into_iter()
.map(|info| { .map(|info| {
let footnotes_used = info let footnotes_used =
.footnotes info.footnotes.keys().map(|target| (target.clone(), false)).collect();
.keys() TargetPatternEntry { info, used: false, footnotes_used }
.map(|target| (target.clone(), false))
.collect();
TargetPatternEntry {
info,
used: false,
footnotes_used,
}
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
eprintln!("Collecting rustc information"); eprintln!("Collecting rustc information");
let rustc_infos = targets let rustc_infos =
.iter() targets.iter().map(|target| rustc_target_info(&rustc, target)).collect::<Vec<_>>();
.map(|target| rustc_target_info(&rustc, target))
.collect::<Vec<_>>();
let targets = targets let targets = targets
.into_iter() .into_iter()
@ -92,9 +83,7 @@ fn main() -> Result<()> {
.collect::<Vec<_>>(); .collect::<Vec<_>>();
eprintln!("Rendering targets check_only={check_only}"); eprintln!("Rendering targets check_only={check_only}");
let targets_dir = Path::new(output_src) let targets_dir = Path::new(output_src).join("platform-support").join("targets");
.join("platform-support")
.join("targets");
if !check_only { if !check_only {
std::fs::create_dir_all(&targets_dir).wrap_err("creating platform-support/targets dir")?; std::fs::create_dir_all(&targets_dir).wrap_err("creating platform-support/targets dir")?;
} }
@ -109,10 +98,7 @@ fn main() -> Result<()> {
for target_pattern in info_patterns { for target_pattern in info_patterns {
if !target_pattern.used { if !target_pattern.used {
bail!( bail!("target pattern `{}` was never used", target_pattern.info.pattern);
"target pattern `{}` was never used",
target_pattern.info.pattern
);
} }
for footnote_target in target_pattern.info.footnotes.keys() { for footnote_target in target_pattern.info.footnotes.keys() {
@ -170,9 +156,7 @@ fn target_doc_info(info_patterns: &mut [TargetPatternEntry], target: &str) -> Ta
} }
if let Some(target_footnotes) = target_pattern.footnotes.get(target) { if let Some(target_footnotes) = target_pattern.footnotes.get(target) {
target_pattern_entry target_pattern_entry.footnotes_used.insert(target.to_owned(), true);
.footnotes_used
.insert(target.to_owned(), true);
if !footnotes.is_empty() { if !footnotes.is_empty() {
panic!("target {target} is assigned metadata from more than one pattern"); panic!("target {target} is assigned metadata from more than one pattern");
@ -182,12 +166,7 @@ fn target_doc_info(info_patterns: &mut [TargetPatternEntry], target: &str) -> Ta
} }
} }
TargetInfoMd { TargetInfoMd { name: target.to_owned(), maintainers, sections, footnotes }
name: target.to_owned(),
maintainers,
sections,
footnotes,
}
} }
/// Information about a target obtained from rustc. /// Information about a target obtained from rustc.
@ -229,21 +208,12 @@ fn rustc_target_info(rustc: &Path, target: &str) -> RustcTargetInfo {
let json_spec = rustc_stdout( let json_spec = rustc_stdout(
rustc, rustc,
&[ &["-Zunstable-options", "--print", "target-spec-json", "--target", target],
"-Zunstable-options",
"--print",
"target-spec-json",
"--target",
target,
],
); );
let spec = serde_json::from_str::<TargetJson>(&json_spec) let spec = serde_json::from_str::<TargetJson>(&json_spec)
.expect("parsing --print target-spec-json for metadata"); .expect("parsing --print target-spec-json for metadata");
RustcTargetInfo { RustcTargetInfo { target_cfgs, metadata: spec.metadata }
target_cfgs,
metadata: spec.metadata,
}
} }
fn rustc_stdout(rustc: &Path, args: &[&str]) -> String { fn rustc_stdout(rustc: &Path, args: &[&str]) -> String {

View file

@ -70,9 +70,7 @@ fn load_single_target_info(entry: &DirEntry) -> Result<ParsedTargetInfoFile> {
fn parse_file(name: &str, content: &str) -> Result<ParsedTargetInfoFile> { fn parse_file(name: &str, content: &str) -> Result<ParsedTargetInfoFile> {
let mut frontmatter_splitter = content.split("---\n"); let mut frontmatter_splitter = content.split("---\n");
let frontmatter = frontmatter_splitter let frontmatter = frontmatter_splitter.nth(1).ok_or_eyre("missing frontmatter")?;
.nth(1)
.ok_or_eyre("missing frontmatter")?;
let frontmatter_line_count = frontmatter.lines().count() + 2; // 2 from --- let frontmatter_line_count = frontmatter.lines().count() + 2; // 2 from ---
@ -86,10 +84,8 @@ fn parse_file(name: &str, content: &str) -> Result<ParsedTargetInfoFile> {
for (idx, line) in body.lines().enumerate() { for (idx, line) in body.lines().enumerate() {
let number = frontmatter_line_count + idx + 1; // 1 because "line numbers" are off by 1 let number = frontmatter_line_count + idx + 1; // 1 because "line numbers" are off by 1
if line.starts_with("```") {
in_codeblock ^= true; // toggle let push_line = |sections: &mut Vec<(String, String)>, line| {
} else if line.starts_with('#') {
if in_codeblock {
match sections.last_mut() { match sections.last_mut() {
Some((_, content)) => { Some((_, content)) => {
content.push_str(line); content.push_str(line);
@ -100,6 +96,15 @@ fn parse_file(name: &str, content: &str) -> Result<ParsedTargetInfoFile> {
bail!("line {number} with content not allowed before the first heading") bail!("line {number} with content not allowed before the first heading")
} }
} }
Ok(())
};
if line.starts_with("```") {
in_codeblock ^= true; // toggle
push_line(&mut sections, line)?;
} else if line.starts_with('#') {
if in_codeblock {
push_line(&mut sections, line)?;
} else if let Some(header) = line.strip_prefix("## ") { } else if let Some(header) = line.strip_prefix("## ") {
if !crate::SECTIONS.contains(&header) { if !crate::SECTIONS.contains(&header) {
bail!( bail!(
@ -112,20 +117,11 @@ fn parse_file(name: &str, content: &str) -> Result<ParsedTargetInfoFile> {
bail!("on line {number}, the only allowed headings are `## `: `{line}`"); bail!("on line {number}, the only allowed headings are `## `: `{line}`");
} }
} else { } else {
match sections.last_mut() { push_line(&mut sections, line)?;
Some((_, content)) => {
content.push_str(line);
content.push('\n');
}
None if line.trim().is_empty() => {}
None => bail!("line with content not allowed before the first heading"),
}
} }
} }
sections sections.iter_mut().for_each(|section| section.1 = section.1.trim().to_owned());
.iter_mut()
.for_each(|section| section.1 = section.1.trim().to_owned());
Ok(ParsedTargetInfoFile { Ok(ParsedTargetInfoFile {
pattern: name.to_owned(), pattern: name.to_owned(),

View file

@ -74,3 +74,26 @@ But it should be possible.
] ]
); );
} }
#[test]
fn backticks() {
let name = "microservices-unknown-linux-gnu"; // microservices are my favourite architecture
let content = r#"
---
---
## Testing
```text
# hello world
```
"#;
let info = super::parse_file(name, content).unwrap();
assert_eq!(info.pattern, name);
assert_eq!(
info.sections,
vec![("Testing".to_owned(), "```text\n# hello world\n```".to_owned(),),]
);
}

View file

@ -60,10 +60,7 @@ pub fn render_target_md(target: &TargetInfo) -> String {
section("Maintainers", &maintainers_content); section("Maintainers", &maintainers_content);
for section_name in crate::SECTIONS { for section_name in crate::SECTIONS {
let value = target let value = target.sections.iter().find(|(name, _)| name == section_name);
.sections
.iter()
.find(|(name, _)| name == section_name);
let section_content = match value { let section_content = match value {
Some((_, value)) => value.clone(), Some((_, value)) => value.clone(),
@ -137,11 +134,8 @@ pub fn render_static(check_only: bool, src_output: &Path, targets: &[TargetInfo]
let summary = src_output.join("SUMMARY.md"); let summary = src_output.join("SUMMARY.md");
let summary_old = fs::read_to_string(&summary).wrap_err("reading SUMMARY.md")?; let summary_old = fs::read_to_string(&summary).wrap_err("reading SUMMARY.md")?;
// indent the list // indent the list
let summary_new = replace_section( let summary_new =
&summary_old, replace_section(&summary_old, "TARGET_LIST", &target_list.replace("- ", " - "))
"TARGET_LIST",
&target_list.replace("- ", " - "),
)
.wrap_err("replacig SUMMARY.md")?; .wrap_err("replacig SUMMARY.md")?;
if !check_only { if !check_only {
fs::write(summary, summary_new).wrap_err("writing SUMAMRY.md")?; fs::write(summary, summary_new).wrap_err("writing SUMAMRY.md")?;