@@ -37,21 +37,61 @@ object ComposerUtil {
3737 processHandler.waitFor()
3838
3939 if (processHandler.exitCode == 0 && output.isNotEmpty()) {
40- composerGlobalDir = output.toString()
40+ // Clean up the output - remove any extra whitespace or newlines
41+ composerGlobalDir = output.toString().trim()
42+ LOG .debug(" Found composer global directory: $composerGlobalDir " )
4143 return composerGlobalDir
44+ } else {
45+ LOG .warn(" Composer command exited with code ${processHandler.exitCode} or empty output" )
4246 }
4347 } catch (e: Exception ) {
4448 LOG .error(" Failed to get composer global directory: ${e.message} " , e)
4549 }
50+
51+ // Fallback to default locations if composer command fails
52+ val userHome = System .getProperty(" user.home" )
53+ val possibleLocations = listOf (
54+ " $userHome /.composer" , // Linux/Mac
55+ " $userHome /AppData/Roaming/Composer" // Windows
56+ )
57+
58+ for (location in possibleLocations) {
59+ val dir = java.io.File (location)
60+ if (dir.exists() && dir.isDirectory) {
61+ LOG .debug(" Using fallback composer global directory: $location " )
62+ composerGlobalDir = location
63+ return composerGlobalDir
64+ }
65+ }
66+
67+ LOG .warn(" Could not determine composer global directory" )
4668 return null
4769 }
4870
4971 fun getPhpcsPath (): String? {
50- return getComposerGlobalDir()?.let { " $it /vendor/bin/phpcs" }
72+ return getComposerGlobalDir()?.let {
73+ val path = java.io.File (it, " vendor/bin/phpcs" )
74+ if (System .getProperty(" os.name" ).lowercase().contains(" windows" )) {
75+ // On Windows, the executable might have a .bat extension
76+ if (java.io.File (" ${path} .bat" ).exists()) {
77+ return @let " ${path} .bat"
78+ }
79+ }
80+ path.absolutePath
81+ }
5182 }
5283
5384 fun getPhpcbfPath (): String? {
54- return getComposerGlobalDir()?.let { " $it /vendor/bin/phpcbf" }
85+ return getComposerGlobalDir()?.let {
86+ val path = java.io.File (it, " vendor/bin/phpcbf" )
87+ if (System .getProperty(" os.name" ).lowercase().contains(" windows" )) {
88+ // On Windows, the executable might have a .bat extension
89+ if (java.io.File (" ${path} .bat" ).exists()) {
90+ return @let " ${path} .bat"
91+ }
92+ }
93+ path.absolutePath
94+ }
5595 }
5696
5797 fun runComposerInstall (project : Project , directory : String ): Boolean {
@@ -90,20 +130,82 @@ object ComposerUtil {
90130 }
91131
92132 fun setupMoodleCs (project : Project ): Boolean {
133+ LOG .debug(" Setting up Moodle CS..." )
134+
135+ // First check if phpcs and phpcbf already exist
136+ val phpcsPath = getPhpcsPath()
137+ val phpcbfPath = getPhpcbfPath()
138+
139+ if (phpcsPath != null && phpcbfPath != null ) {
140+ val phpcsFile = java.io.File (phpcsPath)
141+ val phpcbfFile = java.io.File (phpcbfPath)
142+
143+ if (phpcsFile.exists() && phpcbfFile.exists()) {
144+ LOG .debug(" PHPCS and PHPCBF already exist, checking if moodle standard is available" )
145+
146+ // Check if moodle standard is available
147+ try {
148+ val commandLine = GeneralCommandLine (phpcsPath)
149+ commandLine.addParameters(listOf (" -i" ))
150+
151+ val output = StringBuilder ()
152+ val processHandler = OSProcessHandler (commandLine)
153+ processHandler.addProcessListener(object : ProcessAdapter () {
154+ override fun onTextAvailable (event : ProcessEvent , outputType : Key <* >) {
155+ output.append(event.text)
156+ }
157+ })
158+
159+ processHandler.startNotify()
160+ processHandler.waitFor()
161+
162+ if (processHandler.exitCode == 0 && output.toString().lowercase().contains(" moodle" )) {
163+ LOG .debug(" Moodle standard is already available" )
164+ return true
165+ }
166+ } catch (e: Exception ) {
167+ LOG .warn(" Failed to check if moodle standard is available: ${e.message} " )
168+ // Continue with setup
169+ }
170+ }
171+ }
172+
93173 try {
94174 // Set minimum-stability to dev
175+ LOG .debug(" Setting composer minimum-stability to dev" )
95176 if (! executeComposerCommand(project, listOf (" global" , " config" , " minimum-stability" , " dev" ))) {
96- LOG .error(" Failed to set composer minimum-stability to dev" )
97- return false
177+ LOG .warn(" Failed to set composer minimum-stability to dev, but continuing with installation" )
98178 }
99179
100180 // Install moodlehq/moodle-cs
181+ LOG .debug(" Installing moodlehq/moodle-cs" )
101182 if (! executeComposerCommand(project, listOf (" global" , " require" , " moodlehq/moodle-cs" ))) {
102183 LOG .error(" Failed to install moodlehq/moodle-cs" )
103- return false
184+
185+ // Try alternative approach - install with --dev flag
186+ LOG .debug(" Trying alternative approach with --dev flag" )
187+ if (! executeComposerCommand(project, listOf (" global" , " require" , " --dev" , " moodlehq/moodle-cs" ))) {
188+ LOG .error(" Failed to install moodlehq/moodle-cs with --dev flag" )
189+ return false
190+ }
104191 }
105192
106- return true
193+ // Verify installation
194+ val newPhpcsPath = getPhpcsPath()
195+ val newPhpcbfPath = getPhpcbfPath()
196+
197+ if (newPhpcsPath != null && newPhpcbfPath != null ) {
198+ val newPhpcsFile = java.io.File (newPhpcsPath)
199+ val newPhpcbfFile = java.io.File (newPhpcbfPath)
200+
201+ if (newPhpcsFile.exists() && newPhpcbfFile.exists()) {
202+ LOG .debug(" Successfully installed PHPCS and PHPCBF" )
203+ return true
204+ }
205+ }
206+
207+ LOG .warn(" PHPCS or PHPCBF not found after installation" )
208+ return false
107209 } catch (e: Exception ) {
108210 LOG .error(" Error setting up Moodle CS: ${e.message} " , e)
109211 return false
0 commit comments