Files
rspade_system/app/RSpade/CodeQuality/Rules/Common/ResourceDirectory_CodeQualityRule.php
root 29c657f7a7 Exclude tests directory from framework publish
Add 100+ automated unit tests from .expect file specifications
Add session system test
Add rsx:constants:regenerate command test
Add rsx:logrotate command test
Add rsx:clean command test
Add rsx:manifest:stats command test
Add model enum system test
Add model mass assignment prevention test
Add rsx:check command test
Add migrate:status command test

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-25 03:59:58 +00:00

134 lines
4.5 KiB
PHP

<?php
namespace App\RSpade\CodeQuality\Rules\Common;
use App\RSpade\CodeQuality\Rules\CodeQualityRule_Abstract;
/**
* Rule to detect incorrect 'resources' directory naming
* Should be 'resource' (singular) not 'resources' (plural)
*/
class ResourceDirectory_CodeQualityRule extends CodeQualityRule_Abstract
{
protected static $checked_directories = [];
public function get_id(): string
{
return 'DIR-RESOURCE-01';
}
public function get_name(): string
{
return 'Resource Directory Naming';
}
public function get_description(): string
{
return 'Enforces singular "resource" directory naming convention';
}
public function get_file_patterns(): array
{
// Check all files to extract directory paths
return ['*'];
}
public function get_default_severity(): string
{
return 'high';
}
/**
* Check for 'resources' directory in file path
*/
public function check(string $file_path, string $contents, array $metadata = []): void
{
// Skip directories outside our scan paths
if (!str_contains($file_path, '/rsx/') && !str_contains($file_path, '/app/RSpade/')) {
return;
}
// If in app/RSpade, check if it's in an allowed subdirectory
if (str_contains($file_path, '/app/RSpade/') && !$this->is_in_allowed_rspade_directory($file_path)) {
return;
}
// Skip vendor and node_modules
if (str_contains($file_path, '/vendor/') || str_contains($file_path, '/node_modules/')) {
return;
}
// Skip if already inside a 'resource' directory (contents are invisible to framework)
if (preg_match('#/resource/#', $file_path)) {
return;
}
// Check if path contains 'resources' directory
if (preg_match('#/resources/#', $file_path, $matches, PREG_OFFSET_CAPTURE)) {
// Extract the directory path up to and including 'resources'
$offset = $matches[0][1];
$dir_path = substr($file_path, 0, $offset + strlen('/resources'));
// Only report once per directory
if (isset(static::$checked_directories[$dir_path])) {
return;
}
static::$checked_directories[$dir_path] = true;
$this->add_violation(
$file_path,
1,
"Directory named 'resources' (plural) detected - should be 'resource' (singular)",
"Directory: {$dir_path}/",
"The directory name 'resources' is not allowed in RSX.\n\n" .
"USE 'resource' INSTEAD (singular, not plural).\n\n" .
"WHY THIS MATTERS:\n" .
"'resource' is a special directory that is IGNORED by:\n" .
"- The RSpade manifest system\n" .
"- The autoloader\n" .
"- Bundle generation\n" .
"- All Manifest.php functions\n\n" .
"PURPOSE OF resource/ DIRECTORY:\n" .
"Store special-purpose files that are referenced but not executed:\n" .
"- Raw source code (e.g., Bootstrap 5 source)\n" .
"- Supplemental utilities (e.g., Node.js applications)\n" .
"- Documentation files\n" .
"- Assets that should not be bundled\n\n" .
"ACTION REQUIRED:\n" .
"Rename the directory from 'resources' to 'resource'",
'high'
);
}
}
/**
* Check if a file in /app/RSpade/ is in an allowed subdirectory
* Based on scan_directories configuration
*/
private function is_in_allowed_rspade_directory(string $file_path): bool
{
// Get allowed subdirectories from config
$scan_directories = config('rsx.manifest.scan_directories', []);
// Extract allowed RSpade subdirectories
$allowed_subdirs = [];
foreach ($scan_directories as $scan_dir) {
if (str_starts_with($scan_dir, 'app/RSpade/')) {
$subdir = substr($scan_dir, strlen('app/RSpade/'));
if ($subdir) {
$allowed_subdirs[] = $subdir;
}
}
}
// Check if file is in any allowed subdirectory
foreach ($allowed_subdirs as $subdir) {
if (str_contains($file_path, '/app/RSpade/' . $subdir . '/') ||
str_contains($file_path, '/app/RSpade/' . $subdir)) {
return true;
}
}
return false;
}
}