77use Magento \Framework \Filesystem \Driver \File ;
88use Magento \Framework \Shell ;
99use OpenForgeProject \MageForge \Service \CacheCleaner ;
10+ use OpenForgeProject \MageForge \Service \NodePackageManager ;
1011use OpenForgeProject \MageForge \Service \StaticContentCleaner ;
1112use OpenForgeProject \MageForge \Service \StaticContentDeployer ;
1213use OpenForgeProject \MageForge \Service \SymlinkCleaner ;
@@ -24,7 +25,8 @@ public function __construct(
2425 private readonly StaticContentDeployer $ staticContentDeployer ,
2526 private readonly StaticContentCleaner $ staticContentCleaner ,
2627 private readonly CacheCleaner $ cacheCleaner ,
27- private readonly SymlinkCleaner $ symlinkCleaner
28+ private readonly SymlinkCleaner $ symlinkCleaner ,
29+ private readonly NodePackageManager $ nodePackageManager
2830 ) {
2931 }
3032
@@ -98,9 +100,16 @@ public function build(string $themeCode, string $themePath, SymfonyStyle $io, Ou
98100
99101 public function autoRepair (string $ themePath , SymfonyStyle $ io , OutputInterface $ output , bool $ isVerbose ): bool
100102 {
101- // Check for node_modules in root
102- if (!$ this ->installNodeModulesIfMissing ($ io , $ isVerbose )) {
103- return false ;
103+ $ rootPath = '. ' ;
104+
105+ // Check if node_modules is in sync with package-lock.json
106+ if (!$ this ->nodePackageManager ->isNodeModulesInSync ($ rootPath )) {
107+ if ($ isVerbose ) {
108+ $ io ->warning ('Node modules out of sync, missing, or no lock file found. Installing... ' );
109+ }
110+ if (!$ this ->nodePackageManager ->installNodeModules ($ rootPath , $ io , $ isVerbose )) {
111+ return false ;
112+ }
104113 }
105114
106115 // Check for grunt
@@ -116,39 +125,7 @@ public function autoRepair(string $themePath, SymfonyStyle $io, OutputInterface
116125 return true ;
117126 }
118127
119- /**
120- * Install Node modules if they're missing
121- */
122- private function installNodeModulesIfMissing (SymfonyStyle $ io , bool $ isVerbose ): bool
123- {
124- if (!$ this ->fileDriver ->isDirectory ('node_modules ' )) {
125- if ($ isVerbose ) {
126- $ io ->warning ('Node modules not found in root directory. Running npm ci... ' );
127- }
128-
129- try {
130- if ($ this ->fileDriver ->isExists ('package-lock.json ' )) {
131- $ this ->shell ->execute ('npm ci --quiet ' );
132- } else {
133- if ($ isVerbose ) {
134- $ io ->warning ('No package-lock.json found, running npm install... ' );
135- }
136- $ this ->shell ->execute ('npm install --quiet ' );
137- }
138-
139- if ($ isVerbose ) {
140- $ io ->success ('Node modules installed successfully. ' );
141- }
142-
143- return true ;
144- } catch (\Exception $ e ) {
145- $ io ->error ('Failed to install node modules: ' . $ e ->getMessage ());
146- return false ;
147- }
148- }
149128
150- return true ;
151- }
152129
153130 /**
154131 * Install Grunt if it's missing
@@ -209,11 +186,6 @@ public function watch(string $themeCode, string $themePath, SymfonyStyle $io, Ou
209186 return false ;
210187 }
211188
212- // Check for node_modules in root
213- if (!$ this ->installNodeModulesIfMissing ($ io , $ isVerbose )) {
214- return false ;
215- }
216-
217189 try {
218190 if ($ isVerbose ) {
219191 $ io ->text ('Starting watch mode with verbose output... ' );
0 commit comments