Index: .arclint =================================================================== --- .arclint +++ .arclint @@ -25,9 +25,8 @@ }, "eslint": { "type": "eslint", - "bin": ["eslint", "build\\arclint\\dummies\\eslint.bat", "build/arclint/dummies/eslint.php"], - "include": "/\\.js$/", - "config": "build/arclint/configs/eslintrc.json" + "bin": ["build/arclint/eslint/node_modules/.bin/eslint", "eslint", "build\\arclint\\dummies\\eslint.bat", "build/arclint/dummies/eslint.php"], + "include": "/\\.js$/" }, "cppcheck": { "type": "cppcheck", Index: .eslintrc.json =================================================================== --- /dev/null +++ .eslintrc.json @@ -0,0 +1,10 @@ +{ + "root": true, + "extends": "./build/arclint/configs/eslintrc.json", + "ignorePatterns": [ + "binaries/data/mods/mod/globalscripts/sprintf.js", + "build/arclint/eslint/node_modules/", + "libraries/", + "source/" + ] +} Index: .gitignore =================================================================== --- .gitignore +++ .gitignore @@ -19,6 +19,9 @@ binaries/system/test binaries/system/test_dbg +build/arclint/eslint/node_modules/ +build/arclint/eslint/.eslintcache +build/arclint/eslint/package-lock.json build/workspaces/codeblocks/ build/workspaces/gcc/ build/workspaces/xcode3/ Index: build/arclint/README.md =================================================================== --- build/arclint/README.md +++ build/arclint/README.md @@ -25,10 +25,10 @@ #### eslint -Installation via npm is recommended. The linter assumes a global installation of both eslint and the "brace-rules" plugin. -`npm install -g eslint@latest eslint-plugin-brace-rules` +Node.js is required. Installation via npm is recommended. +Run `npm install` in the `build/arclint/eslint/` directory. -See also https://eslint.org/docs/user-guide/getting-started +See also and . #### cppcheck Index: build/arclint/configs/eslintrc.json =================================================================== --- build/arclint/configs/eslintrc.json +++ build/arclint/configs/eslintrc.json @@ -1,4 +1,5 @@ { + "root": true, "parserOptions": { "ecmaVersion": 2020 }, Index: build/arclint/dummies/cppcheck.php =================================================================== --- build/arclint/dummies/cppcheck.php +++ build/arclint/dummies/cppcheck.php @@ -26,7 +26,7 @@ * Set the VERBOSE env variable to generate an 'advice' level lint message. */ -$verbose = getenv("VERBOSE") ? getenv("VERBOSE") : false; +$verbose = (bool)getenv("VERBOSE"); $advice = !$verbose ? "" : << @@ -40,4 +40,3 @@ EOD; fwrite(STDERR, $str); -?> Index: build/arclint/dummies/eslint.php =================================================================== --- build/arclint/dummies/eslint.php +++ build/arclint/dummies/eslint.php @@ -26,7 +26,7 @@ * Set the VERBOSE env variable to generate an 'advice' level lint message. */ -$verbose = getenv("VERBOSE") ? getenv("VERBOSE") : false; +$verbose = (bool)getenv("VERBOSE"); $advice = << Index: build/arclint/eslint/package.json =================================================================== --- /dev/null +++ build/arclint/eslint/package.json @@ -0,0 +1,13 @@ +{ + "private": true, + "devDependencies": { + "eslint": "7.22.0", + "eslint-plugin-brace-rules": "0.1.6" + }, + "scripts": { + "test": "npm run -s lint", + "lint": "eslint --cache --resolve-plugins-relative-to . --report-unused-disable-directives ../../../", + "fix": "eslint --cache --resolve-plugins-relative-to . --fix", + "fix-all": "eslint --cache --resolve-plugins-relative-to . --fix ../../../" + } +} Index: build/arclint/pyrolint/src/ESLintLinter.php =================================================================== --- build/arclint/pyrolint/src/ESLintLinter.php +++ build/arclint/pyrolint/src/ESLintLinter.php @@ -33,46 +33,35 @@ } public function getDefaultBinary() { + // See also the "bin" array in /.arclint return 'eslint'; } public function getInstallInstructions() { return pht( - 'Install eslint using npm install -g eslint.', - 'Install the brace-rule plugin using', - 'npm install -g eslint-plugin-brace-rules'); + 'Install eslint from npm by running "npm install" in the /build/arclint/eslint/ directory.' + ); } protected function getMandatoryFlags() { - list($err, $stdout, $stderr) = exec_manual('npm root -g'); + // If the 'eslint' was installed globally (e.g. as Jenkins CI has) then + // tell ESLint to load for plugins from the global node path. + // Otherwise, use the local install (e.g. a developer ran 'npm install' in + // their /build/arclint/eslint/ directory). Use of global install is discouraged + // for developers, but for CI we do it because that's easier to snapshot + // and re-use between builds. + if ($this->getBinary() === 'eslint') { + list($err, $stdout, $stderr) = exec_manual('npm root -g'); + $nodePath = strtok($stdout, "\n"); + } else { + $nodePath = 'build/arclint/eslint/'; + } return array( '--format=json', '--no-color', - '--config', - $this->config, - // This allows globally installing plugins even with eslint 6+ '--resolve-plugins-relative-to', - strtok($stdout, "\n") - ); - } - - public function getLinterConfigurationOptions() { - $options = array( - 'config' => array( - 'type' => 'optional string', - 'help' => pht('Link to the config file.'), - ), + $nodePath ); - return $options + parent::getLinterConfigurationOptions(); - } - - public function setLinterConfigurationValue($key, $value) { - switch ($key) { - case 'config': - $this->config = $value; - return; - } - return parent::setLinterConfigurationValue($key, $value); } protected function parseLinterOutput($path, $err, $stdout, $stderr) {