Skip to content

Commit 623b29a

Browse files
Copilotdermatz
andcommitted
Add mageforge:static:clean command implementation
Co-authored-by: dermatz <6103201+dermatz@users.noreply.github.com>
1 parent 4a2676a commit 623b29a

2 files changed

Lines changed: 197 additions & 0 deletions

File tree

Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace OpenForgeProject\MageForge\Console\Command\Static;
6+
7+
use Magento\Framework\App\Filesystem\DirectoryList;
8+
use Magento\Framework\Console\Cli;
9+
use Magento\Framework\Filesystem;
10+
use Magento\Framework\Filesystem\Directory\WriteInterface;
11+
use OpenForgeProject\MageForge\Console\Command\AbstractCommand;
12+
use OpenForgeProject\MageForge\Model\ThemeList;
13+
use OpenForgeProject\MageForge\Model\ThemePath;
14+
use Symfony\Component\Console\Input\InputArgument;
15+
use Symfony\Component\Console\Input\InputInterface;
16+
use Symfony\Component\Console\Output\OutputInterface;
17+
18+
/**
19+
* Command for cleaning static files and preprocessed view files for specific themes
20+
*/
21+
class CleanCommand extends AbstractCommand
22+
{
23+
/**
24+
* @param Filesystem $filesystem
25+
* @param ThemeList $themeList
26+
* @param ThemePath $themePath
27+
*/
28+
public function __construct(
29+
private readonly Filesystem $filesystem,
30+
private readonly ThemeList $themeList,
31+
private readonly ThemePath $themePath
32+
) {
33+
parent::__construct();
34+
}
35+
36+
/**
37+
* {@inheritdoc}
38+
*/
39+
protected function configure(): void
40+
{
41+
$this->setName($this->getCommandName('static', 'clean'))
42+
->setDescription('Clean var/view_preprocessed and pub/static directories for specific theme')
43+
->addArgument(
44+
'themename',
45+
InputArgument::OPTIONAL,
46+
'Theme code to clean (format: Vendor/theme)'
47+
);
48+
}
49+
50+
/**
51+
* {@inheritdoc}
52+
*/
53+
protected function executeCommand(InputInterface $input, OutputInterface $output): int
54+
{
55+
$themeName = $input->getArgument('themename');
56+
57+
// If no theme specified, show available themes
58+
if (empty($themeName)) {
59+
$this->io->warning('No theme specified. Available themes:');
60+
$themes = $this->themeList->getAllThemes();
61+
62+
if (empty($themes)) {
63+
$this->io->info('No themes found.');
64+
return Cli::RETURN_SUCCESS;
65+
}
66+
67+
foreach ($themes as $theme) {
68+
$this->io->writeln(sprintf(' - <fg=cyan>%s</> (%s)', $theme->getCode(), $theme->getThemeTitle()));
69+
}
70+
71+
$this->io->newLine();
72+
$this->io->info('Usage: bin/magento mageforge:static:clean <theme-code>');
73+
$this->io->info('Example: bin/magento mageforge:static:clean Magento/luma');
74+
75+
return Cli::RETURN_SUCCESS;
76+
}
77+
78+
// Validate theme exists
79+
$themePath = $this->themePath->getPath($themeName);
80+
if ($themePath === null) {
81+
$this->io->error(sprintf("Theme '%s' not found.", $themeName));
82+
return Cli::RETURN_FAILURE;
83+
}
84+
85+
$this->io->section(sprintf("Cleaning static files for theme: %s", $themeName));
86+
87+
$cleaned = 0;
88+
89+
// Clean var/view_preprocessed
90+
$cleaned += $this->cleanViewPreprocessed($themeName);
91+
92+
// Clean pub/static
93+
$cleaned += $this->cleanPubStatic($themeName);
94+
95+
if ($cleaned > 0) {
96+
$this->io->success(sprintf(
97+
"Successfully cleaned %d director%s for theme '%s'",
98+
$cleaned,
99+
$cleaned === 1 ? 'y' : 'ies',
100+
$themeName
101+
));
102+
} else {
103+
$this->io->info(sprintf("No files to clean for theme '%s'", $themeName));
104+
}
105+
106+
return Cli::RETURN_SUCCESS;
107+
}
108+
109+
/**
110+
* Clean var/view_preprocessed directory for the theme
111+
*
112+
* @param string $themeName
113+
* @return int Number of directories cleaned
114+
*/
115+
private function cleanViewPreprocessed(string $themeName): int
116+
{
117+
$cleaned = 0;
118+
$varDirectory = $this->filesystem->getDirectoryWrite(DirectoryList::VAR_DIR);
119+
120+
// Extract vendor and theme parts
121+
$themeParts = explode('/', $themeName);
122+
if (count($themeParts) !== 2) {
123+
return 0;
124+
}
125+
126+
[$vendor, $theme] = $themeParts;
127+
128+
// Check if view_preprocessed directory exists
129+
if (!$varDirectory->isDirectory('view_preprocessed')) {
130+
return 0;
131+
}
132+
133+
// Pattern: view_preprocessed/css/frontend/Vendor/theme
134+
// and view_preprocessed/source/frontend/Vendor/theme
135+
$pathsToClean = [
136+
sprintf('view_preprocessed/css/frontend/%s/%s', $vendor, $theme),
137+
sprintf('view_preprocessed/source/frontend/%s/%s', $vendor, $theme),
138+
];
139+
140+
foreach ($pathsToClean as $path) {
141+
if ($varDirectory->isDirectory($path)) {
142+
try {
143+
$varDirectory->delete($path);
144+
$this->io->writeln(sprintf(' <fg=green>✓</> Cleaned: var/%s', $path));
145+
$cleaned++;
146+
} catch (\Exception $e) {
147+
$this->io->writeln(sprintf(' <fg=red>✗</> Failed to clean: var/%s - %s', $path, $e->getMessage()));
148+
}
149+
}
150+
}
151+
152+
return $cleaned;
153+
}
154+
155+
/**
156+
* Clean pub/static directory for the theme
157+
*
158+
* @param string $themeName
159+
* @return int Number of directories cleaned
160+
*/
161+
private function cleanPubStatic(string $themeName): int
162+
{
163+
$cleaned = 0;
164+
$staticDirectory = $this->filesystem->getDirectoryWrite(DirectoryList::STATIC_VIEW);
165+
166+
// Extract vendor and theme parts
167+
$themeParts = explode('/', $themeName);
168+
if (count($themeParts) !== 2) {
169+
return 0;
170+
}
171+
172+
[$vendor, $theme] = $themeParts;
173+
174+
// Check if frontend directory exists in pub/static
175+
if (!$staticDirectory->isDirectory('frontend')) {
176+
return 0;
177+
}
178+
179+
// Pattern: frontend/Vendor/theme
180+
$pathToClean = sprintf('frontend/%s/%s', $vendor, $theme);
181+
182+
if ($staticDirectory->isDirectory($pathToClean)) {
183+
try {
184+
$staticDirectory->delete($pathToClean);
185+
$this->io->writeln(sprintf(' <fg=green>✓</> Cleaned: pub/static/%s', $pathToClean));
186+
$cleaned++;
187+
} catch (\Exception $e) {
188+
$this->io->writeln(sprintf(' <fg=red>✗</> Failed to clean: pub/static/%s - %s', $pathToClean, $e->getMessage()));
189+
}
190+
}
191+
192+
return $cleaned;
193+
}
194+
}

src/etc/di.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@
2424
<item name="mageforge_theme_watch"
2525
xsi:type="object"
2626
>OpenForgeProject\MageForge\Console\Command\Theme\WatchCommand</item>
27+
<item name="mageforge_static_clean"
28+
xsi:type="object"
29+
>OpenForgeProject\MageForge\Console\Command\Static\CleanCommand</item>
2730
</argument>
2831
</arguments>
2932
</type>

0 commit comments

Comments
 (0)