View Javadoc
1   package org.apache.maven.scm.provider.git.gitexe.command.status;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   * http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.io.BufferedReader;
23  import java.io.File;
24  import java.io.FileReader;
25  import java.io.IOException;
26  import java.net.URI;
27  import java.util.List;
28  
29  import org.apache.commons.io.FileUtils;
30  import org.apache.commons.io.IOUtils;
31  import org.apache.maven.scm.ScmFile;
32  import org.apache.maven.scm.ScmFileStatus;
33  import org.apache.maven.scm.ScmFileSet;
34  import org.apache.maven.scm.log.DefaultLog;
35  import org.codehaus.plexus.PlexusTestCase;
36  
37  /**
38   * @author <a href="mailto:struberg@yahoo.de">Mark Struberg</a>
39   */
40  public class GitStatusConsumerTest
41      extends PlexusTestCase
42  {
43  
44      private List<ScmFile> getChangedFiles( File gitlog )
45          throws IOException
46      {
47          return getChangedFiles( gitlog, null );
48      }
49      
50      private List<ScmFile> getChangedFiles( File gitlog, URI relativeRepoPath )
51          throws IOException
52      {
53          GitStatusConsumer consumer = new GitStatusConsumer( new DefaultLog(), null, relativeRepoPath );
54  
55          BufferedReader r = new BufferedReader( new FileReader( gitlog ) );
56  
57          try
58          {
59              String line;
60  
61              while ( ( line = r.readLine() ) != null )
62              {
63                  consumer.consumeLine( line );
64              }
65          }
66          finally
67          {
68              IOUtils.closeQuietly( r );
69          }
70  
71          return consumer.getChangedFiles();
72      }
73  
74      private List<ScmFile> getChangedFiles( String line, File workingDirectory )
75      {
76          GitStatusConsumer consumer = new GitStatusConsumer( new DefaultLog(), workingDirectory );
77  
78          consumer.consumeLine( line );
79  
80          return consumer.getChangedFiles();
81      }
82  
83      private List<ScmFile> getChangedFiles( String line, File workingDirectory, URI relativeRepoPath )
84      {
85          GitStatusConsumer consumer = new GitStatusConsumer( new DefaultLog(), workingDirectory, relativeRepoPath );
86  
87          consumer.consumeLine( line );
88  
89          return consumer.getChangedFiles();
90      }
91  
92      private List<ScmFile> getChangedFiles( String line, File workingDirectory, URI relativeRepoPath, ScmFileSet scmFileSet )
93      {
94          GitStatusConsumer consumer = new GitStatusConsumer( new DefaultLog(), workingDirectory, relativeRepoPath, scmFileSet );
95  
96          consumer.consumeLine( line );
97  
98          return consumer.getChangedFiles();
99      }
100 
101     public void testConsumerUntrackedFile()
102     {
103         List<ScmFile> changedFiles = getChangedFiles( "?? project.xml", null );
104 
105         assertNotNull( changedFiles );
106         assertEquals( 0, changedFiles.size() );
107 
108         changedFiles = getChangedFiles( "?? \"test file with spaces and a special \\177 character.xml\"", null );
109 
110         assertNotNull( changedFiles );
111         assertEquals( 0, changedFiles.size() );
112     }
113 
114     public void testConsumerAddedFile()
115     {
116         List<ScmFile> changedFiles = getChangedFiles( "A  project.xml", null );
117 
118         assertNotNull( changedFiles );
119         assertEquals( 1, changedFiles.size() );
120         assertEquals( "project.xml", changedFiles.get( 0 ).getPath() );
121 
122         changedFiles = getChangedFiles( "A  \"test file with spaces and a special \\177 character.xml\"", null );
123         
124         assertNotNull( changedFiles );
125         assertEquals( 1, changedFiles.size() );
126         assertEquals("test file with spaces and a special \u007f character.xml", changedFiles.get( 0 ).getPath() );
127     }
128 
129     public void testConsumerAddedAndModifiedFile()
130     {
131         List<ScmFile> changedFiles = getChangedFiles( "AM project.xml", null );
132 
133         assertNotNull( changedFiles );
134         assertEquals( 1, changedFiles.size() );
135         testScmFile( changedFiles.get( 0 ), "project.xml", ScmFileStatus.ADDED );
136         
137         changedFiles = getChangedFiles( "AM \"test file with spaces and a special \\177 character.xml\"", null );
138 
139         assertNotNull( changedFiles );
140         assertEquals( 1, changedFiles.size() );
141         testScmFile( changedFiles.get( 0 ), "test file with spaces and a special \u007f character.xml", ScmFileStatus.ADDED );
142     }
143 
144     public void testConsumerAddedFileWithDirectoryAndNoFile()
145         throws IOException
146     {
147         File dir = createTempDirectory();
148 
149         List<ScmFile> changedFiles = getChangedFiles( "A  project.xml", dir );
150 
151         assertNotNull( changedFiles );
152         assertEquals( 0, changedFiles.size() );
153 
154         changedFiles = getChangedFiles( "A  \"test file with spaces and a special \\177 character.xml\"", dir );
155 
156         assertNotNull( changedFiles );
157         assertEquals( 0, changedFiles.size() );
158 
159         FileUtils.deleteDirectory( dir );
160     }
161 
162     public void testConsumerAddedFileWithDirectoryAndFile()
163         throws IOException
164     {
165         File dir = createTempDirectory();
166         FileUtils.write( new File( dir, "project.xml" ), "data" );
167 
168         List<ScmFile> changedFiles = getChangedFiles( "A  project.xml", dir );
169 
170         assertNotNull( changedFiles );
171         assertEquals( 1, changedFiles.size() );
172         assertEquals( "project.xml", changedFiles.get( 0 ).getPath() );
173 
174         FileUtils.write( new File( dir, "test file with spaces and a special \u007f character.xml" ), "data" );
175 
176         changedFiles = getChangedFiles( "A  \"test file with spaces and a special \\177 character.xml\"", dir );
177 
178         assertNotNull( changedFiles );
179         assertEquals( 1, changedFiles.size() );
180         assertEquals("test file with spaces and a special \u007f character.xml", changedFiles.get( 0 ).getPath() );
181 
182         FileUtils.deleteDirectory( dir );
183     }
184 
185     public void testConsumerModifiedFile()
186     {
187         List<ScmFile> changedFiles = getChangedFiles( "M  project.xml", null );
188 
189         assertNotNull( changedFiles );
190         assertEquals( 1, changedFiles.size() );
191         assertEquals( "project.xml", changedFiles.get( 0 ).getPath() );
192 
193         changedFiles = getChangedFiles( "M  \"test file with spaces and a special \\177 character.xml\"", null );
194 
195         assertNotNull( changedFiles );
196         assertEquals( 1, changedFiles.size() );
197         assertEquals("test file with spaces and a special \u007f character.xml", changedFiles.get( 0 ).getPath() );
198     }
199 
200     public void testURI()
201         throws Exception
202     {
203         String path = "Not%Scheme:/sub dir";
204         URI u = GitStatusConsumer.uriFromPath( path );
205         assertEquals( path, u.getPath() );
206     }
207 
208     public void testConsumerWithFileSet()
209         throws IOException
210     {
211         File dir = createTempDirectory();
212         FileUtils.write( new File( dir, "project.xml" ), "data" );
213         FileUtils.write( new File( dir, "pom.xml" ), "more data" );
214         File subdir = new File( dir.getAbsolutePath(), "subDir" );
215         subdir.mkdir();
216         FileUtils.write( new File( subdir, "something.xml" ), "data" );
217 
218         ScmFileSet scmFileSet = new ScmFileSet( dir, null, "project.xml" );
219         List<ScmFile> changedFiles = getChangedFiles( "M project.xml", dir, null, scmFileSet );
220         assertEquals( 0, changedFiles.size() );
221 
222         scmFileSet = new ScmFileSet( dir, "pom.xml" );
223         changedFiles = getChangedFiles( "M pom.xml", dir, null, scmFileSet );
224         assertEquals( 1, changedFiles.size() );
225 
226         scmFileSet = new ScmFileSet( subdir, "something.xml", "pom.xml" );
227         changedFiles = getChangedFiles( "M subDir/something.xml", dir, dir.toURI(), scmFileSet );
228         assertEquals( 1, changedFiles.size() );
229     }
230 
231 	// SCM-740
232 	public void testConsumerModifiedFileInComplexDirectorySetup() throws IOException {
233 
234 		File dir = createTempDirectory();
235 		URI relativeCWD = URI.create( "" );
236 		File subdir = new File( dir, "subDirectory" );
237 		subdir.mkdir();
238 		FileUtils.write( new File( subdir, "project.xml" ), "data" );
239 
240 		List<ScmFile> changedFiles = getChangedFiles( "M  subDirectory/project.xml", dir, relativeCWD );
241 
242 		assertNotNull( changedFiles );
243 		assertEquals( 1, changedFiles.size() );
244         assertEquals( "subDirectory/project.xml", changedFiles.get( 0 ).getPath() );
245 
246         FileUtils.write( new File( subdir, "test file with spaces and a déjà vu character.xml" ), "data" );
247 
248 		changedFiles =
249 			getChangedFiles( "M  \"subDirectory/test file with spaces and a déjà vu character.xml\"", dir, relativeCWD );
250 
251 		assertNotNull( changedFiles );
252 		assertEquals( 1, changedFiles.size() );
253         assertEquals( "subDirectory/test file with spaces and a déjà vu character.xml", changedFiles.get( 0 ).getPath() );
254 
255         FileUtils.deleteDirectory( dir );
256 	}
257 
258 	public void testConsumerModifiedFileInComplexDirectoryWithSpaces() throws IOException {
259 
260 		File dir = createTempDirectory();
261 		URI relativeCWD = URI.create( "" );
262 		File subdir = new File( dir, "sub Directory déjà vu special" );
263 		subdir.mkdir();
264 		FileUtils.write( new File( subdir, "project.xml" ), "data" );
265 
266 		List<ScmFile> changedFiles =
267 			getChangedFiles( "M  \"sub Directory déjà vu special/project.xml\"", dir, relativeCWD );
268 
269 		assertNotNull( changedFiles );
270 		assertEquals( 1, changedFiles.size() );
271         assertEquals( "sub Directory déjà vu special/project.xml", changedFiles.get( 0 ).getPath() );
272 
273         FileUtils.write( new File( subdir, "test file with spaces and a déjà vu character.xml" ), "data" );
274 
275 		changedFiles =
276 			getChangedFiles( "M  \"sub Directory déjà vu special/test file with spaces and a déjà vu character.xml\"",
277 							dir, relativeCWD );
278 
279 		assertNotNull( changedFiles );
280 		assertEquals( 1, changedFiles.size() );
281         assertEquals( "sub Directory déjà vu special/test file with spaces and a déjà vu character.xml", changedFiles.get( 0 ).getPath() );
282 
283         FileUtils.deleteDirectory( dir );
284 	}
285 
286 	public void testConsumerModifiedFileUnstaged()
287     {
288         List<ScmFile> changedFiles = getChangedFiles( "M  project.xml", null );
289 
290         assertNotNull( changedFiles );
291         assertEquals( 1, changedFiles.size() );
292         testScmFile( changedFiles.get( 0 ), "project.xml", ScmFileStatus.MODIFIED);
293 
294         changedFiles = getChangedFiles( "M  \"test file with spaces and a special \\177 character.xml\"", null );
295 
296         assertNotNull( changedFiles );
297         assertEquals( 1, changedFiles.size() );
298         testScmFile( changedFiles.get( 0 ), "test file with spaces and a special \u007f character.xml", ScmFileStatus.MODIFIED);
299     }
300 
301     public void testConsumerModifiedFileBothStagedAndUnstaged()
302     {
303         List<ScmFile> changedFiles = getChangedFiles( "MM project.xml", null );
304 
305         assertNotNull( changedFiles );
306         assertEquals( 1, changedFiles.size() );
307         testScmFile( changedFiles.get( 0 ), "project.xml", ScmFileStatus.MODIFIED);
308 
309         changedFiles = getChangedFiles( "MM \"test file with spaces and a special \\177 character.xml\"", null );
310 
311         assertNotNull( changedFiles );
312         assertEquals( 1, changedFiles.size() );
313         testScmFile( changedFiles.get( 0 ), "test file with spaces and a special \u007f character.xml", ScmFileStatus.MODIFIED);
314     }
315 
316     public void testConsumerModifiedFileWithDirectoryAndNoFile()
317         throws IOException
318     {
319         File dir = createTempDirectory();
320 
321         List<ScmFile> changedFiles = getChangedFiles( "M  project.xml", dir );
322 
323         assertNotNull( changedFiles );
324         assertEquals( 0, changedFiles.size() );
325 
326         changedFiles = getChangedFiles( "M  \"test file with spaces and a special \\177 character.xml\"", dir );
327 
328         assertNotNull( changedFiles );
329         assertEquals( 0, changedFiles.size() );
330 
331         FileUtils.deleteDirectory( dir );
332     }
333 
334     public void testConsumerModifiedFileWithDirectoryAndFile()
335         throws IOException
336     {
337         File dir = createTempDirectory();
338         FileUtils.write( new File( dir, "project.xml" ), "data" );
339 
340         List<ScmFile> changedFiles = getChangedFiles( "M  project.xml", dir );
341 
342         assertNotNull( changedFiles );
343         assertEquals( 1, changedFiles.size() );
344         assertEquals( "project.xml", changedFiles.get( 0 ).getPath() );
345 
346         FileUtils.write( new File( dir, "test file with spaces and a special \u007f character.xml" ), "data" );
347 
348         changedFiles = getChangedFiles( "M  \"test file with spaces and a special \\177 character.xml\"", dir );
349 
350         assertNotNull( changedFiles );
351         assertEquals( 1, changedFiles.size() );
352         assertEquals( "test file with spaces and a special \u007f character.xml", changedFiles.get( 0 ).getPath() );
353 
354         FileUtils.deleteDirectory( dir );
355     }
356 
357     public void testConsumerRemovedFile()
358     {
359         List<ScmFile> changedFiles = getChangedFiles( "D  Capfile", null );
360 
361         assertNotNull( changedFiles );
362         assertEquals( 1, changedFiles.size() );
363         assertEquals( "Capfile", changedFiles.get( 0 ).getPath() );
364 
365         changedFiles = getChangedFiles( "D  \"test file with spaces and a déjà vu character.xml\"", null );
366 
367         assertNotNull( changedFiles );
368         assertEquals( 1, changedFiles.size() );
369         assertEquals( "test file with spaces and a déjà vu character.xml", changedFiles.get( 0 ).getPath() );
370     }
371 
372     public void testConsumerRemovedFileUnstaged()
373     {
374         List<ScmFile> changedFiles = getChangedFiles( "D  Capfile", null );
375 
376         assertNotNull( changedFiles );
377         assertEquals( 1, changedFiles.size() );
378         assertEquals( ScmFileStatus.DELETED, changedFiles.get( 0 ).getStatus() );
379 
380         changedFiles = getChangedFiles( "D  \"test file with spaces and a special \\177 character.xml\"", null );
381 
382         assertNotNull( changedFiles );
383         assertEquals( 1, changedFiles.size() );
384         assertEquals( ScmFileStatus.DELETED, changedFiles.get( 0 ).getStatus() );
385     }
386 
387     public void testConsumerRemovedFileWithDirectoryAndNoFile()
388         throws IOException
389     {
390         File dir = createTempDirectory();
391 
392         List<ScmFile> changedFiles = getChangedFiles( "D  Capfile", dir );
393 
394         assertNotNull( changedFiles );
395         assertEquals( 1, changedFiles.size() );
396         assertEquals( "Capfile", changedFiles.get( 0 ).getPath() );
397 
398         changedFiles = getChangedFiles( "D  \"test file with spaces and a special \\177 character.xml\"", dir );
399 
400         assertNotNull( changedFiles );
401         assertEquals( 1, changedFiles.size() );
402         assertEquals( "test file with spaces and a special \u007f character.xml", changedFiles.get( 0 ).getPath() );
403         
404         FileUtils.deleteDirectory( dir );
405     }
406 
407     public void testConsumerRemovedFileWithDirectoryAndFile()
408         throws IOException
409     {
410         File dir = createTempDirectory();
411         FileUtils.write( new File( dir, "Capfile" ), "data" );
412 
413         List<ScmFile> changedFiles = getChangedFiles( "D  Capfile", dir );
414 
415         assertNotNull( changedFiles );
416         assertEquals( 0, changedFiles.size() );
417 
418         FileUtils.write( new File( dir, "test file with spaces and a special \u007f character.xml" ), "data" );
419 
420         changedFiles = getChangedFiles( "D  \"test file with spaces and a special \\177 character.xml\"", dir );
421 
422         assertNotNull( changedFiles );
423         assertEquals( 0, changedFiles.size() );
424         FileUtils.deleteDirectory( dir );
425     }
426 
427     // Test reproducing SCM-694
428     public void testConsumerRenamedFile()
429         throws Exception
430     {
431         File dir = createTempDirectory();
432 
433         File tmpFile = new File( dir, "NewCapFile" );
434 
435         FileUtils.write( tmpFile, "data" );
436 
437         List<ScmFile> changedFiles = getChangedFiles( "R  OldCapfile -> NewCapFile", dir );
438 
439         assertNotNull( changedFiles );
440         assertEquals( 2, changedFiles.size() );
441         assertEquals( "OldCapfile", changedFiles.get(0).getPath() );
442         assertEquals( "NewCapFile", changedFiles.get(1).getPath() );
443 
444         tmpFile = new File( dir, "New test file with spaces and a special \u007f character.xml" );
445 
446         FileUtils.write( tmpFile, "data" );
447 
448         changedFiles = getChangedFiles( "R  \"Old test file with spaces and a special \\177 character.xml\" -> \"New test file with spaces and a special \\177 character.xml\"", dir );
449 
450         assertNotNull( changedFiles );
451         assertEquals( 2, changedFiles.size() );
452         assertEquals( "Old test file with spaces and a special \u007f character.xml", changedFiles.get(0).getPath() );
453         assertEquals( "New test file with spaces and a special \u007f character.xml", changedFiles.get(1).getPath() );
454         FileUtils.deleteDirectory( dir );
455     }
456 
457     public void testLog1Consumer()
458         throws Exception
459     {
460         List<ScmFile> changedFiles = getChangedFiles( getTestFile( "/src/test/resources/git/status/gitstatus1.gitlog" ) );
461 
462         assertEquals( 4, changedFiles.size() );
463 
464         testScmFile( changedFiles.get( 0 ), "project.xml", ScmFileStatus.ADDED );
465         testScmFile( changedFiles.get( 1 ), "readme.txt", ScmFileStatus.MODIFIED );
466         testScmFile( changedFiles.get( 2 ), "d\u00e9j\u00e0 vu.xml", ScmFileStatus.ADDED );
467         testScmFile( changedFiles.get( 3 ), "d\u00e9j\u00e0 vu.txt", ScmFileStatus.MODIFIED );
468     }
469 
470     public void testEmptyLogConsumer()
471         throws Exception
472     {
473         List<ScmFile> changedFiles = getChangedFiles( getTestFile( "/src/test/resources/git/status/gitstatus-empty.gitlog" ) );
474 
475         assertEquals( 0, changedFiles.size() );
476     }
477 
478     public void testLog2Consumer()
479         throws Exception
480     {
481         List<ScmFile> changedFiles = getChangedFiles( getTestFile( "/src/test/resources/git/status/gitstatus2.gitlog" ) );
482 
483         assertEquals( 4, changedFiles.size() );
484 
485         testScmFile( changedFiles.get( 0 ),
486                      "maven-scm-provider-gitexe/src/main/java/org/apache/maven/scm/provider/git/gitexe/command/add/GitAddCommand.java",
487                      ScmFileStatus.MODIFIED );
488         testScmFile( changedFiles.get( 1 ),
489                      "maven-scm-provider-gitexe/src/main/java/org/apache/maven/scm/provider/git/gitexe/command/checkin/GitCheckInCommand.java",
490                      ScmFileStatus.MODIFIED );
491         testScmFile( changedFiles.get( 2 ),
492                      "maven-scm-provider-gitexe/src/main/java/org/apache/maven/scm/provider/git/gitexe/command/checkin/GitCheckInConsumer.java",
493                      ScmFileStatus.DELETED );
494         testScmFile( changedFiles.get( 3 ),
495                      "maven-scm-provider-gitexe/src/main/java/org/apache/maven/scm/provider/git/gitexe/command/status/GitStatusConsumer.java",
496                      ScmFileStatus.MODIFIED );
497     }
498 
499     // SCM-709
500     public void testResolvePath()
501     {
502         File repositoryRoot = getTestFile( "repo" );
503         File workingDirectory = getTestFile( "repo/work" );
504 
505         URI path = repositoryRoot.toURI().relativize( workingDirectory.toURI() );
506 
507         assertEquals( "work", path.getPath() );
508 
509         assertEquals( "pom.xml", GitStatusConsumer.resolvePath( "work/pom.xml", path ) );
510         assertEquals( "work/pom.xml", GitStatusConsumer.resolvePath( "work/pom.xml", null ) );
511         
512         // spaces in path
513         repositoryRoot = getTestFile( "repo" );
514         workingDirectory = getTestFile( "repo/work with spaces" );
515 
516         path = repositoryRoot.toURI().relativize( workingDirectory.toURI() );
517 
518         assertEquals( "work with spaces", path.getPath() );
519 
520         assertEquals( "pom.xml", GitStatusConsumer.resolvePath( "work with spaces/pom.xml", path ) );
521         assertEquals( "work with spaces/pom.xml", GitStatusConsumer.resolvePath( "work with spaces/pom.xml", null ) );
522 
523         // spaces in path with quotes
524         repositoryRoot = getTestFile( "repo" );
525         workingDirectory = getTestFile( "repo/work with spaces and quotes" );
526 
527         path = repositoryRoot.toURI().relativize( workingDirectory.toURI() );
528 
529         assertEquals( "work with spaces and quotes", path.getPath() );
530 
531         assertEquals( "pom.xml", GitStatusConsumer.resolvePath( "\"work with spaces and quotes/pom.xml\"", path ) );
532         assertEquals( "work with spaces and quotes/pom.xml",
533                 GitStatusConsumer.resolvePath( "\"work with spaces and quotes/pom.xml\"", null ) );
534     }
535 
536 	private void testScmFile( ScmFile fileToTest, String expectedFilePath, ScmFileStatus expectedStatus )
537     {
538         assertEquals( expectedFilePath, fileToTest.getPath() );
539         assertEquals( expectedStatus, fileToTest.getStatus() );
540     }
541 
542     private File createTempDirectory()
543         throws IOException
544     {
545         File dir = File.createTempFile( "gitexe", "test" );
546         dir.delete();
547         dir.mkdir();
548         return dir;
549     }
550 
551 }