1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-30 04:39:00 +01:00

Add config creation utility

This commit is contained in:
Matthew Brown 2017-02-12 23:59:33 -05:00
parent 500044dac1
commit 0277ca49ba
8 changed files with 248 additions and 12 deletions

View 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>

View 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>

View 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>

View 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>

View 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
View File

@ -20,11 +20,11 @@ ini_set('xdebug.max_nesting_level', 512);
// get options from command line
$options = getopt(
'f:mhc:',
'f:mhc:i',
[
'help', 'debug', 'config:', 'monochrome', 'show-info:', 'diff',
'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;
}
if (array_key_exists('init', $options)) {
$options['i'] = false;
}
if (array_key_exists('monochrome', $options)) {
$options['m'] = false;
}
@ -50,16 +54,39 @@ Usage:
psalm [options] [file...]
Options:
-h, --help Display this help message
--debug Debug information
-c, --config=psalm.xml Path to a psalm.xml configuration file
-m, --monochrome Enable monochrome output
--show-info[=BOOLEAN] Show non-exception parser findings.
--diff File to check is a diff
--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
-h, --help
Display this help message
-i, --init [source_dir=src] [--level=3]
Create a psalm config file in the current directory that points to [source_dir]
at the required level, from 1, most strict, to 5, most permissive
--debug
Debug information
-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;
@ -71,6 +98,58 @@ if (getcwd() === false) {
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
$debug = array_key_exists('debug', $options);

View File

@ -823,6 +823,10 @@ class ProjectChecker
} while (dirname($dir_path) !== $dir_path);
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);
}
@ -858,6 +862,9 @@ class ProjectChecker
}
$this->config = Config::loadFromXMLFile($path_to_config);
$this->config->visitStubFiles($this);
$this->config->initializePlugins($this);
}
/**

View File

@ -361,4 +361,15 @@ class ConfigTest extends PHPUnit_Framework_TestCase
$context = new 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));
}
}
}