1 package org.apache.maven.scm.provider.git.gitexe.command.status;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.File;
23 import java.net.URI;
24 import java.util.ArrayList;
25 import java.util.List;
26 import java.util.regex.Matcher;
27 import java.util.regex.Pattern;
28
29 import org.apache.commons.lang.StringUtils;
30 import org.apache.maven.scm.ScmFile;
31 import org.apache.maven.scm.ScmFileStatus;
32 import org.apache.maven.scm.log.ScmLogger;
33 import org.codehaus.plexus.util.cli.StreamConsumer;
34
35
36
37
38 public class GitStatusConsumer
39 implements StreamConsumer
40 {
41
42
43
44
45 private static final Pattern ADDED_PATTERN = Pattern.compile( "^A[ M]* (.*)$" );
46
47
48
49
50 private static final Pattern MODIFIED_PATTERN = Pattern.compile( "^ *M[ M]* (.*)$" );
51
52
53
54
55 private static final Pattern DELETED_PATTERN = Pattern.compile( "^ *D * (.*)$" );
56
57
58
59
60 private static final Pattern RENAMED_PATTERN = Pattern.compile( "^R (.*) -> (.*)$" );
61
62 private ScmLogger logger;
63
64 private File workingDirectory;
65
66
67
68
69 private List<ScmFile> changedFiles = new ArrayList<ScmFile>();
70
71 private URI relativeRepositoryPath;
72
73
74
75
76
77
78
79
80
81
82
83 public GitStatusConsumer( ScmLogger logger, File workingDirectory )
84 {
85 this.logger = logger;
86 this.workingDirectory = workingDirectory;
87 }
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102 public GitStatusConsumer( ScmLogger logger, File workingDirectory, URI relativeRepositoryPath )
103 {
104 this( logger, workingDirectory );
105 this.relativeRepositoryPath = relativeRepositoryPath;
106 }
107
108
109
110
111
112
113
114
115 public void consumeLine( String line )
116 {
117 if ( logger.isDebugEnabled() )
118 {
119 logger.debug( line );
120 }
121 if ( StringUtils.isEmpty( line ) )
122 {
123 return;
124 }
125
126 ScmFileStatus status = null;
127
128 List<String> files = new ArrayList<String>();
129
130 Matcher matcher;
131 if ( ( matcher = ADDED_PATTERN.matcher( line ) ).find() )
132 {
133 status = ScmFileStatus.ADDED;
134 files.add( resolvePath( matcher.group( 1 ), relativeRepositoryPath ) );
135 }
136 else if ( ( matcher = MODIFIED_PATTERN.matcher( line ) ).find() )
137 {
138 status = ScmFileStatus.MODIFIED;
139 files.add( resolvePath( matcher.group( 1 ), relativeRepositoryPath ) );
140 }
141 else if ( ( matcher = DELETED_PATTERN.matcher( line ) ).find() )
142 {
143 status = ScmFileStatus.DELETED;
144 files.add( resolvePath( matcher.group( 1 ), relativeRepositoryPath ) );
145 }
146 else if ( ( matcher = RENAMED_PATTERN.matcher( line ) ).find() )
147 {
148 status = ScmFileStatus.RENAMED;
149 files.add( resolvePath( matcher.group( 1 ), relativeRepositoryPath ) );
150 files.add( resolvePath( matcher.group( 2 ), relativeRepositoryPath ) );
151 logger.debug( "RENAMED status for line '" + line + "' files added '" + matcher.group( 1 ) + "' '"
152 + matcher.group( 2 ) );
153 }
154 else
155 {
156 logger.warn( "Ignoring unrecognized line: " + line );
157 return;
158 }
159
160
161 if ( !files.isEmpty() && status != null )
162 {
163 if ( workingDirectory != null )
164 {
165 if ( status == ScmFileStatus.RENAMED )
166 {
167 String oldFilePath = files.get( 0 );
168 String newFilePath = files.get( 1 );
169 if ( isFile( oldFilePath ) )
170 {
171 logger.debug( "file '" + oldFilePath + "' is a file" );
172 return;
173 }
174 else
175 {
176 logger.debug( "file '" + oldFilePath + "' not a file" );
177 }
178 if ( !isFile( newFilePath ) )
179 {
180 logger.debug( "file '" + newFilePath + "' not a file" );
181 return;
182 }
183 else
184 {
185 logger.debug( "file '" + newFilePath + "' is a file" );
186 }
187 }
188 else if ( status == ScmFileStatus.DELETED )
189 {
190 if ( isFile( files.get( 0 ) ) )
191 {
192 return;
193 }
194 }
195 else
196 {
197 if ( !isFile( files.get( 0 ) ) )
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 private boolean isFile( String file )
212 {
213 File targetFile;
214 if ( relativeRepositoryPath == null )
215 {
216 targetFile = new File( workingDirectory, file );
217 }
218 else
219 {
220 targetFile = new File( relativeRepositoryPath.getPath(), file );
221 }
222 return targetFile.isFile();
223 }
224
225 protected static String resolvePath( String fileEntry, URI path )
226 {
227 if ( path != null )
228 {
229 return resolveURI( fileEntry, path ).getPath();
230 }
231 else
232 {
233 return fileEntry;
234 }
235 }
236
237
238
239
240
241
242
243 public static URI resolveURI( String fileEntry, URI path )
244 {
245
246
247
248 String str = fileEntry.replace( " ", "%20" );
249 return path.relativize( URI.create( str ) );
250 }
251
252
253 public List<ScmFile> getChangedFiles()
254 {
255 return changedFiles;
256 }
257 }