Changeset View
Changeset View
Standalone View
Standalone View
arcanist/linter/ShellLocaleLinter.php
<?php | <?php | ||||
/** | /** | ||||
* Enforce using `export LC_ALL=C` in shell scripts. | * Enforce using `export LC_ALL=C` or `export LC_ALL=C.UTF-8` in shell scripts. | ||||
*/ | */ | ||||
final class ShellLocaleLinter extends ArcanistLinter { | final class ShellLocaleLinter extends ArcanistLinter { | ||||
const INVALID_LOCALE = 1; | const INVALID_LOCALE = 1; | ||||
const LOCALE_STATEMENT = 'export LC_ALL=C'; | const LOCALE_STATEMENTS = array('export LC_ALL=C', 'export LC_ALL=C.UTF-8'); | ||||
public function getInfoName() { | public function getInfoName() { | ||||
return 'lint-shell-locale'; | return 'lint-shell-locale'; | ||||
} | } | ||||
public function getInfoDescription() { | public function getInfoDescription() { | ||||
return pht('Enforce using `'.self::LOCALE_STATEMENT.'` in shell scripts.'); | return pht('Enforce using `'.join('` or `', self::LOCALE_STATEMENTS). | ||||
'` in shell scripts.'); | |||||
} | } | ||||
public function getLinterName() { | public function getLinterName() { | ||||
return 'SHELL_LOCALE'; | return 'SHELL_LOCALE'; | ||||
} | } | ||||
public function getLinterConfigurationName() { | public function getLinterConfigurationName() { | ||||
return 'lint-shell-locale'; | return 'lint-shell-locale'; | ||||
} | } | ||||
public function getLintSeverityMap() { | public function getLintSeverityMap() { | ||||
return array( | return array( | ||||
self::INVALID_LOCALE => ArcanistLintSeverity::SEVERITY_ERROR, | self::INVALID_LOCALE => ArcanistLintSeverity::SEVERITY_ERROR, | ||||
); | ); | ||||
} | } | ||||
public function getLintNameMap() { | public function getLintNameMap() { | ||||
return array( | return array( | ||||
self::INVALID_LOCALE => pht('`'.self::LOCALE_STATEMENT.'` should be '. | self::INVALID_LOCALE => pht( | ||||
'`'.join('` or `', self::LOCALE_STATEMENTS).'` should be '. | |||||
'the first statement.'), | 'the first statement.'), | ||||
); | ); | ||||
} | } | ||||
public function lintPath($path) { | public function lintPath($path) { | ||||
$absPath = Filesystem::resolvePath($path, $this->getProjectRoot()); | $absPath = Filesystem::resolvePath($path, $this->getProjectRoot()); | ||||
$fileContent = Filesystem::readFile($absPath); | $fileContent = Filesystem::readFile($absPath); | ||||
if (!preg_match_all('/^[^#\s]+.+/m', $fileContent, $matches)) { | if (!preg_match_all('/^[^#\s]+.+/m', $fileContent, $matches)) { | ||||
throw new Exception(pht('Error while parsing %s: the script seems to '. | throw new Exception(pht('Error while parsing %s: the script seems to '. | ||||
'have only comments and/or empty lines.', $path)); | 'have only comments and/or empty lines.', $path)); | ||||
} | } | ||||
if (!(trim($matches[0][0]) === self::LOCALE_STATEMENT)) { | if (array_search(trim($matches[0][0]), | ||||
self::LOCALE_STATEMENTS, true) === false) { | |||||
return $this->raiseLintAtPath( | return $this->raiseLintAtPath( | ||||
self::INVALID_LOCALE, | self::INVALID_LOCALE, | ||||
pht('Shell scripts should set the locale to avoid side effects.') | pht('Shell scripts should set the locale to avoid side effects.') | ||||
); | ); | ||||
} | } | ||||
} | } | ||||
} | } |