tidy/extra_checks/
rustdoc_js.rs1use std::ffi::OsStr;
5use std::io;
6use std::path::{Path, PathBuf};
7use std::process::{Child, Command};
8
9use build_helper::npm;
10use ignore::DirEntry;
11
12use crate::walk::walk_no_read;
13
14fn node_module_bin(outdir: &Path, name: &str) -> PathBuf {
15 outdir.join("node_modules/.bin").join(name)
16}
17
18fn spawn_cmd(cmd: &mut Command) -> Result<Child, io::Error> {
19 cmd.spawn().map_err(|err| {
20 eprintln!("unable to run {cmd:?} due to {err:?}");
21 err
22 })
23}
24
25pub(super) fn npm_install(root_path: &Path, outdir: &Path, npm: &Path) -> Result<(), super::Error> {
27 npm::install(root_path, outdir, npm)?;
28 Ok(())
29}
30
31fn rustdoc_js_files(librustdoc_path: &Path) -> Vec<PathBuf> {
32 let mut files = Vec::new();
33 walk_no_read(
34 &[&librustdoc_path.join("html/static/js")],
35 |path, is_dir| is_dir || path.extension().is_none_or(|ext| ext != OsStr::new("js")),
36 &mut |path: &DirEntry| {
37 files.push(path.path().into());
38 },
39 );
40 return files;
41}
42
43fn run_eslint(outdir: &Path, args: &[PathBuf], config_folder: PathBuf) -> Result<(), super::Error> {
44 let mut child = spawn_cmd(
45 Command::new(node_module_bin(outdir, "eslint"))
46 .arg("-c")
47 .arg(config_folder.join(".eslintrc.js"))
48 .args(args),
49 )?;
50 match child.wait() {
51 Ok(exit_status) => {
52 if exit_status.success() {
53 return Ok(());
54 }
55 Err(super::Error::FailedCheck("eslint command failed"))
56 }
57 Err(error) => Err(super::Error::Generic(format!("eslint command failed: {error:?}"))),
58 }
59}
60
61pub(super) fn lint(
62 outdir: &Path,
63 librustdoc_path: &Path,
64 tools_path: &Path,
65) -> Result<(), super::Error> {
66 let files_to_check = rustdoc_js_files(librustdoc_path);
67 println!("Running eslint on rustdoc JS files");
68 run_eslint(outdir, &files_to_check, librustdoc_path.join("html/static"))?;
69
70 run_eslint(outdir, &[tools_path.join("rustdoc-js/tester.js")], tools_path.join("rustdoc-js"))?;
71 run_eslint(
72 outdir,
73 &[tools_path.join("rustdoc-gui/tester.js")],
74 tools_path.join("rustdoc-gui"),
75 )?;
76 Ok(())
77}
78
79pub(super) fn typecheck(outdir: &Path, librustdoc_path: &Path) -> Result<(), super::Error> {
80 let mut child = spawn_cmd(
82 Command::new(node_module_bin(outdir, "tsc"))
83 .arg("-p")
84 .arg(librustdoc_path.join("html/static/js/tsconfig.json")),
85 )?;
86 match child.wait() {
87 Ok(exit_status) => {
88 if exit_status.success() {
89 return Ok(());
90 }
91 Err(super::Error::FailedCheck("tsc command failed"))
92 }
93 Err(error) => Err(super::Error::Generic(format!("tsc command failed: {error:?}"))),
94 }
95}
96
97pub(super) fn es_check(outdir: &Path, librustdoc_path: &Path) -> Result<(), super::Error> {
98 let files_to_check = rustdoc_js_files(librustdoc_path);
99 let mut cmd = Command::new(node_module_bin(outdir, "es-check"));
100 cmd.arg("es2019");
101 for f in files_to_check {
102 cmd.arg(f);
103 }
104 match spawn_cmd(&mut cmd)?.wait() {
105 Ok(exit_status) => {
106 if exit_status.success() {
107 return Ok(());
108 }
109 Err(super::Error::FailedCheck("es-check command failed"))
110 }
111 Err(error) => Err(super::Error::Generic(format!("es-check command failed: {error:?}"))),
112 }
113}