| /* |
| * Copyright 2012-present Facebook, Inc. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); you may |
| * not use this file except in compliance with the License. You may obtain |
| * a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| * License for the specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| package com.facebook.buck.step.fs; |
| |
| import com.facebook.buck.shell.ShellStep; |
| import com.facebook.buck.step.ExecutionContext; |
| import com.facebook.buck.util.Verbosity; |
| import com.google.common.base.Preconditions; |
| import com.google.common.collect.ImmutableList; |
| import com.google.common.collect.ImmutableSet; |
| |
| import java.io.File; |
| import java.util.Set; |
| |
| /** |
| * A {@link com.facebook.buck.step.Step} that creates or updates a ZIP archive using {@code zip}. |
| * |
| * @see <a href="http://www.info-zip.org/mans/zip.html">ZIP</a> |
| */ |
| public class ZipStep extends ShellStep { |
| |
| public static final int MIN_COMPRESSION_LEVEL = 0; |
| public static final int DEFAULT_COMPRESSION_LEVEL = 6; |
| public static final int MAX_COMPRESSION_LEVEL = 9; |
| |
| /** |
| * These map to {@code zip} 'command modes' (as seen in man page). |
| * @see <a href="http://www.info-zip.org/mans/zip.html">ZIP</a> |
| */ |
| public static enum Mode { |
| /** |
| * Update existing entries and add new files. |
| * If the archive does not exist create it. This is the default mode. |
| */ |
| ADD(""), |
| /** |
| * Update existing entries if newer on the file system and add new files. |
| * If the archive does not exist issue warning then create a new archive. |
| */ |
| UPDATE("-u"), |
| /** |
| * Update existing entries of an archive if newer on the file system. |
| * Does not add new files to the archive. |
| */ |
| FRESHEN("-f"), |
| /** |
| * Select entries in an existing archive and delete them. |
| */ |
| DELETE("-d"); |
| |
| public final String arg; |
| |
| private Mode(String arg) { |
| this.arg = arg; |
| } |
| } |
| |
| private final Mode mode; |
| private final String pathToZipFile; |
| private final ImmutableSet<String> paths; |
| private final boolean junkPaths; |
| private final int compressionLevel; |
| |
| |
| /** |
| * Create a {@link ZipStep} to create or update a zip archive. |
| * |
| * Note that paths added to the archive are always relative to the working directory.<br/> |
| * For example, if you're in {@code /dir} and you add {@code file.txt}, you get |
| * an archive containing just the file. If you were in {@code /} and added |
| * {@code dir/file.txt}, you would get an archive containing the file within a directory. |
| * |
| * @param mode one of {@link ZipStep.Mode#ADD}, {@link ZipStep.Mode#UPDATE UPDATE}, |
| * {@link ZipStep.Mode#FRESHEN FRESHEN} or {@link ZipStep.Mode#DELETE DELETE}, as in the |
| * {@code zip} command. |
| * @param pathToZipFile path to archive to create or update |
| * @param paths a set of files and/or directories to work on. The entire working directory is |
| * assumed if this set is empty. |
| * @param junkPaths if {@code true}, the relative paths of added archive entries are discarded, |
| * i.e. they are all placed in the root of the archive. |
| * @param compressionLevel between 0 (store) and 9. |
| * @param workingDirectory working directory for {@code zip} command. |
| * If {@code null}, project directory root is used instead. |
| * |
| * @see <a href="http://www.info-zip.org/mans/zip.html">ZIP</a> |
| */ |
| public ZipStep( |
| Mode mode, |
| String pathToZipFile, |
| Set<String> paths, |
| boolean junkPaths, |
| int compressionLevel, |
| File workingDirectory) { |
| super(workingDirectory); |
| Preconditions.checkArgument(compressionLevel >= MIN_COMPRESSION_LEVEL && |
| compressionLevel <= MAX_COMPRESSION_LEVEL, "compressionLevel out of bounds."); |
| this.mode = mode; |
| this.pathToZipFile = Preconditions.checkNotNull(pathToZipFile); |
| this.paths = ImmutableSet.copyOf(Preconditions.checkNotNull(paths)); |
| this.junkPaths = junkPaths; |
| this.compressionLevel = compressionLevel; |
| } |
| |
| /** |
| * Create a {@link ZipStep} that adds an entire directory to an archive. The files directly in |
| * the directory will appear in the root of the archive. Default compression level is assumed. |
| * |
| * @param pathToZipFile path to archive to create or update |
| * @param directoryToAdd directory to add to the archive |
| * |
| * @see #ZipStep(Mode, String, Set, boolean, int, File) |
| */ |
| public ZipStep(String pathToZipFile, File directoryToAdd) { |
| this( |
| Mode.ADD, |
| pathToZipFile, |
| ImmutableSet.<String>of() /* pathsToAdd */, |
| false /* junkPaths */, |
| DEFAULT_COMPRESSION_LEVEL /* compressionLevel */, |
| Preconditions.checkNotNull(directoryToAdd)); |
| } |
| |
| @Override |
| protected ImmutableList<String> getShellCommandInternal(ExecutionContext context) { |
| ImmutableList.Builder<String> args = ImmutableList.builder(); |
| args.add("zip"); |
| |
| // What to do? |
| if (mode != Mode.ADD) { |
| args.add(mode.arg); |
| } |
| |
| Verbosity verbosity = context.getVerbosity(); |
| if (!verbosity.shouldUseVerbosityFlagIfAvailable()) { |
| if (verbosity.shouldPrintStandardInformation()) { |
| args.add("-q"); |
| } else { |
| args.add("-qq"); |
| } |
| } |
| |
| // Don't add extra fields, neither do the Android tools. |
| args.add("-X"); |
| |
| // recurse |
| args.add("-r"); |
| |
| // compression level |
| args.add("-" + compressionLevel); |
| |
| // unk paths |
| if (junkPaths) { |
| args.add("-j"); |
| } |
| |
| // destination archive |
| args.add(pathToZipFile); |
| |
| // files to add to archive |
| if (paths.isEmpty()) { |
| // Add the contents of workingDirectory to archive. |
| args.add("-i*"); |
| args.add("."); |
| } else { |
| // Add specified paths, relative to workingDirectory. |
| args.addAll(paths); |
| } |
| |
| return args.build(); |
| } |
| |
| @Override |
| public String getShortName() { |
| return "zip"; |
| } |
| |
| } |