1 package org.apache.maven.plugins.scmpublish;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.commons.io.FileUtils;
23 import org.apache.commons.io.IOUtils;
24 import org.apache.commons.io.filefilter.NameFileFilter;
25 import org.apache.commons.io.filefilter.NotFileFilter;
26 import org.apache.maven.plugin.MojoExecutionException;
27 import org.apache.maven.plugin.MojoFailureException;
28 import org.apache.maven.plugins.annotations.Component;
29 import org.apache.maven.plugins.annotations.Mojo;
30 import org.apache.maven.plugins.annotations.Parameter;
31 import org.apache.maven.project.MavenProject;
32 import org.codehaus.plexus.util.MatchPatterns;
33
34 import java.io.BufferedReader;
35 import java.io.File;
36 import java.io.FileInputStream;
37 import java.io.FileOutputStream;
38 import java.io.IOException;
39 import java.io.InputStreamReader;
40 import java.io.OutputStreamWriter;
41 import java.io.PrintWriter;
42 import java.util.ArrayList;
43 import java.util.Arrays;
44 import java.util.Collections;
45 import java.util.HashSet;
46 import java.util.List;
47 import java.util.Set;
48
49
50
51
52
53
54 @Mojo ( name = "publish-scm", aggregator = true, requiresProject = false )
55 public class ScmPublishPublishScmMojo
56 extends AbstractScmPublishMojo
57 {
58
59
60
61 @Parameter ( property = "scmpublish.content", defaultValue = "${project.build.directory}/staging" )
62 private File content;
63
64
65
66 @Component
67 protected MavenProject project;
68
69 private List<File> deleted = new ArrayList<File>();
70
71 private List<File> added = new ArrayList<File>();
72
73 private List<File> updated = new ArrayList<File>();
74
75
76
77
78
79
80
81
82
83
84 private void update( File checkout, File dir, List<String> doNotDeleteDirs )
85 throws IOException
86 {
87 String[] files =
88 checkout.list( new NotFileFilter( new NameFileFilter( scmProvider.getScmSpecificFilename() ) ) );
89
90 Set<String> checkoutContent = new HashSet<String>( Arrays.asList( files ) );
91 List<String> dirContent = ( dir != null ) ? Arrays.asList( dir.list() ) : Collections.<String>emptyList();
92
93 Set<String> deleted = new HashSet<String>( checkoutContent );
94 deleted.removeAll( dirContent );
95
96 MatchPatterns ignoreDeleteMatchPatterns = null;
97 List<String> pathsAsList = new ArrayList<String>( 0 );
98 if ( ignorePathsToDelete != null && ignorePathsToDelete.length > 0 )
99 {
100 ignoreDeleteMatchPatterns = MatchPatterns.from( ignorePathsToDelete );
101 pathsAsList = Arrays.asList( ignorePathsToDelete );
102 }
103
104 for ( String name : deleted )
105 {
106 if ( ignoreDeleteMatchPatterns != null && ignoreDeleteMatchPatterns.matches( name, true ) )
107 {
108 getLog().debug(
109 name + " match one of the patterns '" + pathsAsList + "': do not add to deleted files" );
110 continue;
111 }
112 getLog().debug( "file marked for deletion:" + name );
113 File file = new File( checkout, name );
114
115 if ( ( doNotDeleteDirs != null ) && file.isDirectory() && ( doNotDeleteDirs.contains( name ) ) )
116 {
117
118 continue;
119 }
120
121 if ( file.isDirectory() )
122 {
123 update( file, null, null );
124 }
125 this.deleted.add( file );
126 }
127
128 for ( String name : dirContent )
129 {
130 File file = new File( checkout, name );
131 File source = new File( dir, name );
132
133 if ( source.isDirectory() )
134 {
135 if ( !checkoutContent.contains( name ) )
136 {
137 this.added.add( file );
138 file.mkdir();
139 }
140
141 update( file, source, null );
142 }
143 else
144 {
145 if ( checkoutContent.contains( name ) )
146 {
147 this.updated.add( file );
148 }
149 else
150 {
151 this.added.add( file );
152 }
153
154 copyFile( source, file );
155 }
156 }
157 }
158
159
160
161
162
163
164
165
166
167 private void copyFile( File srcFile, File destFile )
168 throws IOException
169 {
170 if ( requireNormalizeNewlines( srcFile ) )
171 {
172 copyAndNormalizeNewlines( srcFile, destFile );
173 }
174 else
175 {
176 FileUtils.copyFile( srcFile, destFile );
177 }
178 }
179
180
181
182
183
184
185
186
187 private void copyAndNormalizeNewlines( File srcFile, File destFile )
188 throws IOException
189 {
190 BufferedReader in = null;
191 PrintWriter out = null;
192 try
193 {
194 in = new BufferedReader( new InputStreamReader( new FileInputStream( srcFile ), siteOutputEncoding ) );
195 out = new PrintWriter( new OutputStreamWriter( new FileOutputStream( destFile ), siteOutputEncoding ) );
196 String line;
197 while ( ( line = in.readLine() ) != null )
198 {
199 if ( in.ready() )
200 {
201 out.println( line );
202 }
203 else
204 {
205 out.print( line );
206 }
207 }
208 }
209 finally
210 {
211 IOUtils.closeQuietly( out );
212 IOUtils.closeQuietly( in );
213 }
214 }
215
216 public void scmPublishExecute()
217 throws MojoExecutionException, MojoFailureException
218 {
219 if ( siteOutputEncoding == null )
220 {
221 getLog().warn( "No output encoding, defaulting to UTF-8." );
222 siteOutputEncoding = "utf-8";
223 }
224
225 if ( !content.exists() )
226 {
227 throw new MojoExecutionException( "Configured content directory does not exist: " + content );
228 }
229
230 if ( !content.canRead() )
231 {
232 throw new MojoExecutionException( "Can't read content directory: " + content );
233 }
234
235 checkoutExisting();
236
237 try
238 {
239 logInfo( "Updating content..." );
240 update( checkoutDirectory, content, ( project == null ) ? null : project.getModel().getModules() );
241 }
242 catch ( IOException ioe )
243 {
244 throw new MojoExecutionException( "Could not copy content to scm checkout", ioe );
245 }
246
247 logInfo( "Publish files: %d addition(s), %d update(s), %d delete(s)", added.size(), updated.size(),
248 deleted.size() );
249
250 if ( isDryRun() )
251 {
252 for ( File addedFile : added )
253 {
254 logInfo( "Added %s", addedFile.getAbsolutePath() );
255 }
256 for ( File deletedFile : deleted )
257 {
258 logInfo( "Deleted %s", deletedFile.getAbsolutePath() );
259 }
260 for ( File updatedFile : updated )
261 {
262 logInfo( "Updated %s", updatedFile.getAbsolutePath() );
263 }
264 return;
265 }
266
267 if ( !added.isEmpty() )
268 {
269 addFiles( added );
270 }
271
272 if ( !deleted.isEmpty() )
273 {
274 deleteFiles( deleted );
275 }
276
277 logInfo( "Checking in SCM..." );
278 checkinFiles();
279 }
280 }