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 org.apache.commons.lang.StringUtils;
23  import org.apache.maven.scm.ScmFile;
24  import org.apache.maven.scm.ScmFileStatus;
25  import org.apache.maven.scm.log.ScmLogger;
26  import org.apache.regexp.RE;
27  import org.apache.regexp.RESyntaxException;
28  import org.codehaus.plexus.util.cli.StreamConsumer;
29  
30  import java.io.File;
31  import java.util.ArrayList;
32  import java.util.List;
33  
34  /**
35   * @author <a href="mailto:struberg@yahoo.de">Mark Struberg</a>
36   */
37  public class GitStatusConsumer
38      implements StreamConsumer
39  {
40      /**
41       * The pattern used to match added file lines
42       */
43      private static final String ADDED_PATTERN = "^A[ M]* (.*)$";
44  
45      /**
46       * The pattern used to match modified file lines
47       */
48      private static final String MODIFIED_PATTERN = "^ *M[ M]* (.*)$";
49  
50      /**
51       * The pattern used to match deleted file lines
52       */
53      private static final String DELETED_PATTERN = "^ *D * (.*)$";
54  
55      /**
56       * The pattern used to match renamed file lines
57       */
58      private static final String RENAMED_PATTERN = "R (.*) -> (.*)$";
59  
60      /**
61       * @see #ADDED_PATTERN
62       */
63      private RE addedRegexp;
64  
65      /**
66       * @see #MODIFIED_PATTERN
67       */
68      private RE modifiedRegexp;
69  
70      /**
71       * @see #DELETED_PATTERN
72       */
73      private RE deletedRegexp;
74  
75      /**
76       * @see #RENAMED_PATTERN
77       */
78      private RE renamedRegexp;
79  
80      private ScmLogger logger;
81  
82      private File workingDirectory;
83  
84      private List<ScmFile> changedFiles = new ArrayList<ScmFile>();
85  
86      // ----------------------------------------------------------------------
87      //
88      // ----------------------------------------------------------------------
89  
90      public GitStatusConsumer( ScmLogger logger, File workingDirectory )
91      {
92          this.logger = logger;
93          this.workingDirectory = workingDirectory;
94  
95          try
96          {
97              addedRegexp = new RE( ADDED_PATTERN );
98              modifiedRegexp = new RE( MODIFIED_PATTERN );
99              deletedRegexp = new RE( DELETED_PATTERN );
100             renamedRegexp = new RE( RENAMED_PATTERN );
101         }
102         catch ( RESyntaxException ex )
103         {
104             throw new RuntimeException(
105                 "INTERNAL ERROR: Could not create regexp to parse git log file. This shouldn't happen. Something is probably wrong with the oro installation.",
106                 ex );
107         }
108     }
109 
110     // ----------------------------------------------------------------------
111     // StreamConsumer Implementation
112     // ----------------------------------------------------------------------
113 
114     /**
115      * {@inheritDoc}
116      */
117     public void consumeLine( String line )
118     {
119         if ( logger.isDebugEnabled() )
120         {
121             logger.debug( line );
122         }
123         if ( StringUtils.isEmpty( line ) )
124         {
125             return;
126         }
127 
128         ScmFileStatus status = null;
129 
130         List<String> files = new ArrayList<String>();
131 
132         if ( addedRegexp.match( line ) )
133         {
134             status = ScmFileStatus.ADDED;
135             files.add( addedRegexp.getParen( 1 ) );
136         }
137         else if ( modifiedRegexp.match( line ) )
138         {
139             status = ScmFileStatus.MODIFIED;
140             files.add( modifiedRegexp.getParen( 1 ) );
141         }
142         else if ( deletedRegexp.match( line ) )
143         {
144             status = ScmFileStatus.DELETED;
145             files.add( deletedRegexp.getParen( 1 ) );
146         }
147         else if ( renamedRegexp.match( line ) )
148         {
149             status = ScmFileStatus.RENAMED;
150             files.add( StringUtils.trim( renamedRegexp.getParen( 1 ) ) );
151             files.add( StringUtils.trim( renamedRegexp.getParen( 2 ) ) );
152             logger.debug( "RENAMED status for line '" + line + "' files added '" + renamedRegexp.getParen( 1 ) + "' '"
153                               + renamedRegexp.getParen( 2 ) );
154         }
155 
156         // If the file isn't a file; don't add it.
157         if ( !files.isEmpty() && status != null )
158         {
159             if ( workingDirectory != null )
160             {
161                 if ( status == ScmFileStatus.RENAMED )
162                 {
163                     String oldFilePath = files.get( 0 );
164                     String newFilePath = files.get( 1 );
165                     if ( new File( workingDirectory, oldFilePath ).isFile() )
166                     {
167                         logger.debug(
168                             "file '" + new File( workingDirectory, oldFilePath ).getAbsolutePath() + "' is a file" );
169                         return;
170                     }
171                     else
172                     {
173                         logger.debug(
174                             "file '" + new File( workingDirectory, oldFilePath ).getAbsolutePath() + "' not a file" );
175                     }
176                     if ( !new File( workingDirectory, newFilePath ).isFile() )
177                     {
178                         logger.debug(
179                             "file '" + new File( workingDirectory, newFilePath ).getAbsolutePath() + "' not a file" );
180                         return;
181                     }
182                     else
183                     {
184                         logger.debug(
185                             "file '" + new File( workingDirectory, newFilePath ).getAbsolutePath() + "' is a file" );
186                     }
187                 }
188                 else if ( status == ScmFileStatus.DELETED )
189                 {
190                     if ( new File( workingDirectory, files.get( 0 ) ).isFile() )
191                     {
192                         return;
193                     }
194                 }
195                 else
196                 {
197                     if ( !new File( workingDirectory, files.get( 0 ) ).isFile() )
198                     {
199                         return;
200                     }
201                 }
202             }
203 
204             for ( String file : files )
205             {
206                 changedFiles.add( new ScmFile( file, status ) );
207             }
208         }
209     }
210 
211     public List<ScmFile> getChangedFiles()
212     {
213         return changedFiles;
214     }
215 }