22//! characters.
33
44use std:: ffi:: OsStr ;
5- use std:: fs;
65use std:: path:: { Path , PathBuf } ;
7- use std:: process:: Command ;
6+ use std:: process:: { Child , Command } ;
7+ use std:: { fs, io} ;
88
99use build_helper:: ci:: CiEnv ;
1010use ignore:: DirEntry ;
1111
1212use crate :: walk:: walk_no_read;
1313
1414fn node_module_bin ( outdir : & Path , name : & str ) -> PathBuf {
15- outdir. join ( name)
15+ outdir. join ( "node_modules/.bin" ) . join ( name)
16+ }
17+
18+ fn 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+ } )
1623}
1724
1825/// install all js dependencies from package.json.
19- pub ( super ) fn npm_install ( outdir : & Path ) -> Result < ( ) , super :: Error > {
20- let copy_to_build = |p| fs:: copy ( p, outdir. join ( p) ) ;
26+ pub ( super ) fn npm_install ( root_path : & Path , outdir : & Path ) -> Result < ( ) , super :: Error > {
27+ let copy_to_build = |p| {
28+ fs:: copy ( root_path. join ( p) , outdir. join ( p) ) . map_err ( |e| {
29+ eprintln ! ( "unable to copy {p:?} to build directory: {e:?}" ) ;
30+ e
31+ } )
32+ } ;
2133 // copy stuff to the output directory to make node_modules get put there.
2234 copy_to_build ( "package.json" ) ?;
2335 copy_to_build ( "package-lock.json" ) ?;
@@ -34,7 +46,7 @@ pub(super) fn npm_install(outdir: &Path) -> Result<(), super::Error> {
3446 // of repeated tidy invokations.
3547 cmd. args ( & [ "--audit=false" , "--save=false" , "--fund=false" ] ) ;
3648 cmd. current_dir ( outdir) ;
37- let mut child = cmd . spawn ( ) ?;
49+ let mut child = spawn_cmd ( & mut cmd ) ?;
3850 match child. wait ( ) {
3951 Ok ( exit_status) => {
4052 if exit_status. success ( ) {
@@ -59,11 +71,12 @@ fn rustdoc_js_files(librustdoc_path: &Path) -> Vec<PathBuf> {
5971}
6072
6173fn run_eslint ( outdir : & Path , args : & [ PathBuf ] , config_folder : PathBuf ) -> Result < ( ) , super :: Error > {
62- let mut child = Command :: new ( node_module_bin ( outdir, "eslint" ) )
63- . arg ( "-c" )
64- . arg ( config_folder. join ( ".eslintrc.js" ) )
65- . args ( args)
66- . spawn ( ) ?;
74+ let mut child = spawn_cmd (
75+ Command :: new ( node_module_bin ( outdir, "eslint" ) )
76+ . arg ( "-c" )
77+ . arg ( config_folder. join ( ".eslintrc.js" ) )
78+ . args ( args) ,
79+ ) ?;
6780 match child. wait ( ) {
6881 Ok ( exit_status) => {
6982 if exit_status. success ( ) {
@@ -75,62 +88,12 @@ fn run_eslint(outdir: &Path, args: &[PathBuf], config_folder: PathBuf) -> Result
7588 }
7689}
7790
78- fn get_eslint_version_inner ( global : bool ) -> Option < String > {
79- let mut command = Command :: new ( "npm" ) ;
80- command. arg ( "list" ) . arg ( "--parseable" ) . arg ( "--long" ) . arg ( "--depth=0" ) ;
81- if global {
82- command. arg ( "--global" ) ;
83- }
84- let output = command. output ( ) . ok ( ) ?;
85- let lines = String :: from_utf8_lossy ( & output. stdout ) ;
86- lines. lines ( ) . find_map ( |l| l. split ( ':' ) . nth ( 1 ) ?. strip_prefix ( "eslint@" ) ) . map ( |v| v. to_owned ( ) )
87- }
88-
89- fn get_eslint_version ( ) -> Option < String > {
90- get_eslint_version_inner ( false ) . or_else ( || get_eslint_version_inner ( true ) )
91- }
92-
9391pub ( super ) fn lint (
9492 outdir : & Path ,
9593 librustdoc_path : & Path ,
9694 tools_path : & Path ,
9795 src_path : & Path ,
9896) -> Result < ( ) , super :: Error > {
99- let eslint_version_path = src_path. join ( "ci/docker/host-x86_64/tidy/eslint.version" ) ;
100- let eslint_version = match std:: fs:: read_to_string ( & eslint_version_path) {
101- Ok ( version) => version. trim ( ) . to_string ( ) ,
102- Err ( error) => {
103- eprintln ! ( "failed to read `{}`: {error:?}" , eslint_version_path. display( ) ) ;
104- return Err ( error. into ( ) ) ;
105- }
106- } ;
107- // Having the correct `eslint` version installed via `npm` isn't strictly necessary, since we're invoking it via `npx`,
108- // but this check allows the vast majority that is not working on the rustdoc frontend to avoid the penalty of running
109- // `eslint` in tidy. See also: https://github.com/rust-lang/rust/pull/142851
110- match get_eslint_version ( ) {
111- Some ( version) => {
112- if version != eslint_version {
113- // unfortunatly we can't use `Error::Version` here becuse `str::trim` isn't const and
114- // Version::required must be a static str
115- return Err ( super :: Error :: Generic ( format ! (
116- "⚠️ Installed version of eslint (`{version}`) is different than the \
117- one used in the CI (`{eslint_version}`)\n \
118- You can install this version using `npm update eslint` or by using \
119- `npm install eslint@{eslint_version}`\n
120- "
121- ) ) ) ;
122- }
123- }
124- None => {
125- //eprintln!("`eslint` doesn't seem to be installed. Skipping tidy check for JS files.");
126- //eprintln!("You can install it using `npm install eslint@{eslint_version}`");
127- return Err ( super :: Error :: MissingReq (
128- "eslint" ,
129- "js lint checks" ,
130- Some ( format ! ( "You can install it using `npm install eslint@{eslint_version}`" ) ) ,
131- ) ) ;
132- }
133- }
13497 let files_to_check = rustdoc_js_files ( librustdoc_path) ;
13598 println ! ( "Running eslint on rustdoc JS files" ) ;
13699 run_eslint ( outdir, & files_to_check, librustdoc_path. join ( "html/static" ) ) ?;
@@ -146,10 +109,11 @@ pub(super) fn lint(
146109
147110pub ( super ) fn typecheck ( outdir : & Path , librustdoc_path : & Path ) -> Result < ( ) , super :: Error > {
148111 // use npx to ensure correct version
149- let mut child = Command :: new ( node_module_bin ( outdir, "tsc" ) )
150- . arg ( "-p" )
151- . arg ( librustdoc_path. join ( "html/static/js/tsconfig.json" ) )
152- . spawn ( ) ?;
112+ let mut child = spawn_cmd (
113+ Command :: new ( node_module_bin ( outdir, "tsc" ) )
114+ . arg ( "-p" )
115+ . arg ( librustdoc_path. join ( "html/static/js/tsconfig.json" ) ) ,
116+ ) ?;
153117 match child. wait ( ) {
154118 Ok ( exit_status) => {
155119 if exit_status. success ( ) {
@@ -168,7 +132,7 @@ pub(super) fn es_check(outdir: &Path, librustdoc_path: &Path) -> Result<(), supe
168132 for f in files_to_check {
169133 cmd. arg ( f) ;
170134 }
171- match cmd . spawn ( ) ?. wait ( ) {
135+ match spawn_cmd ( & mut cmd ) ?. wait ( ) {
172136 Ok ( exit_status) => {
173137 if exit_status. success ( ) {
174138 return Ok ( ( ) ) ;
0 commit comments