mirror of
https://github.com/danog/psalm.git
synced 2024-12-02 09:37:59 +01:00
Add config creation utility
This commit is contained in:
parent
500044dac1
commit
0277ca49ba
11
assets/config_levels/1.xml
Normal file
11
assets/config_levels/1.xml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<psalm
|
||||||
|
name="Example Psalm config with recommended defaults"
|
||||||
|
stopOnFirstError="false"
|
||||||
|
useDocblockTypes="true"
|
||||||
|
totallyTyped="true"
|
||||||
|
>
|
||||||
|
<projectFiles>
|
||||||
|
<directory name="src" />
|
||||||
|
</projectFiles>
|
||||||
|
</psalm>
|
11
assets/config_levels/2.xml
Normal file
11
assets/config_levels/2.xml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<psalm
|
||||||
|
name="Example Psalm config with recommended defaults"
|
||||||
|
stopOnFirstError="false"
|
||||||
|
useDocblockTypes="true"
|
||||||
|
totallyTyped="false"
|
||||||
|
>
|
||||||
|
<projectFiles>
|
||||||
|
<directory name="src" />
|
||||||
|
</projectFiles>
|
||||||
|
</psalm>
|
25
assets/config_levels/3.xml
Normal file
25
assets/config_levels/3.xml
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<psalm
|
||||||
|
name="Example Psalm config with recommended defaults"
|
||||||
|
stopOnFirstError="false"
|
||||||
|
useDocblockTypes="true"
|
||||||
|
totallyTyped="false"
|
||||||
|
>
|
||||||
|
<projectFiles>
|
||||||
|
<directory name="src" />
|
||||||
|
</projectFiles>
|
||||||
|
|
||||||
|
<issueHandlers>
|
||||||
|
<!-- level 3 issues - slightly lazy code writing, but provably low false-negatives -->
|
||||||
|
<DeprecatedMethod errorLevel="info" />
|
||||||
|
|
||||||
|
<MissingClosureReturnType errorLevel="info" />
|
||||||
|
<MissingReturnType errorLevel="info" />
|
||||||
|
<MissingPropertyType errorLevel="info" />
|
||||||
|
<InvalidDocblock errorLevel="info" />
|
||||||
|
<MisplacedRequiredParam errorLevel="info" />
|
||||||
|
|
||||||
|
<PropertyNotSetInConstructor errorLevel="info" />
|
||||||
|
<MissingConstructor errorLevel="info" />
|
||||||
|
</issueHandlers>
|
||||||
|
</psalm>
|
40
assets/config_levels/4.xml
Normal file
40
assets/config_levels/4.xml
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<psalm
|
||||||
|
name="Example Psalm config with recommended defaults"
|
||||||
|
stopOnFirstError="false"
|
||||||
|
useDocblockTypes="true"
|
||||||
|
totallyTyped="false"
|
||||||
|
>
|
||||||
|
<projectFiles>
|
||||||
|
<directory name="src" />
|
||||||
|
</projectFiles>
|
||||||
|
|
||||||
|
<issueHandlers>
|
||||||
|
<!-- level 3 issues - slightly lazy code writing, but provably low false-negatives -->
|
||||||
|
|
||||||
|
<DeprecatedMethod errorLevel="info" />
|
||||||
|
|
||||||
|
<MissingClosureReturnType errorLevel="info" />
|
||||||
|
<MissingReturnType errorLevel="info" />
|
||||||
|
<MissingPropertyType errorLevel="info" />
|
||||||
|
<InvalidDocblock errorLevel="info" />
|
||||||
|
<MisplacedRequiredParam errorLevel="info" />
|
||||||
|
|
||||||
|
<PropertyNotSetInConstructor errorLevel="info" />
|
||||||
|
<MissingConstructor errorLevel="info" />
|
||||||
|
|
||||||
|
<!-- level 4 issues - points to possible deficiencies in logic, higher false-positives -->
|
||||||
|
|
||||||
|
<MoreSpecificReturnType errorLevel="info" />
|
||||||
|
<TypeCoercion errorLevel="info" />
|
||||||
|
|
||||||
|
<PossiblyNullArgument errorLevel="info" />
|
||||||
|
<PossiblyNullArrayAccess errorLevel="info" />
|
||||||
|
<PossiblyNullOperand errorLevel="info" />
|
||||||
|
<PossiblyNullPropertyAssignment errorLevel="info" />
|
||||||
|
<PossiblyNullPropertyFetch errorLevel="info" />
|
||||||
|
<PossiblyNullReference errorLevel="info" />
|
||||||
|
<PossiblyUndefinedVariable errorLevel="info" />
|
||||||
|
<PossiblyUnusedVariable errorLevel="info" />
|
||||||
|
</issueHandlers>
|
||||||
|
</psalm>
|
52
assets/config_levels/5.xml
Normal file
52
assets/config_levels/5.xml
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<psalm
|
||||||
|
name="Example Psalm config with recommended defaults"
|
||||||
|
stopOnFirstError="false"
|
||||||
|
useDocblockTypes="true"
|
||||||
|
totallyTyped="false"
|
||||||
|
>
|
||||||
|
<projectFiles>
|
||||||
|
<directory name="src" />
|
||||||
|
</projectFiles>
|
||||||
|
|
||||||
|
<issueHandlers>
|
||||||
|
<!-- level 3 issues - slightly lazy code writing, but provably low false-negatives -->
|
||||||
|
|
||||||
|
<DeprecatedMethod errorLevel="info" />
|
||||||
|
|
||||||
|
<MissingClosureReturnType errorLevel="info" />
|
||||||
|
<MissingReturnType errorLevel="info" />
|
||||||
|
<MissingPropertyType errorLevel="info" />
|
||||||
|
<InvalidDocblock errorLevel="info" />
|
||||||
|
<MisplacedRequiredParam errorLevel="info" />
|
||||||
|
|
||||||
|
<PropertyNotSetInConstructor errorLevel="info" />
|
||||||
|
<MissingConstructor errorLevel="info" />
|
||||||
|
|
||||||
|
<!-- level 4 issues - points to possible deficiencies in logic, higher false-positives -->
|
||||||
|
|
||||||
|
<MoreSpecificReturnType errorLevel="info" />
|
||||||
|
<TypeCoercion errorLevel="info" />
|
||||||
|
|
||||||
|
<PossiblyNullArgument errorLevel="info" />
|
||||||
|
<PossiblyNullArrayAccess errorLevel="info" />
|
||||||
|
<PossiblyNullOperand errorLevel="info" />
|
||||||
|
<PossiblyNullPropertyAssignment errorLevel="info" />
|
||||||
|
<PossiblyNullPropertyFetch errorLevel="info" />
|
||||||
|
<PossiblyNullReference errorLevel="info" />
|
||||||
|
<PossiblyUndefinedVariable errorLevel="info" />
|
||||||
|
<PossiblyUnusedVariable errorLevel="info" />
|
||||||
|
|
||||||
|
<!-- level 5 issues - should be avoided at mosts costs... -->
|
||||||
|
|
||||||
|
<FailedTypeResolution errorLevel="info" />
|
||||||
|
<ForbiddenCode errorLevel="info" />
|
||||||
|
<ImplicitToStringCast errorLevel="info" />
|
||||||
|
<InvalidScalarArgument errorLevel="info" />
|
||||||
|
<InvalidToString errorLevel="info" />
|
||||||
|
<MethodSignatureMismatch errorLevel="info" />
|
||||||
|
<NoInterfaceProperties errorLevel="info" />
|
||||||
|
<TooManyArguments errorLevel="info" />
|
||||||
|
<TypeDoesNotContainType errorLevel="info" />
|
||||||
|
</issueHandlers>
|
||||||
|
</psalm>
|
103
bin/psalm
103
bin/psalm
@ -20,11 +20,11 @@ ini_set('xdebug.max_nesting_level', 512);
|
|||||||
|
|
||||||
// get options from command line
|
// get options from command line
|
||||||
$options = getopt(
|
$options = getopt(
|
||||||
'f:mhc:',
|
'f:mhc:i',
|
||||||
[
|
[
|
||||||
'help', 'debug', 'config:', 'monochrome', 'show-info:', 'diff',
|
'help', 'debug', 'config:', 'monochrome', 'show-info:', 'diff',
|
||||||
'file:', 'self-check', 'update-docblocks', 'output-format:',
|
'file:', 'self-check', 'update-docblocks', 'output-format:',
|
||||||
'find-dead-code',
|
'find-dead-code', 'init',
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -32,6 +32,10 @@ if (array_key_exists('help', $options)) {
|
|||||||
$options['h'] = false;
|
$options['h'] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (array_key_exists('init', $options)) {
|
||||||
|
$options['i'] = false;
|
||||||
|
}
|
||||||
|
|
||||||
if (array_key_exists('monochrome', $options)) {
|
if (array_key_exists('monochrome', $options)) {
|
||||||
$options['m'] = false;
|
$options['m'] = false;
|
||||||
}
|
}
|
||||||
@ -50,16 +54,39 @@ Usage:
|
|||||||
psalm [options] [file...]
|
psalm [options] [file...]
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
-h, --help Display this help message
|
-h, --help
|
||||||
--debug Debug information
|
Display this help message
|
||||||
-c, --config=psalm.xml Path to a psalm.xml configuration file
|
|
||||||
-m, --monochrome Enable monochrome output
|
-i, --init [source_dir=src] [--level=3]
|
||||||
--show-info[=BOOLEAN] Show non-exception parser findings.
|
Create a psalm config file in the current directory that points to [source_dir]
|
||||||
--diff File to check is a diff
|
at the required level, from 1, most strict, to 5, most permissive
|
||||||
--self-check Psalm checks itself
|
|
||||||
--update-docblocks Adds correct return types to the given file(s)
|
--debug
|
||||||
--output-format=console Changes the output format
|
Debug information
|
||||||
--find-dead-code Look for dead code
|
|
||||||
|
-c, --config=psalm.xml
|
||||||
|
Path to a psalm.xml configuration file. Run psalm --init to create one.
|
||||||
|
|
||||||
|
-m, --monochrome
|
||||||
|
Enable monochrome output
|
||||||
|
|
||||||
|
--show-info[=BOOLEAN]
|
||||||
|
Show non-exception parser findings
|
||||||
|
|
||||||
|
--diff
|
||||||
|
Runs Psalm in diff mode, only checking files that have changed (and their dependents)
|
||||||
|
|
||||||
|
--self-check
|
||||||
|
Psalm checks itself
|
||||||
|
|
||||||
|
--update-docblocks
|
||||||
|
Adds correct return types to the given file(s)
|
||||||
|
|
||||||
|
--output-format=console
|
||||||
|
Changes the output format
|
||||||
|
|
||||||
|
--find-dead-code
|
||||||
|
Look for dead code
|
||||||
|
|
||||||
|
|
||||||
HELP;
|
HELP;
|
||||||
@ -71,6 +98,58 @@ if (getcwd() === false) {
|
|||||||
die('Cannot get current working directory');
|
die('Cannot get current working directory');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isset($options['i'])) {
|
||||||
|
$args = array_slice($argv, 2);
|
||||||
|
|
||||||
|
if (file_exists('psalm.xml')) {
|
||||||
|
die('A config file already exists in the current directory' . PHP_EOL);
|
||||||
|
}
|
||||||
|
|
||||||
|
$level = 3;
|
||||||
|
$source_dir = 'src';
|
||||||
|
|
||||||
|
if (count($args)) {
|
||||||
|
if (count($args) > 2) {
|
||||||
|
die('Too many arguments provided for psalm --init' . PHP_EOL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($args[1])) {
|
||||||
|
if (!preg_match('/^[1-5]$/', $args[1])) {
|
||||||
|
die('Config strictness must be a number between 1 and 5 inclusive' . PHP_EOL);
|
||||||
|
}
|
||||||
|
|
||||||
|
$level = (int)$args[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!file_exists($args[0])) {
|
||||||
|
$bad_dir_path = getcwd() . DIRECTORY_SEPARATOR . $args[0];
|
||||||
|
die('The given path ' . $bad_dir_path . ' does not appear to be a directory' . PHP_EOL);
|
||||||
|
}
|
||||||
|
|
||||||
|
$source_dir = $args[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
$template_file_name = 'assets/config_levels/' . $level . '.xml';
|
||||||
|
|
||||||
|
if (!file_exists($template_file_name)) {
|
||||||
|
die('Could not open config template' . PHP_EOL);
|
||||||
|
}
|
||||||
|
|
||||||
|
$template = (string)file_get_contents($template_file_name);
|
||||||
|
|
||||||
|
$template = str_replace('<projectFiles>
|
||||||
|
<directory name="src" />
|
||||||
|
</projectFiles>', '<projectFiles>
|
||||||
|
<directory name="' . $source_dir . '" />
|
||||||
|
</projectFiles>', $template);
|
||||||
|
|
||||||
|
if (!file_put_contents('psalm.xml', $template)) {
|
||||||
|
die('Could not write to psalm.xml' . PHP_EOL);
|
||||||
|
}
|
||||||
|
|
||||||
|
exit('Config file created successfully. Please re-run psalm.' . PHP_EOL);
|
||||||
|
}
|
||||||
|
|
||||||
// get vars from options
|
// get vars from options
|
||||||
$debug = array_key_exists('debug', $options);
|
$debug = array_key_exists('debug', $options);
|
||||||
|
|
||||||
|
@ -823,6 +823,10 @@ class ProjectChecker
|
|||||||
} while (dirname($dir_path) !== $dir_path);
|
} while (dirname($dir_path) !== $dir_path);
|
||||||
|
|
||||||
if (!$config) {
|
if (!$config) {
|
||||||
|
if ($this->output_format === self::TYPE_CONSOLE) {
|
||||||
|
exit('Could not locate a config XML file in path ' . $path . '. Have you run \'psalm --init\' ?' . PHP_EOL);
|
||||||
|
}
|
||||||
|
|
||||||
throw new Exception\ConfigException('Config not found for path ' . $path);
|
throw new Exception\ConfigException('Config not found for path ' . $path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -858,6 +862,9 @@ class ProjectChecker
|
|||||||
}
|
}
|
||||||
|
|
||||||
$this->config = Config::loadFromXMLFile($path_to_config);
|
$this->config = Config::loadFromXMLFile($path_to_config);
|
||||||
|
|
||||||
|
$this->config->visitStubFiles($this);
|
||||||
|
$this->config->initializePlugins($this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -361,4 +361,15 @@ class ConfigTest extends PHPUnit_Framework_TestCase
|
|||||||
$context = new Context();
|
$context = new Context();
|
||||||
$file_checker->visitAndAnalyzeMethods($context);
|
$file_checker->visitAndAnalyzeMethods($context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testTemplatedFiles()
|
||||||
|
{
|
||||||
|
foreach (['1.xml', '2.xml', '3.xml', '4.xml', '5.xml'] as $file_name) {
|
||||||
|
Config::loadFromXMLFile(realpath(dirname(__DIR__) . '/assets/config_levels/' . $file_name));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user