diff --git a/.arclint b/.arclint --- a/.arclint +++ b/.arclint @@ -17,10 +17,6 @@ "(^src/(secp256k1|univalue|leveldb)/)" ] }, - "check-doc": { - "type": "check-doc", - "include": "(^src/.*\\.(h|c|cpp)$)" - }, "lint-tests": { "type": "lint-tests", "include": "(^src/(rpc/|wallet/)?test/.*\\.(cpp)$)" diff --git a/.runonce.arclint b/.runonce.arclint new file mode 100644 --- /dev/null +++ b/.runonce.arclint @@ -0,0 +1,8 @@ +{ + "linters": { + "check-doc": { + "type": "check-doc", + "include": "(^src/.*\\.(h|c|cpp)$)" + } + } +} diff --git a/arcanist/.phutil_module_cache b/arcanist/.phutil_module_cache --- a/arcanist/.phutil_module_cache +++ b/arcanist/.phutil_module_cache @@ -1 +1 @@ -{"__symbol_cache_version__":11,"b3016722acf4fd40b88be13e339d74c1":{"have":{"class":{"BitcoinABCConfiguration":13}},"need":{"class":{"ArcanistConfiguration":45,"ArcanistLintWorkflow":360},"class\/interface":{"ArcanistWorkflow":468,"ArcanistNoEffectException":261}},"xmap":{"BitcoinABCConfiguration":["ArcanistConfiguration"]}},"2809b09d2021203b43c57da33d1fe8bf":{"have":{"class":{"AssertWithSideEffectsLinter":210}},"need":{"function":{"pht":439},"class":{"ArcanistLinter":246,"ArcanistLintSeverity":926,"Filesystem":1170}},"xmap":{"AssertWithSideEffectsLinter":["ArcanistLinter"]}},"90a8b110dc475955f15bb81d37268cb5":{"have":{"class":{"AutoPEP8FormatLinter":75}},"need":{"function":{"pht":297,"execx":769,"id":1903},"class":{"ArcanistExternalLinter":104,"ArcanistLintMessage":1910,"Filesystem":1754,"ArcanistLinter":2017,"ArcanistLintSeverity":2095}},"xmap":{"AutoPEP8FormatLinter":["ArcanistExternalLinter"]}},"38f0c676bff5192a344464142caaa253":{"have":{"class":{"CHeaderLinter":99}},"need":{"function":{"pht":611},"class":{"ArcanistLinter":121,"ArcanistLintSeverity":1060,"Filesystem":1307}},"xmap":{"CHeaderLinter":["ArcanistLinter"]}},"a30e4e25376ca05d4ae719915441be9e":{"have":{"class":{"CheckDocLinter":106}},"need":{"function":{"pht":323,"id":1848},"class":{"ArcanistExternalLinter":129,"ArcanistLintMessage":1855,"Filesystem":731,"ArcanistLinter":1903,"ArcanistLintSeverity":1989}},"xmap":{"CheckDocLinter":["ArcanistExternalLinter"]}},"6af7410cfea496ff1d4dcc2624b6b8ea":{"have":{"class":{"ClangFormatLinter":79}},"need":{"function":{"pht":302,"execx":781,"id":1653},"class":{"ArcanistExternalLinter":105,"ArcanistLintMessage":1660,"Filesystem":1504,"ArcanistLinter":1767,"ArcanistLintSeverity":1845}},"xmap":{"ClangFormatLinter":["ArcanistExternalLinter"]}},"9285ad9415f8ebe564f7119e5a72c559":{"have":{"class":{"FormatStringLinter":146}},"need":{"function":{"pht":377,"csprintf":1492,"id":1872},"class":{"ArcanistExternalLinter":173,"ArcanistLintMessage":1879,"Filesystem":827,"ArcanistLinter":1956,"ArcanistLintSeverity":2044}},"xmap":{"FormatStringLinter":["ArcanistExternalLinter"]}},"224d394856b17878058b4c14acb7178b":{"have":{"class":{"LocaleDependenceLinter":160}},"need":{"function":{"pht":5400},"class":{"ArcanistLinter":191,"ArcanistLintSeverity":5903,"Filesystem":6149}},"xmap":{"LocaleDependenceLinter":["ArcanistLinter"]}},"6f2f22dd0f259fb2eaa284b4fab3bc29":{"have":{"class":{"PythonFormatLinter":123}},"need":{"function":{"pht":353,"id":1838},"class":{"ArcanistExternalLinter":150,"ArcanistLintMessage":1845,"Filesystem":776,"ArcanistLinter":1970,"ArcanistLintSeverity":2053}},"xmap":{"PythonFormatLinter":["ArcanistExternalLinter"]}},"25781df78f6eebfb223296b8265e9d19":{"have":{"class":{"TestsLinter":103}},"need":{"function":{"pht":318,"id":2629},"class":{"ArcanistExternalLinter":123,"ArcanistLintMessage":2636,"Filesystem":776,"ArcanistLinter":2684,"ArcanistLintSeverity":2792}},"xmap":{"TestsLinter":["ArcanistExternalLinter"]}},"0ab29329c5371d373da9d1ad4ff7db97":{"have":{"class":{"BitcoinABCConfigurationDrivenLintEngine":13}},"need":{"function":{"pht":383,"phutil_json_decode":700,"idx":1440,"id":4148},"class":{"ArcanistLintEngine":61,"ArcanistUsageException":351,"PhutilProxyException":789,"PhutilClassMapQuery":4155,"Filesystem":295,"PhutilTypeSpec":1067,"PhutilConsole":3620},"class\/interface":{"PhutilJSONParserException":740,"PhutilTypeCheckException":1262}},"xmap":{"BitcoinABCConfigurationDrivenLintEngine":["ArcanistLintEngine"]}},"45021061144f2a52622e3325a70c80cf":{"have":{"class":{"RunLastLintEngine":19}},"need":{"class":{"BitcoinABCConfigurationDrivenLintEngine":45}},"xmap":{"RunLastLintEngine":["BitcoinABCConfigurationDrivenLintEngine"]}}} \ No newline at end of file +{"__symbol_cache_version__":11,"2809b09d2021203b43c57da33d1fe8bf":{"have":{"class":{"AssertWithSideEffectsLinter":210}},"need":{"function":{"pht":439},"class":{"ArcanistLinter":246,"ArcanistLintSeverity":926,"Filesystem":1170}},"xmap":{"AssertWithSideEffectsLinter":["ArcanistLinter"]}},"90a8b110dc475955f15bb81d37268cb5":{"have":{"class":{"AutoPEP8FormatLinter":75}},"need":{"function":{"pht":297,"execx":769,"id":1903},"class":{"ArcanistExternalLinter":104,"ArcanistLintMessage":1910,"Filesystem":1754,"ArcanistLinter":2017,"ArcanistLintSeverity":2095}},"xmap":{"AutoPEP8FormatLinter":["ArcanistExternalLinter"]}},"38f0c676bff5192a344464142caaa253":{"have":{"class":{"CHeaderLinter":99}},"need":{"function":{"pht":611},"class":{"ArcanistLinter":121,"ArcanistLintSeverity":1060,"Filesystem":1307}},"xmap":{"CHeaderLinter":["ArcanistLinter"]}},"a30e4e25376ca05d4ae719915441be9e":{"have":{"class":{"CheckDocLinter":106}},"need":{"function":{"pht":323,"id":1848},"class":{"ArcanistExternalLinter":129,"ArcanistLintMessage":1855,"Filesystem":731,"ArcanistLinter":1903,"ArcanistLintSeverity":1989}},"xmap":{"CheckDocLinter":["ArcanistExternalLinter"]}},"6af7410cfea496ff1d4dcc2624b6b8ea":{"have":{"class":{"ClangFormatLinter":79}},"need":{"function":{"pht":302,"execx":781,"id":1653},"class":{"ArcanistExternalLinter":105,"ArcanistLintMessage":1660,"Filesystem":1504,"ArcanistLinter":1767,"ArcanistLintSeverity":1845}},"xmap":{"ClangFormatLinter":["ArcanistExternalLinter"]}},"9285ad9415f8ebe564f7119e5a72c559":{"have":{"class":{"FormatStringLinter":146}},"need":{"function":{"pht":377,"csprintf":1492,"id":1872},"class":{"ArcanistExternalLinter":173,"ArcanistLintMessage":1879,"Filesystem":827,"ArcanistLinter":1956,"ArcanistLintSeverity":2044}},"xmap":{"FormatStringLinter":["ArcanistExternalLinter"]}},"224d394856b17878058b4c14acb7178b":{"have":{"class":{"LocaleDependenceLinter":160}},"need":{"function":{"pht":5400},"class":{"ArcanistLinter":191,"ArcanistLintSeverity":5903,"Filesystem":6149}},"xmap":{"LocaleDependenceLinter":["ArcanistLinter"]}},"6f2f22dd0f259fb2eaa284b4fab3bc29":{"have":{"class":{"PythonFormatLinter":123}},"need":{"function":{"pht":353,"id":1838},"class":{"ArcanistExternalLinter":150,"ArcanistLintMessage":1845,"Filesystem":776,"ArcanistLinter":1970,"ArcanistLintSeverity":2053}},"xmap":{"PythonFormatLinter":["ArcanistExternalLinter"]}},"25781df78f6eebfb223296b8265e9d19":{"have":{"class":{"TestsLinter":103}},"need":{"function":{"pht":318,"id":2629},"class":{"ArcanistExternalLinter":123,"ArcanistLintMessage":2636,"Filesystem":776,"ArcanistLinter":2684,"ArcanistLintSeverity":2792}},"xmap":{"TestsLinter":["ArcanistExternalLinter"]}},"0ab29329c5371d373da9d1ad4ff7db97":{"have":{"class":{"BitcoinABCConfigurationDrivenLintEngine":13}},"need":{"function":{"pht":383,"phutil_json_decode":700,"idx":1440,"id":4148},"class":{"ArcanistLintEngine":61,"ArcanistUsageException":351,"PhutilProxyException":789,"PhutilClassMapQuery":4155,"Filesystem":295,"PhutilTypeSpec":1067,"PhutilConsole":3620},"class\/interface":{"PhutilJSONParserException":740,"PhutilTypeCheckException":1262}},"xmap":{"BitcoinABCConfigurationDrivenLintEngine":["ArcanistLintEngine"]}},"45021061144f2a52622e3325a70c80cf":{"have":{"class":{"RunLastLintEngine":19}},"need":{"class":{"BitcoinABCConfigurationDrivenLintEngine":45}},"xmap":{"RunLastLintEngine":["BitcoinABCConfigurationDrivenLintEngine"]}},"95c3ca0a656be4fc106bd4dfec2f27e6":{"have":{"class":{"RunOnceLintEngine":19}},"need":{"class":{"BitcoinABCConfigurationDrivenLintEngine":45}},"xmap":{"RunOnceLintEngine":["BitcoinABCConfigurationDrivenLintEngine"]}},"cdf54537a73f1edcaa6e97c5dba4f60b":{"have":{"class":{"BitcoinABCConfiguration":13}},"need":{"class":{"ArcanistConfiguration":45,"ArcanistLintWorkflow":360},"class\/interface":{"ArcanistWorkflow":468,"ArcanistNoEffectException":261}},"xmap":{"BitcoinABCConfiguration":["ArcanistConfiguration"]}}} \ No newline at end of file diff --git a/arcanist/__phutil_library_map__.php b/arcanist/__phutil_library_map__.php --- a/arcanist/__phutil_library_map__.php +++ b/arcanist/__phutil_library_map__.php @@ -20,6 +20,7 @@ 'LocaleDependenceLinter' => 'linter/LocaleDependenceLinter.php', 'PythonFormatLinter' => 'linter/PythonFormatLinter.php', 'RunLastLintEngine' => 'linter/engine/RunLastLintEngine.php', + 'RunOnceLintEngine' => 'linter/engine/RunOnceLintEngine.php', 'TestsLinter' => 'linter/TestsLinter.php', ), 'function' => array(), @@ -35,6 +36,7 @@ 'LocaleDependenceLinter' => 'ArcanistLinter', 'PythonFormatLinter' => 'ArcanistExternalLinter', 'RunLastLintEngine' => 'BitcoinABCConfigurationDrivenLintEngine', + 'RunOnceLintEngine' => 'BitcoinABCConfigurationDrivenLintEngine', 'TestsLinter' => 'ArcanistExternalLinter', ), )); diff --git a/arcanist/configuration/BitcoinABCConfiguration.php b/arcanist/configuration/BitcoinABCConfiguration.php --- a/arcanist/configuration/BitcoinABCConfiguration.php +++ b/arcanist/configuration/BitcoinABCConfiguration.php @@ -18,6 +18,11 @@ public function willRunWorkflow($command, ArcanistWorkflow $workflow) { if ($command === 'diff' && !$workflow->getArgument('nolint')) { $err = $this->runLint($workflow); + + $config = $workflow->getConfigurationManager(); + $config->setRuntimeConfig('lint.engine', 'RunOnceLintEngine'); + $err |= $this->runLint($workflow); + if ($err != ArcanistLintWorkflow::RESULT_OKAY) { $workflow->finalize(); exit($err); @@ -27,7 +32,6 @@ * Set the configuration but don't run the linter, the diff workflow will * do it for us. */ - $config = $workflow->getConfigurationManager(); $config->setRuntimeConfig('lint.engine', 'RunLastLintEngine'); } } @@ -35,6 +39,10 @@ public function didRunWorkflow($command, ArcanistWorkflow $workflow, $err) { if ($command === 'lint') { $config = $workflow->getConfigurationManager(); + + $config->setRuntimeConfig('lint.engine', 'RunOnceLintEngine'); + $this->runLint($workflow); + $config->setRuntimeConfig('lint.engine', 'RunLastLintEngine'); $this->runLint($workflow); } diff --git a/arcanist/linter/engine/RunOnceLintEngine.php b/arcanist/linter/engine/RunOnceLintEngine.php new file mode 100644 --- /dev/null +++ b/arcanist/linter/engine/RunOnceLintEngine.php @@ -0,0 +1,24 @@ +configurationFile = '.runonce.arclint'; + return parent::buildLinters(); + } + + protected function matchPaths( + array $paths, + array $include, + array $exclude, + array $global_exclude) { + $paths = parent::matchPaths($paths, $include, $exclude, $global_exclude); + /* + * We want to make sure that at least one path matches the regex, otherwise + * the linter should not run. + * But if there are multiple paths, only associate one of them to make the + * linter run only once. + */ + return empty($paths)? array() : array($paths[0]); + } +}