Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion .ddev/commands/web/mago
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,19 @@ if [[ ${1-} == "analyze" ]]; then
target="${1}"
shift
fi
exec vendor/bin/mago --workspace magento --config mago.toml analyze "${target}" "$@"
# `paths = ["src"]` from mago.toml has no match under the magento workspace,
# which logs a harmless "Failed to walk" warning; symbols come from
# `includes = ["vendor"]`. Log only real errors — findings and the exit code
# are unaffected. Override with e.g. MAGO_LOG=warn when debugging.
export MAGO_LOG="${MAGO_LOG:-error}"
vendor/bin/mago --workspace magento --config mago.toml analyze "${target}" "$@"
# At MAGO_LOG=error mago suppresses its own (stderr) "No issues found" log
# line, so a clean run would be fully silent. Note success on stderr — same
# stream mago logs to — keeping stdout machine-readable (json/github/…).
echo "mago analyze: no issues found." >&2
# set -e aborts above on findings; exit here so a successful analyze does
# not fall through to the plain `mago "$@"` invocation below.
exit 0
fi

vendor/bin/mago "$@"
11 changes: 10 additions & 1 deletion .github/workflows/static-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -207,9 +207,18 @@ jobs:
# graph. Only the module source is analyzed; phtml templates and the
# Magento-idiomatic `mixed-*` codes are filtered via mago.toml. The Mago
# binary and config come from the separate module checkout (its
# require-dev isn't part of the artifact).
# require-dev isn't part of the artifact). mago.toml sets
# `minimum-fail-level = "note"`, so any finding (including warnings and
# help messages) fails this job — green means a completely clean report.
- name: Mago analyze
working-directory: magento2
env:
# `paths = ["src"]` from mago.toml has no match under this workspace
# (module source is analyzed via the vendor copy), which logs a
# harmless "Failed to walk" warning. Log only real errors — findings
# and the exit code are unaffected. Raise to `warn` when debugging
# incomplete-analysis problems (e.g. vendor files that fail to parse).
MAGO_LOG: error
run: |
../mageforge/vendor/bin/mago \
--config ../mageforge/mago.toml \
Expand Down
11 changes: 11 additions & 0 deletions mago.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@ php-version = "8.3"
paths = ["src"]
includes = ["vendor"]
extensions = ["php", "phtml"]
# .trunk contains symlinks into the developer's host cache (~/.cache/trunk)
# that are dangling inside the ddev container and would log walk warnings.
# The astock phpcs-psr2-stock dir ships legacy sniffs with real parse errors.
excludes = [
"**/.trunk/**",
"**/astock/stock-api-libphp/libs/phpcs-psr2-stock/**",
]

[parser]
enable-short-tags = false
Expand All @@ -16,6 +23,10 @@ inline-empty-constructor-braces = false
inline-empty-classlike-braces = false

[analyzer]
# Fail on every reported finding (notes, help, warnings, errors) — not just
# errors. Keeps `ddev mago analyze` and the CI job red until the report is
# completely clean instead of silently passing with warnings.
minimum-fail-level = "note"
# phtml templates rely on variables ($block, $escaper, $secureRenderer, …) that
# Magento's template engine injects into the render scope at runtime. A static
# analyzer cannot know them, so every template would report "undefined variable"
Expand Down
4 changes: 2 additions & 2 deletions src/Console/Command/AbstractCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -209,8 +209,8 @@ protected function isInteractiveTerminal(OutputInterface $output): bool
return false;
}

// Check if STDIN is available
if (!defined('STDIN') || !is_resource(STDIN)) {
// Check if STDIN is available (undefined outside the CLI SAPI)
if (!defined('STDIN')) {
return false;
}

Expand Down
8 changes: 6 additions & 2 deletions src/Console/Command/System/CheckCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ private function getMysqlVersionViaClient(): ?string
}

if ($output !== '') {
$matches = [];
preg_match('/Distrib ([0-9.]+)/', $output, $matches);
return isset($matches[1]) ? $matches[1] : null;
}
Expand Down Expand Up @@ -279,6 +280,7 @@ private function getComposerVersion(): string
return 'Not installed';
}

