1 package org.apache.maven.scm.provider.git.command.diff;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.maven.scm.ScmFile;
23 import org.apache.maven.scm.ScmFileStatus;
24 import org.apache.maven.scm.log.ScmLogger;
25 import org.apache.regexp.RE;
26 import org.apache.regexp.RESyntaxException;
27 import org.codehaus.plexus.util.cli.StreamConsumer;
28
29 import java.io.File;
30 import java.util.ArrayList;
31 import java.util.HashMap;
32 import java.util.List;
33 import java.util.Map;
34
35
36
37
38
39
40
41 public class GitDiffConsumer
42 implements StreamConsumer
43 {
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59 private static final String DIFF_FILES_PATTERN = "^diff --git\\sa/(.*)\\sb/(.*)";
60
61 private static final String START_REVISION_TOKEN = "---";
62
63 private static final String END_REVISION_TOKEN = "+++";
64
65 private static final String ADDED_LINE_TOKEN = "+";
66
67 private static final String REMOVED_LINE_TOKEN = "-";
68
69 private static final String UNCHANGED_LINE_TOKEN = " ";
70
71 private static final String CHANGE_SEPARATOR_TOKEN = "@@";
72
73 private static final String NO_NEWLINE_TOKEN = "\\ No newline at end of file";
74
75 private static final String INDEX_LINE_TOKEN = "index ";
76
77 private static final String NEW_FILE_MODE_TOKEN = "new file mode ";
78
79 private static final String DELETED_FILE_MODE_TOKEN = "deleted file mode ";
80
81 private ScmLogger logger;
82
83 private String currentFile;
84
85 private StringBuilder currentDifference;
86
87 private List<ScmFile> changedFiles = new ArrayList<ScmFile>();
88
89 private Map<String,CharSequence> differences = new HashMap<String,CharSequence>();
90
91 private StringBuilder patch = new StringBuilder();
92
93
94
95
96 private RE filesRegexp;
97
98
99
100
101
102 public GitDiffConsumer( ScmLogger logger, File workingDirectory )
103 {
104 this.logger = logger;
105 try
106 {
107 filesRegexp = new RE( DIFF_FILES_PATTERN );
108 }
109 catch ( RESyntaxException ex )
110 {
111 throw new RuntimeException(
112 "INTERNAL ERROR: Could not create regexp to parse git log file. Something is probably wrong with the oro installation.",
113 ex );
114 }
115
116 }
117
118
119
120
121
122
123 public void consumeLine( String line )
124 {
125 if ( filesRegexp.match( line ) )
126 {
127
128 currentFile = filesRegexp.getParen( 1 );
129
130 changedFiles.add( new ScmFile( currentFile, ScmFileStatus.MODIFIED ) );
131
132 currentDifference = new StringBuilder();
133
134 differences.put( currentFile, currentDifference );
135
136 patch.append( line ).append( "\n" );
137
138 return;
139 }
140
141 if ( currentFile == null )
142 {
143 if ( logger.isWarnEnabled() )
144 {
145 logger.warn( "Unparseable line: '" + line + "'" );
146 }
147 patch.append( line ).append( "\n" );
148 return;
149 }
150 else if ( line.startsWith( INDEX_LINE_TOKEN ) )
151 {
152
153 patch.append( line ).append( "\n" );
154 }
155 else if ( line.startsWith( NEW_FILE_MODE_TOKEN ) || line.startsWith( DELETED_FILE_MODE_TOKEN ) )
156 {
157
158 patch.append( line ).append( "\n" );
159 }
160 else if ( line.startsWith( START_REVISION_TOKEN ) )
161 {
162
163 patch.append( line ).append( "\n" );
164 }
165 else if ( line.startsWith( END_REVISION_TOKEN ) )
166 {
167
168 patch.append( line ).append( "\n" );
169 }
170 else if ( line.startsWith( ADDED_LINE_TOKEN ) || line.startsWith( REMOVED_LINE_TOKEN )
171 || line.startsWith( UNCHANGED_LINE_TOKEN ) || line.startsWith( CHANGE_SEPARATOR_TOKEN )
172 || line.equals( NO_NEWLINE_TOKEN ) )
173 {
174
175 currentDifference.append( line ).append( "\n" );
176 patch.append( line ).append( "\n" );
177 }
178 else
179 {
180
181
182 if ( logger.isWarnEnabled() )
183 {
184 logger.warn( "Unparseable line: '" + line + "'" );
185 }
186 patch.append( line ).append( "\n" );
187
188 currentFile = null;
189 currentDifference = null;
190 }
191 }
192
193 public List<ScmFile> getChangedFiles()
194 {
195 return changedFiles;
196 }
197
198 public Map<String,CharSequence> getDifferences()
199 {
200 return differences;
201 }
202
203 public String getPatch()
204 {
205 return patch.toString();
206 }
207
208 }