summaryrefslogtreecommitdiffstats
path: root/sonar-batch
diff options
context:
space:
mode:
authorJulien HENRY <julien.henry@sonarsource.com>2013-11-26 15:28:00 +0100
committerJulien HENRY <julien.henry@sonarsource.com>2013-11-26 15:28:46 +0100
commit25fbc1708b8cc7787db574ff4f124b706930802d (patch)
treeaa0fb1a3e0d7350a9f04049dff9de891913a2c2e /sonar-batch
parent145913a4689d0e95f41ddecff499582607cf4b36 (diff)
downloadsonarqube-25fbc1708b8cc7787db574ff4f124b706930802d.tar.gz
sonarqube-25fbc1708b8cc7787db574ff4f124b706930802d.zip
SONAR-4830 Extract plugin dependencies in the cache
Diffstat (limited to 'sonar-batch')
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchPluginInstaller.java76
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchPluginRepository.java14
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/bootstrap/BootstrapContainer.java1
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchPluginInstallerTest.java77
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchPluginRepositoryTest.java48
-rw-r--r--sonar-batch/src/test/resources/org/sonar/batch/bootstrap/BatchPluginInstallerTest/sonar-checkstyle-plugin-2.8.jarbin0 -> 1026947 bytes
6 files changed, 179 insertions, 37 deletions
diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchPluginInstaller.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchPluginInstaller.java
new file mode 100644
index 00000000000..64086ef1cbb
--- /dev/null
+++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchPluginInstaller.java
@@ -0,0 +1,76 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.batch.bootstrap;
+
+import org.sonar.api.BatchComponent;
+import org.sonar.api.utils.ZipUtils;
+import org.sonar.core.plugins.DefaultPluginMetadata;
+import org.sonar.core.plugins.PluginInstaller;
+import org.sonar.home.cache.FileCache;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.zip.ZipEntry;
+
+public class BatchPluginInstaller extends PluginInstaller implements BatchComponent {
+
+ private FileCache cache;
+
+ public BatchPluginInstaller(FileCache cache) {
+ this.cache = cache;
+ }
+
+ public DefaultPluginMetadata installToCache(File pluginFile, boolean isCore) {
+ DefaultPluginMetadata metadata = extractMetadata(pluginFile, isCore);
+ install(metadata, null, pluginFile);
+ return metadata;
+ }
+
+ @Override
+ protected File extractPluginDependencies(File pluginFile, File pluginBasedir) throws IOException {
+ return cache.unzip(pluginFile);
+ }
+
+ private void copyDependencies(DefaultPluginMetadata metadata, File pluginFile, File pluginBasedir) throws IOException {
+ if (!metadata.getPathsToInternalDeps().isEmpty()) {
+ // needs to unzip the jar
+ File baseDir;
+ if (pluginBasedir == null) {
+ baseDir = cache.unzip(pluginFile);
+ } else {
+ ZipUtils.unzip(pluginFile, pluginBasedir, new LibFilter());
+ baseDir = pluginBasedir;
+ }
+ for (String depPath : metadata.getPathsToInternalDeps()) {
+ File dependency = new File(baseDir, depPath);
+ if (!dependency.isFile() || !dependency.exists()) {
+ throw new IllegalArgumentException("Dependency " + depPath + " can not be found in " + pluginFile.getName());
+ }
+ metadata.addDeployedFile(dependency);
+ }
+ }
+ }
+
+ private static final class LibFilter implements ZipUtils.ZipEntryFilter {
+ public boolean accept(ZipEntry entry) {
+ return entry.getName().startsWith("META-INF/lib");
+ }
+ }
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchPluginRepository.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchPluginRepository.java
index bcc4c0afd9c..b0ebab822af 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchPluginRepository.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchPluginRepository.java
@@ -30,9 +30,7 @@ import org.sonar.api.Plugin;
import org.sonar.api.config.Settings;
import org.sonar.api.platform.PluginMetadata;
import org.sonar.api.platform.PluginRepository;
-import org.sonar.api.utils.TempFolder;
import org.sonar.core.plugins.PluginClassloaders;
-import org.sonar.core.plugins.PluginInstaller;
import org.sonar.core.plugins.RemotePlugin;
import java.io.File;
@@ -54,14 +52,15 @@ public class BatchPluginRepository implements PluginRepository {
private Map<String, PluginMetadata> metadataByKey;
private Settings settings;
private PluginClassloaders classLoaders;
- private TempFolder tempDirectories;
private final AnalysisMode analysisMode;
+ private final BatchPluginInstaller pluginInstaller;
- public BatchPluginRepository(PluginDownloader pluginDownloader, TempFolder tempDirectories, Settings settings, AnalysisMode analysisMode) {
+ public BatchPluginRepository(PluginDownloader pluginDownloader, Settings settings, AnalysisMode analysisMode,
+ BatchPluginInstaller pluginInstaller) {
this.pluginDownloader = pluginDownloader;
- this.tempDirectories = tempDirectories;
this.settings = settings;
this.analysisMode = analysisMode;
+ this.pluginInstaller = pluginInstaller;
}
public void start() {
@@ -71,14 +70,11 @@ public class BatchPluginRepository implements PluginRepository {
void doStart(List<RemotePlugin> remotePlugins) {
PluginFilter filter = new PluginFilter(settings, analysisMode);
- PluginInstaller extractor = new PluginInstaller();
metadataByKey = Maps.newHashMap();
for (RemotePlugin remote : remotePlugins) {
if (filter.accepts(remote.getKey())) {
File pluginFile = pluginDownloader.downloadPlugin(remote);
- File targetDir = tempDirectories.newDir("plugins/" + remote.getKey());
- LOG.debug("Installing plugin {} into {}", remote.getKey(), targetDir.getAbsolutePath());
- PluginMetadata metadata = extractor.install(pluginFile, remote.isCore(), targetDir);
+ PluginMetadata metadata = pluginInstaller.installToCache(pluginFile, remote.isCore());
if (StringUtils.isBlank(metadata.getBasePlugin()) || filter.accepts(metadata.getBasePlugin())) {
metadataByKey.put(metadata.getKey(), metadata);
} else {
diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BootstrapContainer.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BootstrapContainer.java
index 13bb325e89d..502c092e8dc 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BootstrapContainer.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BootstrapContainer.java
@@ -82,6 +82,7 @@ public class BootstrapContainer extends ComponentContainer {
AnalysisMode.class,
PluginDownloader.class,
BatchPluginRepository.class,
+ BatchPluginInstaller.class,
BatchSettings.class,
ServerClient.class,
ExtensionInstaller.class,
diff --git a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchPluginInstallerTest.java b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchPluginInstallerTest.java
new file mode 100644
index 00000000000..eb35381c476
--- /dev/null
+++ b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchPluginInstallerTest.java
@@ -0,0 +1,77 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.batch.bootstrap;
+
+import org.apache.commons.io.FileUtils;
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.sonar.core.plugins.DefaultPluginMetadata;
+import org.sonar.home.cache.FileCacheBuilder;
+
+import java.io.File;
+import java.io.IOException;
+
+import static org.fest.assertions.Assertions.assertThat;
+
+public class BatchPluginInstallerTest {
+
+ private BatchPluginInstaller extractor;
+
+ @ClassRule
+ public static TemporaryFolder temporaryFolder = new TemporaryFolder();
+
+ private File userHome;
+
+ @Before
+ public void setUp() throws IOException {
+ userHome = temporaryFolder.newFolder();
+ extractor = new BatchPluginInstaller(new FileCacheBuilder().setUserHome(userHome).build());
+ }
+
+ @Test
+ public void should_copy_and_extract_dependencies() throws IOException {
+ File fileFromCache = getFileFromCache("sonar-checkstyle-plugin-2.8.jar");
+ DefaultPluginMetadata metadata = extractor.installToCache(fileFromCache, true);
+
+ assertThat(metadata.getKey()).isEqualTo("checkstyle");
+ assertThat(new File(fileFromCache.getParent(), "sonar-checkstyle-plugin-2.8.jar")).exists();
+ assertThat(new File(fileFromCache.getParent(), "sonar-checkstyle-plugin-2.8.jar_unzip/META-INF/lib/checkstyle-5.1.jar")).exists();
+ }
+
+ @Test
+ public void should_extract_only_dependencies() throws IOException {
+ File fileFromCache = getFileFromCache("sonar-checkstyle-plugin-2.8.jar");
+ extractor.installToCache(fileFromCache, true);
+
+ assertThat(new File(fileFromCache.getParent(), "sonar-checkstyle-plugin-2.8.jar")).exists();
+ assertThat(new File(fileFromCache.getParent(), "sonar-checkstyle-plugin-2.8.jar_unzip/META-INF/MANIFEST.MF")).doesNotExist();
+ assertThat(new File(fileFromCache.getParent(), "sonar-checkstyle-plugin-2.8.jar_unzip/org/sonar/plugins/checkstyle/CheckstyleVersion.class")).doesNotExist();
+ }
+
+ File getFileFromCache(String filename) throws IOException {
+ File src = FileUtils.toFile(BatchPluginInstallerTest.class.getResource("/org/sonar/batch/bootstrap/BatchPluginInstallerTest/" + filename));
+ File destFile = new File(new File(userHome, "" + filename.hashCode()), filename);
+ FileUtils.copyFile(src, destFile);
+ return destFile;
+ }
+
+}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchPluginRepositoryTest.java b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchPluginRepositoryTest.java
index 6ab8e5182fb..bb947f8b8c5 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchPluginRepositoryTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchPluginRepositoryTest.java
@@ -27,8 +27,9 @@ import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.sonar.api.CoreProperties;
import org.sonar.api.config.Settings;
-import org.sonar.api.utils.TempFolder;
import org.sonar.core.plugins.RemotePlugin;
+import org.sonar.home.cache.FileCache;
+import org.sonar.home.cache.FileCacheBuilder;
import org.sonar.test.TestUtils;
import java.io.File;
@@ -46,10 +47,14 @@ public class BatchPluginRepositoryTest {
private BatchPluginRepository repository;
private AnalysisMode mode;
+ private FileCache cache;
+ private File userHome;
@Before
- public void before() {
+ public void before() throws IOException {
mode = mock(AnalysisMode.class);
+ userHome = temp.newFolder();
+ cache = new FileCacheBuilder().setUserHome(userHome).build();
}
@After
@@ -61,15 +66,12 @@ public class BatchPluginRepositoryTest {
@Test
public void shouldLoadPlugin() throws IOException {
- TempFolder tempDirs = mock(TempFolder.class);
- File toDir = temp.newFolder();
- when(tempDirs.newDir("plugins/checkstyle")).thenReturn(toDir);
RemotePlugin checkstyle = new RemotePlugin("checkstyle", true);
PluginDownloader downloader = mock(PluginDownloader.class);
- when(downloader.downloadPlugin(checkstyle)).thenReturn(copyFile("sonar-checkstyle-plugin-2.8.jar"));
+ when(downloader.downloadPlugin(checkstyle)).thenReturn(fileFromCache("sonar-checkstyle-plugin-2.8.jar"));
- repository = new BatchPluginRepository(downloader, tempDirs, new Settings(), mode);
+ repository = new BatchPluginRepository(downloader, new Settings(), mode, new BatchPluginInstaller(cache));
repository.doStart(Arrays.asList(checkstyle));
@@ -81,19 +83,14 @@ public class BatchPluginRepositoryTest {
@Test
public void shouldLoadPluginExtension() throws IOException {
- TempFolder tempDirs = mock(TempFolder.class);
- File toDir1 = temp.newFolder();
- File toDir2 = temp.newFolder();
- when(tempDirs.newDir("plugins/checkstyle")).thenReturn(toDir1);
- when(tempDirs.newDir("plugins/checkstyleextensions")).thenReturn(toDir2);
RemotePlugin checkstyle = new RemotePlugin("checkstyle", true);
RemotePlugin checkstyleExt = new RemotePlugin("checkstyleextensions", false);
PluginDownloader downloader = mock(PluginDownloader.class);
- when(downloader.downloadPlugin(checkstyle)).thenReturn(copyFile("sonar-checkstyle-plugin-2.8.jar"));
- when(downloader.downloadPlugin(checkstyleExt)).thenReturn(copyFile("sonar-checkstyle-extensions-plugin-0.1-SNAPSHOT.jar"));
+ when(downloader.downloadPlugin(checkstyle)).thenReturn(fileFromCache("sonar-checkstyle-plugin-2.8.jar"));
+ when(downloader.downloadPlugin(checkstyleExt)).thenReturn(fileFromCache("sonar-checkstyle-extensions-plugin-0.1-SNAPSHOT.jar"));
- repository = new BatchPluginRepository(downloader, tempDirs, new Settings(), mode);
+ repository = new BatchPluginRepository(downloader, new Settings(), mode, new BatchPluginInstaller(cache));
repository.doStart(Arrays.asList(checkstyle, checkstyleExt));
@@ -106,33 +103,28 @@ public class BatchPluginRepositoryTest {
@Test
public void shouldExcludePluginAndItsExtensions() throws IOException {
- TempFolder tempDirs = mock(TempFolder.class);
- File toDir1 = temp.newFolder();
- File toDir2 = temp.newFolder();
- when(tempDirs.newDir("plugins/checkstyle")).thenReturn(toDir1);
- when(tempDirs.newDir("plugins/checkstyleextensions")).thenReturn(toDir2);
RemotePlugin checkstyle = new RemotePlugin("checkstyle", true);
RemotePlugin checkstyleExt = new RemotePlugin("checkstyleextensions", false);
PluginDownloader downloader = mock(PluginDownloader.class);
- when(downloader.downloadPlugin(checkstyle)).thenReturn(copyFile("sonar-checkstyle-plugin-2.8.jar"));
- when(downloader.downloadPlugin(checkstyleExt)).thenReturn(copyFile("sonar-checkstyle-extensions-plugin-0.1-SNAPSHOT.jar"));
+ when(downloader.downloadPlugin(checkstyle)).thenReturn(fileFromCache("sonar-checkstyle-plugin-2.8.jar"));
+ when(downloader.downloadPlugin(checkstyleExt)).thenReturn(fileFromCache("sonar-checkstyle-extensions-plugin-0.1-SNAPSHOT.jar"));
Settings settings = new Settings();
settings.setProperty(CoreProperties.BATCH_EXCLUDE_PLUGINS, "checkstyle");
- repository = new BatchPluginRepository(downloader, tempDirs, settings, mode);
+ repository = new BatchPluginRepository(downloader, settings, mode, new BatchPluginInstaller(cache));
repository.doStart(Arrays.asList(checkstyle, checkstyleExt));
assertThat(repository.getMetadata()).isEmpty();
}
- private File copyFile(String filename) throws IOException {
+ private File fileFromCache(String filename) throws IOException {
File file = TestUtils.getResource("/org/sonar/batch/bootstrap/BatchPluginRepositoryTest/" + filename);
- File tempDir = new File("target/test-tmp/BatchPluginRepositoryTest");
- FileUtils.forceMkdir(tempDir);
- FileUtils.copyFileToDirectory(file, tempDir);
- return new File(tempDir, filename);
+ File destDir = new File(userHome, "cache/foomd5");
+ FileUtils.forceMkdir(destDir);
+ FileUtils.copyFileToDirectory(file, destDir);
+ return new File(destDir, filename);
}
@Test
diff --git a/sonar-batch/src/test/resources/org/sonar/batch/bootstrap/BatchPluginInstallerTest/sonar-checkstyle-plugin-2.8.jar b/sonar-batch/src/test/resources/org/sonar/batch/bootstrap/BatchPluginInstallerTest/sonar-checkstyle-plugin-2.8.jar
new file mode 100644
index 00000000000..f937399bec5
--- /dev/null
+++ b/sonar-batch/src/test/resources/org/sonar/batch/bootstrap/BatchPluginInstallerTest/sonar-checkstyle-plugin-2.8.jar
Binary files differ