@@ -47,101 +47,47 @@ class PullModel extends \JModelDatabase
4747 );
4848
4949 /**
50- * Method to parse a patch and extract the affected files
50+ * Parse the list of modified files from a pull request
5151 *
52- * @param string $patch Patch file to parse
52+ * @param object $files The modified files to parse
5353 *
54- * @return array Array of files within a patch
54+ * @return array
5555 *
56- * @since 2.0
56+ * @since __DEPLOY_VERSION__
5757 */
58- protected function parsePatch ( $ patch )
58+ protected function parseFileList ( $ files )
5959 {
60- $ state = 0 ;
61- $ files = array ();
60+ $ parsedFiles = array ();
6261
63- $ lines = explode ("\n" , $ patch );
64-
65- foreach ($ lines as $ line )
62+ foreach ($ files as $ file )
6663 {
67- switch ($ state )
64+ /*
65+ * Check if the patch tester is running in a production environment
66+ * If so, do not patch certain files as errors will be thrown
67+ */
68+ if (!file_exists (JPATH_ROOT . '/installation/index.php ' ))
6869 {
69- case 0 :
70- if (strpos ($ line , 'diff --git ' ) === 0 )
71- {
72- $ state = 1 ;
73- }
74-
75- $ file = new \stdClass ;
76- $ file ->action = 'modified ' ;
77-
78- break ;
79-
80- case 1 :
81- if (strpos ($ line , 'index ' ) === 0 )
82- {
83- $ file ->index = substr ($ line , 6 );
84- }
85-
86- if (strpos ($ line , '--- ' ) === 0 )
87- {
88- $ file ->old = substr ($ line , 6 );
89- }
90-
91- if (strpos ($ line , '+++ ' ) === 0 )
92- {
93- $ file ->new = substr ($ line , 6 );
94- }
95-
96- if (strpos ($ line , 'new file mode ' ) === 0 )
97- {
98- $ file ->action = 'added ' ;
99- }
100-
101- if (strpos ($ line , 'deleted file mode ' ) === 0 )
102- {
103- $ file ->action = 'deleted ' ;
104- }
105-
106- // Binary files are presently unsupported, use this to reset the parser in the meantime
107- if (strpos ($ line , 'Binary files ' ) === 0 )
108- {
109- $ state = 0 ;
110-
111- $ this ->state ->set ('pull.has_binary ' , true );
112- }
113-
114- if (strpos ($ line , '@@ ' ) === 0 )
115- {
116- $ state = 0 ;
70+ $ filePath = explode ('/ ' , $ file ->filename );
11771
118- /*
119- * Check if the patch tester is running in a production environment
120- * If so, do not patch certain files as errors will be thrown
121- */
122- if (!file_exists (JPATH_ROOT . '/installation/index.php ' ))
123- {
124- $ filePath = explode ('/ ' , $ file ->new );
125-
126- if (in_array ($ filePath [0 ], $ this ->nonProductionFiles ))
127- {
128- continue ;
129- }
130-
131- if (in_array ($ filePath [0 ], $ this ->nonProductionFolders ))
132- {
133- continue ;
134- }
135- }
136-
137- $ files [] = $ file ;
138- }
72+ if (in_array ($ filePath [0 ], $ this ->nonProductionFiles ))
73+ {
74+ continue ;
75+ }
13976
140- break ;
77+ if (in_array ($ filePath [0 ], $ this ->nonProductionFolders ))
78+ {
79+ continue ;
80+ }
14181 }
82+
83+ $ parsedFiles [] = (object ) array (
84+ 'action ' => $ file ->status ,
85+ 'filename ' => $ file ->filename ,
86+ 'fileurl ' => $ file ->contents_url ,
87+ );
14288 }
14389
144- return $ files ;
90+ return $ parsedFiles ;
14591 }
14692
14793 /**
@@ -194,49 +140,62 @@ public function apply($id)
194140
195141 try
196142 {
197- $ patchResponse = $ github ->getDiffForPullRequest ($ this ->getState ()->get ('github_user ' ), $ this ->getState ()->get ('github_repo ' ), $ id );
198- $ patch = json_decode ($ patchResponse ->body );
143+ $ filesResponse = $ github ->getFilesForPullRequest ($ this ->getState ()->get ('github_user ' ), $ this ->getState ()->get ('github_repo ' ), $ id );
144+ $ files = json_decode ($ filesResponse ->body );
199145 }
200146 catch (UnexpectedResponse $ e )
201147 {
202148 throw new \RuntimeException (\JText::sprintf ('COM_PATCHTESTER_COULD_NOT_CONNECT_TO_GITHUB ' , $ e ->getMessage ()), $ e ->getCode (), $ e );
203149 }
204150
205- $ files = $ this ->parsePatch ($ patch );
206-
207- if (!$ files )
151+ if (!count ($ files ))
208152 {
209153 return false ;
210154 }
211155
212- foreach ($ files as $ file )
156+ $ parsedFiles = $ this ->parseFileList ($ files );
157+
158+ foreach ($ parsedFiles as $ file )
213159 {
214- if ($ file ->action == 'deleted ' && !file_exists (JPATH_ROOT . '/ ' . $ file ->old ))
160+ if ($ file ->action == 'deleted ' && !file_exists (JPATH_ROOT . '/ ' . $ file ->filename ))
215161 {
216162 throw new \RuntimeException (\JText::sprintf ('COM_PATCHTESTER_FILE_DELETED_DOES_NOT_EXIST_S ' , $ file ->old ));
217163 }
218164
219165 if ($ file ->action == 'added ' || $ file ->action == 'modified ' )
220166 {
221167 // If the backup file already exists, we can't apply the patch
222- if (file_exists (JPATH_COMPONENT . '/backups/ ' . md5 ($ file ->new ) . '.txt ' ))
168+ if (file_exists (JPATH_COMPONENT . '/backups/ ' . md5 ($ file ->filename ) . '.txt ' ))
223169 {
224- throw new \RuntimeException (\JText::sprintf ('COM_PATCHTESTER_CONFLICT_S ' , $ file ->new ));
170+ throw new \RuntimeException (\JText::sprintf ('COM_PATCHTESTER_CONFLICT_S ' , $ file ->filename ));
225171 }
226172
227- if ($ file ->action == 'modified ' && !file_exists (JPATH_ROOT . '/ ' . $ file ->old ))
173+ if ($ file ->action == 'modified ' && !file_exists (JPATH_ROOT . '/ ' . $ file ->filename ))
228174 {
229- throw new \RuntimeException (\JText::sprintf ('COM_PATCHTESTER_FILE_MODIFIED_DOES_NOT_EXIST_S ' , $ file ->old ));
175+ throw new \RuntimeException (\JText::sprintf ('COM_PATCHTESTER_FILE_MODIFIED_DOES_NOT_EXIST_S ' , $ file ->filename ));
230176 }
231177
232- $ url = 'https://raw.github.com/ ' . urlencode ($ pull ->head ->user ->login ) . '/ ' . urlencode ($ pull ->head ->repo ->name )
233- . '/ ' . urlencode ($ pull ->head ->ref ) . '/ ' . $ file ->new ;
234-
235178 try
236179 {
237- $ file ->body = $ github ->getClient ()->get ($ url )->body ;
180+ $ contentsResponse = $ github ->getFileContents (
181+ $ this ->getState ()->get ('github_user ' ), $ this ->getState ()->get ('github_repo ' ), $ file ->filename , urlencode ($ pull ->head ->ref )
182+ );
183+
184+ $ contents = json_decode ($ contentsResponse ->body );
185+
186+ // In case encoding type ever changes
187+ switch ($ contents ->encoding )
188+ {
189+ case 'base64 ' :
190+ $ file ->body = base64_decode ($ contents ->content );
191+
192+ break ;
193+
194+ default :
195+ throw new \RuntimeException (\JText::_ ('COM_PATCHTESTER_ERROR_UNSUPPORTED_ENCODING ' ));
196+ }
238197 }
239- catch (\ Exception $ e )
198+ catch (UnexpectedResponse $ e )
240199 {
241200 throw new \RuntimeException (\JText::sprintf ('COM_PATCHTESTER_COULD_NOT_CONNECT_TO_GITHUB ' , $ e ->getMessage ()), $ e ->getCode (), $ e );
242201 }
@@ -247,38 +206,35 @@ public function apply($id)
247206 jimport ('joomla.filesystem.path ' );
248207
249208 // At this point, we have ensured that we have all the new files and there are no conflicts
250- foreach ($ files as $ file )
209+ foreach ($ parsedFiles as $ file )
251210 {
252211 // We only create a backup if the file already exists
253- if ($ file ->action == 'deleted ' || (file_exists (JPATH_ROOT . '/ ' . $ file ->new ) && $ file ->action == 'modified ' ))
212+ if ($ file ->action == 'deleted ' || (file_exists (JPATH_ROOT . '/ ' . $ file ->filename ) && $ file ->action == 'modified ' ))
254213 {
255- if (!\JFile::copy (\JPath::clean (JPATH_ROOT . '/ ' . $ file ->old ), JPATH_COMPONENT . '/backups/ ' . md5 ($ file ->old ) . '.txt ' ))
214+ $ src = JPATH_ROOT . '/ ' . $ file ->filename ;
215+ $ dest = JPATH_COMPONENT . '/backups/ ' . md5 ($ file ->filename ) . '.txt ' ;
216+
217+ if (!\JFile::copy (\JPath::clean ($ src ), $ dest ))
256218 {
257- throw new \RuntimeException (
258- \JText::sprintf (
259- 'COM_PATCHTESTER_ERROR_CANNOT_COPY_FILE ' ,
260- JPATH_ROOT . '/ ' . $ file ->old ,
261- JPATH_COMPONENT . '/backups/ ' . md5 ($ file ->old ) . '.txt '
262- )
263- );
219+ throw new \RuntimeException (\JText::sprintf ('COM_PATCHTESTER_ERROR_CANNOT_COPY_FILE ' , $ src , $ dest ));
264220 }
265221 }
266222
267223 switch ($ file ->action )
268224 {
269225 case 'modified ' :
270226 case 'added ' :
271- if (!\JFile::write (\JPath::clean (JPATH_ROOT . '/ ' . $ file ->new ), $ file ->body ))
227+ if (!\JFile::write (\JPath::clean (JPATH_ROOT . '/ ' . $ file ->filename ), $ file ->body ))
272228 {
273- throw new \RuntimeException (\JText::sprintf ('COM_PATCHTESTER_ERROR_CANNOT_WRITE_FILE ' , JPATH_ROOT . '/ ' . $ file ->new ));
229+ throw new \RuntimeException (\JText::sprintf ('COM_PATCHTESTER_ERROR_CANNOT_WRITE_FILE ' , JPATH_ROOT . '/ ' . $ file ->filename ));
274230 }
275231
276232 break ;
277233
278234 case 'deleted ' :
279- if (!\JFile::delete (\JPath::clean (JPATH_ROOT . '/ ' . $ file ->old )))
235+ if (!\JFile::delete (\JPath::clean (JPATH_ROOT . '/ ' . $ file ->filename )))
280236 {
281- throw new \RuntimeException (\JText::sprintf ('COM_PATCHTESTER_ERROR_CANNOT_DELETE_FILE ' , JPATH_ROOT . '/ ' . $ file ->old ));
237+ throw new \RuntimeException (\JText::sprintf ('COM_PATCHTESTER_ERROR_CANNOT_DELETE_FILE ' , JPATH_ROOT . '/ ' . $ file ->filename ));
282238 }
283239
284240 break ;
@@ -287,7 +243,7 @@ public function apply($id)
287243
288244 $ record = (object ) array (
289245 'pull_id ' => $ pull ->number ,
290- 'data ' => json_encode ($ files ),
246+ 'data ' => json_encode ($ parsedFiles ),
291247 'patched_by ' => \JFactory::getUser ()->id ,
292248 'applied ' => 1 ,
293249 'applied_version ' => JVERSION ,
@@ -350,36 +306,35 @@ public function revert($id)
350306 {
351307 case 'deleted ' :
352308 case 'modified ' :
353- if (!\JFile::copy (JPATH_COMPONENT . '/backups/ ' . md5 ($ file ->old ) . '.txt ' , JPATH_ROOT . '/ ' . $ file ->old ))
309+ $ src = JPATH_COMPONENT . '/backups/ ' . md5 ($ file ->filename ) . '.txt ' ;
310+ $ dest = JPATH_ROOT . '/ ' . $ file ->filename ;
311+
312+ if (!\JFile::copy ($ src , $ dest ))
354313 {
355- throw new \RuntimeException (
356- \JText::sprintf (
357- 'COM_PATCHTESTER_ERROR_CANNOT_COPY_FILE ' ,
358- JPATH_COMPONENT . '/backups/ ' . md5 ($ file ->old ) . '.txt ' ,
359- JPATH_ROOT . '/ ' . $ file ->old
360- )
361- );
314+ throw new \RuntimeException (\JText::sprintf ('COM_PATCHTESTER_ERROR_CANNOT_COPY_FILE ' , $ src , $ dest ));
362315 }
363316
364- if (file_exists (JPATH_COMPONENT . ' /backups/ ' . md5 ( $ file -> old ) . ' .txt ' ))
317+ if (file_exists ($ src ))
365318 {
366- if (!\JFile::delete (JPATH_COMPONENT . ' /backups/ ' . md5 ( $ file -> old ) . ' .txt ' ))
319+ if (!\JFile::delete ($ src ))
367320 {
368321 throw new \RuntimeException (
369- \JText::sprintf ('COM_PATCHTESTER_ERROR_CANNOT_DELETE_FILE ' , JPATH_COMPONENT . ' /backups/ ' . md5 ( $ file -> old ) . ' .txt ' )
322+ \JText::sprintf ('COM_PATCHTESTER_ERROR_CANNOT_DELETE_FILE ' , $ src )
370323 );
371324 }
372325 }
373326
374327 break ;
375328
376329 case 'added ' :
377- if (file_exists (JPATH_ROOT . '/ ' . $ file ->new ))
330+ $ src = JPATH_ROOT . '/ ' . $ file ->filename ;
331+
332+ if (file_exists ($ src ))
378333 {
379- if (!\JFile::delete (JPATH_ROOT . ' / ' . $ file -> new ))
334+ if (!\JFile::delete ($ src ))
380335 {
381336 throw new \RuntimeException (
382- \JText::sprintf ('COM_PATCHTESTER_ERROR_CANNOT_DELETE_FILE ' , JPATH_ROOT . ' / ' . $ file -> new )
337+ \JText::sprintf ('COM_PATCHTESTER_ERROR_CANNOT_DELETE_FILE ' , $ src )
383338 );
384339 }
385340 }
0 commit comments