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