View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.release.plugin.mojos;
18  
19  import java.io.File;
20  import java.io.IOException;
21  import java.io.InputStream;
22  import java.io.OutputStream;
23  import java.nio.file.Files;
24  import java.util.ArrayList;
25  import java.util.List;
26  import java.util.zip.ZipEntry;
27  import java.util.zip.ZipOutputStream;
28  
29  import org.apache.commons.io.IOUtils;
30  import org.apache.commons.lang3.StringUtils;
31  import org.apache.maven.plugin.AbstractMojo;
32  import org.apache.maven.plugin.MojoExecutionException;
33  import org.apache.maven.plugin.MojoFailureException;
34  import org.apache.maven.plugins.annotations.LifecyclePhase;
35  import org.apache.maven.plugins.annotations.Mojo;
36  import org.apache.maven.plugins.annotations.Parameter;
37  
38  /**
39   * Takes the built <code>./target/site</code> directory and compresses it to
40   * <code>./target/commons-release-plugin/site.zip</code>.
41   *
42   * @since 1.0
43   * @deprecated - as we no longer wish to compress the site, we are going to put this functionality in the
44   *               {@link CommonsDistributionStagingMojo}.
45   */
46  @Deprecated
47  @Mojo(name = "compress-site",
48          defaultPhase = LifecyclePhase.POST_SITE,
49          threadSafe = true,
50          aggregator = true)
51  public class CommonsSiteCompressionMojo extends AbstractMojo {
52  
53      /**
54       * The working directory for the plugin which, assuming the maven uses the default
55       * <code>${project.build.directory}</code>, this becomes <code>target/commons-release-plugin</code>.
56       */
57      @Parameter(defaultValue = "${project.build.directory}/commons-release-plugin",
58              property = "commons.outputDirectory")
59      private File workingDirectory;
60  
61      /**
62       */
63      @Parameter(defaultValue = "${project.build.directory}/site", property = "commons.siteOutputDirectory")
64      private File siteDirectory;
65  
66      /**
67       * The url of the subversion repository to which we wish the artifacts to be staged. Typically
68       * this would need to be of the form:
69       * <code>scm:svn:https://dist.apache.org/repos/dist/dev/commons/foo</code>. Note. that the prefix to the
70       * substring <code>https</code> is a requirement.
71       */
72      @Parameter(defaultValue = "", property = "commons.distSvnStagingUrl")
73      private String distSvnStagingUrl;
74  
75      /**
76       * A parameter to generally avoid running unless it is specifically turned on by the consuming module.
77       */
78      @Parameter(defaultValue = "false", property = "commons.release.isDistModule")
79      private Boolean isDistModule;
80  
81      /**
82       * The list of files to compress into the site.zip file.
83       */
84      private List<File> filesToCompress;
85  
86      @Override
87      public void execute() throws MojoExecutionException, MojoFailureException {
88          if (!isDistModule) {
89              getLog().info("This module is marked as a non distribution "
90                      + "or assembly module, and the plugin will not run.");
91              return;
92          }
93          if (StringUtils.isEmpty(distSvnStagingUrl)) {
94              getLog().warn("commons.distSvnStagingUrl is not set, the commons-release-plugin will not run.");
95              return;
96          }
97          if (!siteDirectory.exists()) {
98              getLog().error("\"mvn site\" was not run before this goal, or a siteDirectory did not exist.");
99              throw new MojoFailureException(
100                     "\"mvn site\" was not run before this goal, or a siteDirectory did not exist."
101             );
102         }
103         if (!workingDirectory.exists()) {
104             getLog().info("Current project contains no distributions. Not executing.");
105             return;
106         }
107         try {
108             filesToCompress = new ArrayList<>();
109             getAllSiteFiles(siteDirectory, filesToCompress);
110             writeZipFile(workingDirectory, siteDirectory, filesToCompress);
111         } catch (final IOException e) {
112             getLog().error("Failed to create ./target/commons-release-plugin/site.zip: " + e.getMessage(), e);
113             throw new MojoExecutionException(
114                     "Failed to create ./target/commons-release-plugin/site.zip: " + e.getMessage(),
115                     e
116             );
117         }
118     }
119 
120     /**
121      * By default this method iterates across the <code>target/site</code> directory and adds all the files
122      * to the {@link CommonsSiteCompressionMojo#filesToCompress} {@link List}.
123      *
124      * @param siteDirectory the {@link File} that represents the <code>target/site</code> directory.
125      * @param filesToCompress the {@link List} to which to add all the files.
126      */
127     private void getAllSiteFiles(final File siteDirectory, final List<File> filesToCompress) {
128         final File[] files = siteDirectory.listFiles();
129         for (final File file : files) {
130             filesToCompress.add(file);
131             if (file.isDirectory()) {
132                 getAllSiteFiles(file, filesToCompress);
133             }
134         }
135     }
136 
137     /**
138      * A helper method for writing all the files in our <code>fileList</code> to a <code>site.zip</code> file
139      * in the <code>workingDirectory</code>.
140      *
141      * @param outputDirectory is a {@link File} representing the place to put the site.zip file.
142      * @param directoryToZip is a {@link File} representing the directory of the site (normally
143      *                       <code>target/site</code>).
144      * @param fileList the list of files to be zipped up, generally generated by
145      *                 {@link CommonsSiteCompressionMojo#getAllSiteFiles(File, List)}.
146      * @throws IOException when the copying of the files goes incorrectly.
147      */
148     private void writeZipFile(final File outputDirectory, final File directoryToZip, final List<File> fileList)
149             throws IOException {
150         try (OutputStream fos = Files.newOutputStream(new File(outputDirectory.getAbsolutePath() + "/site.zip")
151                 .toPath());
152              ZipOutputStream zos = new ZipOutputStream(fos)) {
153             for (final File file : fileList) {
154                 if (!file.isDirectory()) { // we only ZIP files, not directories
155                     addToZip(directoryToZip, file, zos);
156                 }
157             }
158         }
159     }
160 
161     /**
162      * Given the <code>directoryToZip</code> we add the <code>file</code> to the ZIP archive represented by
163      * <code>zos</code>.
164      *
165      * @param directoryToZip a {@link File} representing the directory from which the file exists that we are
166      *                       compressing. Generally this is <code>target/site</code>.
167      * @param file a {@link File} to add to the {@link ZipOutputStream} <code>zos</code>.
168      * @param zos the {@link ZipOutputStream} to which to add our <code>file</code>.
169      * @throws IOException if adding the <code>file</code> doesn't work out properly.
170      */
171     private void addToZip(final File directoryToZip, final File file, final ZipOutputStream zos) throws IOException {
172         try (InputStream fis = Files.newInputStream(file.toPath())) {
173             // we want the zipEntry's path to be a relative path that is relative
174             // to the directory being zipped, so chop off the rest of the path
175             final String zipFilePath = file.getCanonicalPath().substring(
176                     directoryToZip.getCanonicalPath().length() + 1,
177                     file.getCanonicalPath().length());
178             final ZipEntry zipEntry = new ZipEntry(zipFilePath);
179             zos.putNextEntry(zipEntry);
180             IOUtils.copy(fis, zos);
181         }
182     }
183 }