mirror of
https://github.com/getgrav/grav.git
synced 2026-03-01 01:51:29 +01:00
impoved yaml linter to be more use built-in grav for more detail
Signed-off-by: Andy Miller <rhuk@mac.com>
This commit is contained in:
@@ -15,6 +15,7 @@ use Grav\Common\Utils;
|
||||
use RecursiveDirectoryIterator;
|
||||
use RecursiveIteratorIterator;
|
||||
use RegexIterator;
|
||||
use RocketTheme\Toolbox\Compat\Yaml\Yaml as CompatYaml;
|
||||
use RocketTheme\Toolbox\File\MarkdownFile;
|
||||
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
|
||||
use Symfony\Component\Yaml\Yaml;
|
||||
@@ -30,18 +31,19 @@ class YamlLinter
|
||||
* @param callable|null $callback Optional callback for progress: function(string $file, bool $success, ?string $error)
|
||||
* @return array
|
||||
*/
|
||||
public static function lint(?string $folder = null, ?callable $callback = null)
|
||||
public static function lint(?string $folder = null, ?callable $callback = null, bool $strict = false)
|
||||
{
|
||||
if (null !== $folder) {
|
||||
$folder = $folder ?: GRAV_ROOT;
|
||||
|
||||
return static::recurseFolder($folder, '(md|yaml)', $callback);
|
||||
return static::recurseFolder($folder, '(md|yaml)', $callback, $strict);
|
||||
}
|
||||
|
||||
return array_merge(
|
||||
static::lintConfig($callback),
|
||||
static::lintPages($callback),
|
||||
static::lintBlueprints($callback)
|
||||
static::lintConfig($callback, $strict),
|
||||
static::lintPages($callback, $strict),
|
||||
static::lintBlueprints($callback, $strict),
|
||||
static::lintEnvironments($callback, $strict)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -49,25 +51,58 @@ class YamlLinter
|
||||
* @param callable|null $callback Optional callback for progress: function(string $file, bool $success, ?string $error)
|
||||
* @return array
|
||||
*/
|
||||
public static function lintPages(?callable $callback = null)
|
||||
public static function lintPages(?callable $callback = null, bool $strict = false)
|
||||
{
|
||||
return static::recurseFolder('page://', '(md|yaml)', $callback);
|
||||
return static::recurseFolder('page://', '(md|yaml)', $callback, $strict);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param callable|null $callback Optional callback for progress: function(string $file, bool $success, ?string $error)
|
||||
* @param bool $strict Use the stricter Compat YAML parser (matches runtime behavior)
|
||||
* @return array
|
||||
*/
|
||||
public static function lintConfig(?callable $callback = null)
|
||||
public static function lintConfig(?callable $callback = null, bool $strict = false)
|
||||
{
|
||||
return static::recurseFolder('config://', '(md|yaml)', $callback);
|
||||
return static::recurseFolder('config://', '(md|yaml)', $callback, $strict);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param callable|null $callback Optional callback for progress: function(string $file, bool $success, ?string $error)
|
||||
* @param bool $strict Use the stricter Compat YAML parser (matches runtime behavior)
|
||||
* @return array
|
||||
*/
|
||||
public static function lintBlueprints(?callable $callback = null)
|
||||
public static function lintEnvironments(?callable $callback = null, bool $strict = false)
|
||||
{
|
||||
$lint_errors = [];
|
||||
$user_path = GRAV_ROOT . '/' . GRAV_USER_PATH;
|
||||
|
||||
// Scan Grav 1.6 style: user/<hostname>/config/
|
||||
foreach (glob($user_path . '/*/config', GLOB_ONLYDIR) as $envConfigDir) {
|
||||
$envName = basename(dirname($envConfigDir));
|
||||
// Skip known non-environment directories
|
||||
if (in_array($envName, ['config', 'plugins', 'themes', 'pages', 'accounts', 'data', 'assets'])) {
|
||||
continue;
|
||||
}
|
||||
$lint_errors = array_merge($lint_errors, static::recurseFolder($envConfigDir, '(md|yaml)', $callback, $strict));
|
||||
}
|
||||
|
||||
// Scan Grav 1.7+ style: user/env/<hostname>/config/
|
||||
$envPath = $user_path . '/env';
|
||||
if (is_dir($envPath)) {
|
||||
foreach (glob($envPath . '/*/config', GLOB_ONLYDIR) as $envConfigDir) {
|
||||
$lint_errors = array_merge($lint_errors, static::recurseFolder($envConfigDir, '(md|yaml)', $callback, $strict));
|
||||
}
|
||||
}
|
||||
|
||||
return $lint_errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param callable|null $callback Optional callback for progress: function(string $file, bool $success, ?string $error)
|
||||
* @param bool $strict Use the stricter Compat YAML parser (matches runtime behavior)
|
||||
* @return array
|
||||
*/
|
||||
public static function lintBlueprints(?callable $callback = null, bool $strict = false)
|
||||
{
|
||||
/** @var UniformResourceLocator $locator */
|
||||
$locator = Grav::instance()['locator'];
|
||||
@@ -76,7 +111,7 @@ class YamlLinter
|
||||
$theme_path = 'themes://' . $current_theme . '/blueprints';
|
||||
|
||||
$locator->addPath('blueprints', '', [$theme_path]);
|
||||
return static::recurseFolder('blueprints://', '(md|yaml)', $callback);
|
||||
return static::recurseFolder('blueprints://', '(md|yaml)', $callback, $strict);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -85,7 +120,7 @@ class YamlLinter
|
||||
* @param callable|null $callback Optional callback for progress: function(string $file, bool $success, ?string $error)
|
||||
* @return array
|
||||
*/
|
||||
public static function recurseFolder($path, $extensions = '(md|yaml)', ?callable $callback = null)
|
||||
public static function recurseFolder($path, $extensions = '(md|yaml)', ?callable $callback = null, bool $strict = false)
|
||||
{
|
||||
$lint_errors = [];
|
||||
|
||||
@@ -104,7 +139,12 @@ class YamlLinter
|
||||
foreach ($iterator as $filepath => $file) {
|
||||
$relativePath = str_replace(GRAV_ROOT, '', $filepath);
|
||||
try {
|
||||
Yaml::parse(static::extractYaml($filepath));
|
||||
$yaml = static::extractYaml($filepath);
|
||||
if ($strict) {
|
||||
CompatYaml::parse($yaml);
|
||||
} else {
|
||||
Yaml::parse($yaml);
|
||||
}
|
||||
if ($callback) {
|
||||
$callback($relativePath, true, null);
|
||||
}
|
||||
|
||||
@@ -39,6 +39,12 @@ class YamlLinterCommand extends GravCommand
|
||||
InputOption::VALUE_OPTIONAL,
|
||||
'Go through specific folder'
|
||||
)
|
||||
->addOption(
|
||||
'strict',
|
||||
's',
|
||||
InputOption::VALUE_NONE,
|
||||
'Use the stricter Compat YAML parser that matches runtime behavior'
|
||||
)
|
||||
->setDescription('Checks various files for YAML errors')
|
||||
->setHelp('Checks various files for YAML errors');
|
||||
}
|
||||
@@ -54,6 +60,7 @@ class YamlLinterCommand extends GravCommand
|
||||
$io->title('Yaml Linter');
|
||||
|
||||
$verbose = $io->isVerbose();
|
||||
$strict = (bool) $input->getOption('strict');
|
||||
$checked = 0;
|
||||
$callback = $verbose ? function (string $file, bool $success, ?string $error) use ($io, &$checked) {
|
||||
$checked++;
|
||||
@@ -64,10 +71,14 @@ class YamlLinterCommand extends GravCommand
|
||||
}
|
||||
} : null;
|
||||
|
||||
if ($strict) {
|
||||
$io->note('Using strict Compat YAML parser (matches runtime behavior)');
|
||||
}
|
||||
|
||||
$error = 0;
|
||||
if ($input->getOption('all')) {
|
||||
$io->section('All');
|
||||
$errors = YamlLinter::lint('', $callback);
|
||||
$errors = YamlLinter::lint('', $callback, $strict);
|
||||
|
||||
$this->displayResult($errors, $io, 'No YAML Linting issues found', $verbose, $checked);
|
||||
if (!empty($errors)) {
|
||||
@@ -75,7 +86,7 @@ class YamlLinterCommand extends GravCommand
|
||||
}
|
||||
} elseif ($folder = $input->getOption('folder')) {
|
||||
$io->section($folder);
|
||||
$errors = YamlLinter::lint($folder, $callback);
|
||||
$errors = YamlLinter::lint($folder, $callback, $strict);
|
||||
|
||||
$this->displayResult($errors, $io, 'No YAML Linting issues found', $verbose, $checked);
|
||||
if (!empty($errors)) {
|
||||
@@ -84,7 +95,7 @@ class YamlLinterCommand extends GravCommand
|
||||
} else {
|
||||
$io->section('User Configuration');
|
||||
$checked = 0;
|
||||
$errors = YamlLinter::lintConfig($callback);
|
||||
$errors = YamlLinter::lintConfig($callback, $strict);
|
||||
|
||||
$this->displayResult($errors, $io, 'No YAML Linting issues with configuration', $verbose, $checked);
|
||||
if (!empty($errors)) {
|
||||
@@ -93,7 +104,7 @@ class YamlLinterCommand extends GravCommand
|
||||
|
||||
$io->section('Pages Frontmatter');
|
||||
$checked = 0;
|
||||
$errors = YamlLinter::lintPages($callback);
|
||||
$errors = YamlLinter::lintPages($callback, $strict);
|
||||
|
||||
$this->displayResult($errors, $io, 'No YAML Linting issues with pages', $verbose, $checked);
|
||||
if (!empty($errors)) {
|
||||
@@ -102,12 +113,21 @@ class YamlLinterCommand extends GravCommand
|
||||
|
||||
$io->section('Page Blueprints');
|
||||
$checked = 0;
|
||||
$errors = YamlLinter::lintBlueprints($callback);
|
||||
$errors = YamlLinter::lintBlueprints($callback, $strict);
|
||||
|
||||
$this->displayResult($errors, $io, 'No YAML Linting issues with blueprints', $verbose, $checked);
|
||||
if (!empty($errors)) {
|
||||
$error = 1;
|
||||
}
|
||||
|
||||
$io->section('Environment Configuration');
|
||||
$checked = 0;
|
||||
$errors = YamlLinter::lintEnvironments($callback, $strict);
|
||||
|
||||
$this->displayResult($errors, $io, 'No YAML Linting issues with environment configs', $verbose, $checked);
|
||||
if (!empty($errors)) {
|
||||
$error = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return $error;
|
||||
|
||||
Reference in New Issue
Block a user