$matches = [];
preg_match('/Composer version ([^ ]+)/', $output, $matches);
return isset($matches[1]) ? $matches[1] : 'Unknown';
}
Expand Down Expand Up @@ -316,6 +318,7 @@ private function getGitVersion(): string
return 'Not installed';
}

$matches = [];
preg_match('/git version (.+)/', $output, $matches);
return isset($matches[1]) ? $matches[1] : 'Unknown';
}
Expand Down Expand Up @@ -780,8 +783,9 @@ private function getValueFromEnvironmentService($objectManager, string $name): ?
try {
$environmentService = $objectManager->get(\Magento\Framework\App\EnvironmentInterface::class);
$method = 'get' . str_replace(' ', '', ucwords(str_replace('_', ' ', strtolower($name))));
if (is_object($environmentService) && method_exists($environmentService, $method)) {
$value = $environmentService->$method();
$getter = [$environmentService, $method];
if (is_callable($getter)) {
$value = $getter();
if ($value !== null) {
return (string) $value;
}
Expand Down
1 change: 1 addition & 0 deletions src/Console/Command/Theme/BuildCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,7 @@ private function displayBuildSummary(SymfonyStyle $io, array $successList, float
$themeName = $parts[0];
$details = $parts[1];
// Color the builder name in magenta
$matches = [];
if (preg_match('/(using\s+)([^\s]+)(\s+builder)/', $details, $matches)) {
$details = str_replace(
$matches[0],
Expand Down
13 changes: 9 additions & 4 deletions src/Console/Command/Theme/CleanCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@
*/
class CleanCommand extends AbstractCommand
{
/**
* Tracks whether the theme-independent directories were already cleaned in this run.
*
* @var bool
*/
private bool $globalCleaned = false;

/**
* @param ThemeCleaner $themeCleaner
* @param ThemeList $themeList
Expand Down Expand Up @@ -329,17 +336,15 @@ private function displayThemeHeader(string $themeName, int $currentTheme, int $t
*/
private function cleanThemeDirectories(string $themeName, bool $dryRun): int
{
static $globalCleaned = false;

$cleaned = 0;
$cleaned += $this->themeCleaner->cleanViewPreprocessed($themeName, $this->io, $dryRun, true);
$cleaned += $this->themeCleaner->cleanPubStatic($themeName, $this->io, $dryRun, true);

if (!$globalCleaned) {
if (!$this->globalCleaned) {
$cleaned += $this->themeCleaner->cleanPageCache($this->io, $dryRun, true);
$cleaned += $this->themeCleaner->cleanVarTmp($this->io, $dryRun, true);
$cleaned += $this->themeCleaner->cleanGenerated($this->io, $dryRun, true);
$globalCleaned = true;
$this->globalCleaned = true;
}
return $cleaned;
}
Expand Down
2 changes: 1 addition & 1 deletion src/Console/Command/Theme/TokensCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ private function handleOutputFile(string $tailwindPath, string $themePath, strin
*/
private function copyToVarGenerated(string $sourceFilePath, string $themeCode): string
{
$currentDir = getcwd();
$currentDir = getcwd() ?: '.';
$varGeneratedPath = $currentDir . '/var/generated/hyva-token/' . str_replace('/', '/', $themeCode);

if (!$this->fileDriver->isDirectory($varGeneratedPath)) {
Expand Down
12 changes: 9 additions & 3 deletions src/Service/StandardThemeBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@

class StandardThemeBuilder
{
/**
* Tracks whether the global Grunt tasks were already executed in this build process.
*
* @var bool
*/
private bool $gruntTasksRun = false;

/**
* Create a standard theme builder.
*
Expand Down Expand Up @@ -47,13 +54,12 @@ public function build(
$successList[] = "$themeCode: Dependencies checked";

// Run Grunt tasks (only once per build process)
static $gruntTasksRun = false;
if (!$gruntTasksRun) {
if (!$this->gruntTasksRun) {
if (!$this->gruntTaskRunner->runTasks($io, $output, $isVerbose)) {
return false;
}
$successList[] = 'Global: Grunt tasks executed';
$gruntTasksRun = true;
$this->gruntTasksRun = true;
}

// Deploy static content
Expand Down
Loading