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 public GitStatusConsumer( ScmLogger logger, File workingDirectory, URI relativeRepositoryPath )
102 {
103 this( logger, workingDirectory );
104 this.relativeRepositoryPath = relativeRepositoryPath;
105 }
106
107
108
109
110
111
112
113
114 public void consumeLine( String line )
115 {
116 if ( logger.isDebugEnabled() )
117 {
118 logger.debug( line );
119 }
120 if ( StringUtils.isEmpty( line ) )
121 {
122 return;
123 }
124
125 ScmFileStatus status = null;
126
127 List<String> files = new ArrayList<String>();
128
129 Matcher matcher;
130 if ( ( matcher = ADDED_PATTERN.matcher( line ) ).find() )
131 {
132 status = ScmFileStatus.ADDED;
133 files.add(resolvePath(matcher.group(1), relativeRepositoryPath));
134 }
135 else if ( ( matcher = MODIFIED_PATTERN.matcher( line ) ).find() )
136 {
137 status = ScmFileStatus.MODIFIED;
138 files.add(resolvePath(matcher.group(1), relativeRepositoryPath));
139 }
140 else if ( ( matcher = DELETED_PATTERN.matcher( line ) ) .find() )
141 {
142 status = ScmFileStatus.DELETED;
143 files.add(resolvePath(matcher.group(1), relativeRepositoryPath));
144 }
145 else if ( ( matcher = RENAMED_PATTERN.matcher( line ) ).find() )
146 {
147 status = ScmFileStatus.RENAMED;
148 files.add( resolvePath( matcher.group( 1 ), relativeRepositoryPath ) );
149 files.add( resolvePath( matcher.group( 2 ), relativeRepositoryPath ) );
150 logger.debug( "RENAMED status for line '" + line + "' files added '" + matcher.group( 1 ) + "' '"
151 + matcher.group( 2 ) );
152 }
153 else
154 {
155 logger.warn( "Ignoring unrecognized line: " + line );
156 return;
157 }
158
159
160 if ( !files.isEmpty() && status != null )
161 {
162 if ( workingDirectory != null )
163 {
164 if ( status == ScmFileStatus.RENAMED )
165 {
166 String oldFilePath = files.get( 0 );
167 String newFilePath = files.get( 1 );
168 if ( isFile( oldFilePath ) )
169 {
170 logger.debug(
171 "file '" + oldFilePath + "' is a file" );
172 return;
173 }
174 else
175 {
176 logger.debug(
177 "file '" + oldFilePath + "' not a file" );
178 }
179 if ( !isFile( newFilePath ) )
180 {
181 logger.debug(
182 "file '" + newFilePath + "' not a file" );
183 return;
184 }
185 else
186 {
187 logger.debug(
188 "file '" + newFilePath + "' is a file" );
189 }
190 }
191 else if ( status == ScmFileStatus.DELETED )
192 {
193 if ( isFile( files.get( 0 ) ) )
194 {
195 return;
196 }
197 }
198 else
199 {
200 if ( !isFile( files.get( 0 ) ) )
201 {
202 return;
203 }
204 }
205 }
206
207 for ( String file : files )
208 {
209 changedFiles.add( new ScmFile( file, status ) );
210 }
211 }
212 }
213
214 private boolean isFile( String file )
215 {
216 File targetFile;
217 if ( relativeRepositoryPath == null )
218 {
219 targetFile = new File( workingDirectory, file );
220 }
221 else
222 {
223 targetFile = new File( relativeRepositoryPath.getPath(), file );
224 }
225 return targetFile.isFile();
226 }
227
228 protected static String resolvePath( String fileEntry, URI path )
229 {
230 if ( path != null )
231 {
232 return resolveURI( fileEntry, path ).getPath();
233 }
234 else
235 {
236 return fileEntry;
237 }
238 }
239
240
241
242
243
244
245
246 public static URI resolveURI( String fileEntry, URI path )
247 {
248
249
250 String str = fileEntry.replace( " ", "%20" );
251 return path.relativize( URI.create( str ) );
252 }
253
254
255 public List<ScmFile> getChangedFiles()
256 {
257 return changedFiles;
258 }
259 }