| /* |
| * Copyright 2013-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.java; |
| |
| import static java.util.jar.Attributes.Name.IMPLEMENTATION_VERSION; |
| import static java.util.jar.Attributes.Name.MANIFEST_VERSION; |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.assertTrue; |
| |
| import com.facebook.buck.step.ExecutionContext; |
| import com.facebook.buck.step.TestExecutionContext; |
| import com.facebook.buck.testutil.Zip; |
| import com.facebook.buck.util.ProjectFilesystem; |
| import com.facebook.buck.zip.CustomZipOutputStream; |
| import com.facebook.buck.zip.ZipOutputStreams; |
| import com.google.common.collect.ImmutableSet; |
| |
| import org.junit.Rule; |
| import org.junit.Test; |
| import org.junit.rules.TemporaryFolder; |
| |
| import java.io.ByteArrayInputStream; |
| import java.io.File; |
| import java.io.FileOutputStream; |
| import java.io.IOException; |
| import java.util.Set; |
| import java.util.jar.Manifest; |
| import java.util.zip.ZipEntry; |
| |
| public class JarDirectoryStepTest { |
| |
| @Rule public TemporaryFolder folder = new TemporaryFolder(); |
| |
| @Test |
| public void shouldNotThrowAnExceptionWhenAddingDuplicateEntries() throws IOException { |
| File zipup = folder.newFolder("zipup"); |
| |
| File first = createZip(new File(zipup, "a.zip"), "example.txt"); |
| File second = createZip(new File(zipup, "b.zip"), "example.txt"); |
| |
| JarDirectoryStep step = new JarDirectoryStep("output.jar", |
| ImmutableSet.of(first.getName(), second.getName()), |
| "com.example.Main", |
| /* manifest file */ null); |
| ExecutionContext context = TestExecutionContext.newBuilder() |
| .setProjectFilesystem(new ProjectFilesystem(zipup)) |
| .build(); |
| |
| int returnCode = step.execute(context); |
| |
| assertEquals(0, returnCode); |
| |
| File zip = new File(zipup, "output.jar"); |
| assertTrue(zip.exists()); |
| |
| // "example.txt" and the MANIFEST.MF. |
| assertZipFileCountIs(2, zip); |
| assertZipContains(zip, "example.txt"); |
| } |
| |
| @Test |
| public void shouldNotComplainWhenDuplicateDirectoryNamesAreAdded() throws IOException { |
| File zipup = folder.newFolder(); |
| |
| File first = createZip(new File(zipup, "first.zip"), "dir/example.txt", "dir/root1file.txt"); |
| File second = createZip(new File(zipup, "second.zip"), "dir/example.txt", "dir/root2file.txt"); |
| |
| JarDirectoryStep step = new JarDirectoryStep("output.jar", |
| ImmutableSet.of(first.getName(), second.getName()), |
| "com.example.Main", |
| /* manifest file */ null); |
| |
| ExecutionContext context = TestExecutionContext.newBuilder() |
| .setProjectFilesystem(new ProjectFilesystem(zipup)) |
| .build(); |
| |
| int returnCode = step.execute(context); |
| |
| assertEquals(0, returnCode); |
| |
| File zip = new File(zipup, "output.jar"); |
| |
| // The three below plus the manifest. |
| assertZipFileCountIs(4, zip); |
| assertZipContains(zip, "dir/example.txt", "dir/root1file.txt", "dir/root2file.txt"); |
| } |
| |
| @Test |
| public void entriesFromTheGivenManifestShouldOverrideThoseInTheJars() throws IOException { |
| String expected = "1.4"; |
| // Write the manifest, setting the implementation version |
| File tmp = folder.newFolder(); |
| |
| Manifest manifest = new Manifest(); |
| manifest.getMainAttributes().putValue(MANIFEST_VERSION.toString(), "1.0"); |
| manifest.getMainAttributes().putValue(IMPLEMENTATION_VERSION.toString(), expected); |
| File manifestFile = new File(tmp, "manifest"); |
| try (FileOutputStream fos = new FileOutputStream(manifestFile)) { |
| manifest.write(fos); |
| } |
| |
| // Write another manifest, setting the implementation version to something else |
| manifest = new Manifest(); |
| manifest.getMainAttributes().putValue(MANIFEST_VERSION.toString(), "1.0"); |
| manifest.getMainAttributes().putValue(IMPLEMENTATION_VERSION.toString(), "1.0"); |
| |
| File input = new File(tmp, "input.jar"); |
| try (CustomZipOutputStream out = ZipOutputStreams.newOutputStream(input)) { |
| ZipEntry entry = new ZipEntry("META-INF/MANIFEST.MF"); |
| out.putNextEntry(entry); |
| manifest.write(out); |
| } |
| |
| File output = new File(tmp, "output.jar"); |
| JarDirectoryStep step = new JarDirectoryStep( |
| "output.jar", |
| ImmutableSet.of("input.jar"), |
| /* main class */ null, |
| "manifest"); |
| ExecutionContext context = TestExecutionContext.newBuilder() |
| .setProjectFilesystem(new ProjectFilesystem(tmp)) |
| .build(); |
| assertEquals(0, step.execute(context)); |
| |
| try (Zip zip = new Zip(output, false)) { |
| byte[] rawManifest = zip.readFully("META-INF/MANIFEST.MF"); |
| manifest = new Manifest(new ByteArrayInputStream(rawManifest)); |
| String version = manifest.getMainAttributes().getValue(IMPLEMENTATION_VERSION); |
| |
| assertEquals(expected, version); |
| } |
| } |
| |
| private File createZip(File zipFile, String... fileNames) throws IOException { |
| try (Zip zip = new Zip(zipFile, true)) { |
| for (String fileName : fileNames) { |
| zip.add(fileName, ""); |
| } |
| } |
| return zipFile; |
| } |
| |
| private void assertZipFileCountIs(int expected, File zip) throws IOException { |
| Set<String> fileNames = getFileNames(zip); |
| |
| assertEquals(fileNames.toString(), expected, fileNames.size()); |
| } |
| |
| private void assertZipContains(File zip, String... files) throws IOException { |
| final Set<String> contents = getFileNames(zip); |
| |
| for (String file : files) { |
| assertTrue(String.format("%s -> %s", file, contents), contents.contains(file)); |
| } |
| } |
| |
| private Set<String> getFileNames(File zipFile) throws IOException { |
| try (Zip zip = new Zip(zipFile, false)) { |
| return zip.getFileNames(); |
| } |
| } |
| |
| } |