import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
import org.sonar.api.utils.log.Profiler;
+import org.sonar.core.plugin.PluginType;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.plugin.PluginDto;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
import org.sonar.core.extension.PluginRiskConsent;
+import org.sonar.core.plugin.PluginType;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.property.PropertyDto;
import static org.apache.commons.io.FileUtils.moveFile;
import static org.sonar.core.util.FileUtils.deleteQuietly;
import static org.sonar.server.log.ServerProcessLogging.STARTUP_LOGGER_NAME;
-import static org.sonar.server.plugins.PluginType.BUNDLED;
-import static org.sonar.server.plugins.PluginType.EXTERNAL;
+import static org.sonar.core.plugin.PluginType.BUNDLED;
+import static org.sonar.core.plugin.PluginType.EXTERNAL;
public class PluginJarLoader {
private static final Logger LOG = Loggers.get(PluginJarLoader.class);
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2022 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.server.plugins;
-
-public enum PluginType {
- EXTERNAL, BUNDLED
-}
import static java.lang.String.format;
import static org.apache.commons.io.FileUtils.forceMkdir;
import static org.apache.commons.io.FileUtils.moveFileToDirectory;
-import static org.sonar.server.plugins.PluginType.EXTERNAL;
+import static org.sonar.core.plugin.PluginType.EXTERNAL;
public class PluginUninstaller implements Startable {
private static final Logger LOG = Loggers.get(PluginUninstaller.class);
import javax.annotation.Nullable;
import org.sonar.api.Plugin;
import org.sonar.core.platform.PluginInfo;
+import org.sonar.core.plugin.PluginType;
import org.sonar.server.plugins.PluginFilesAndMd5.FileAndMd5;
public class ServerPlugin {
import java.io.IOException;
import java.util.Objects;
import org.sonar.core.platform.PluginInfo;
+import org.sonar.core.plugin.PluginType;
import org.sonar.updatecenter.common.PluginManifest;
public class ServerPluginInfo extends PluginInfo {
import org.sonar.core.platform.ExplodedPlugin;
import org.sonar.core.platform.PluginClassLoader;
import org.sonar.core.platform.PluginJarExploder;
+import org.sonar.core.plugin.PluginType;
/**
* Entry point to install and load plugins on server startup. It manages
import org.sonar.api.Plugin;
import org.sonar.core.platform.PluginInfo;
import org.sonar.core.platform.PluginRepository;
+import org.sonar.core.plugin.PluginType;
import static com.google.common.base.Preconditions.checkArgument;
import static java.lang.String.format;
import org.junit.Test;
import org.sonar.api.Plugin;
import org.sonar.core.platform.PluginInfo;
+import org.sonar.core.plugin.PluginType;
import org.sonar.db.DbTester;
import org.sonar.db.plugin.PluginDto;
import org.sonar.server.plugins.PluginFilesAndMd5.FileAndMd5;
import static org.sonar.core.extension.PluginRiskConsent.ACCEPTED;
import static org.sonar.core.extension.PluginRiskConsent.NOT_ACCEPTED;
import static org.sonar.core.extension.PluginRiskConsent.REQUIRED;
-import static org.sonar.server.plugins.PluginType.BUNDLED;
-import static org.sonar.server.plugins.PluginType.EXTERNAL;
+import static org.sonar.core.plugin.PluginType.BUNDLED;
+import static org.sonar.core.plugin.PluginType.EXTERNAL;
public class PluginConsentVerifierTest {
@Rule
import org.sonar.api.Plugin;
import org.sonar.api.utils.log.LogTester;
import org.sonar.core.platform.PluginInfo;
+import org.sonar.core.plugin.PluginType;
import org.sonar.server.platform.ServerFileSystem;
import org.sonar.updatecenter.common.Version;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
-import static org.sonar.server.plugins.PluginType.BUNDLED;
-import static org.sonar.server.plugins.PluginType.EXTERNAL;
+import static org.sonar.core.plugin.PluginType.BUNDLED;
+import static org.sonar.core.plugin.PluginType.EXTERNAL;
public class PluginUninstallerTest {
@Rule
package org.sonar.server.plugins;
import org.junit.Test;
+import org.sonar.core.plugin.PluginType;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.sonar.server.plugins.PluginType.BUNDLED;
-import static org.sonar.server.plugins.PluginType.EXTERNAL;
+import static org.sonar.core.plugin.PluginType.BUNDLED;
+import static org.sonar.core.plugin.PluginType.EXTERNAL;
public class ServerPluginInfoTest {
@Test
import static org.mockito.ArgumentMatchers.anyList;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
-import static org.sonar.server.plugins.PluginType.EXTERNAL;
+import static org.sonar.core.plugin.PluginType.EXTERNAL;
public class ServerPluginManagerTest {
import org.junit.Test;
import org.sonar.api.Plugin;
import org.sonar.core.platform.PluginInfo;
+import org.sonar.core.plugin.PluginType;
import org.sonar.server.plugins.PluginFilesAndMd5.FileAndMd5;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
-import static org.sonar.server.plugins.PluginType.BUNDLED;
-import static org.sonar.server.plugins.PluginType.EXTERNAL;
+import static org.sonar.core.plugin.PluginType.BUNDLED;
+import static org.sonar.core.plugin.PluginType.EXTERNAL;
public class ServerPluginRepositoryTest {
private ServerPluginRepository repository = new ServerPluginRepository();
import org.sonar.core.platform.PluginInfo;
import org.sonar.process.systeminfo.SystemInfoSection;
import org.sonar.process.systeminfo.protobuf.ProtobufSystemInfo;
-import org.sonar.server.plugins.PluginType;
+import org.sonar.core.plugin.PluginType;
import org.sonar.server.plugins.ServerPluginRepository;
import org.sonar.updatecenter.common.Version;
import org.sonar.core.platform.PluginInfo;
import org.sonar.process.systeminfo.SystemInfoSection;
import org.sonar.process.systeminfo.protobuf.ProtobufSystemInfo;
-import org.sonar.server.plugins.PluginType;
+import org.sonar.core.plugin.PluginType;
import org.sonar.server.plugins.ServerPluginRepository;
import org.sonar.updatecenter.common.Version;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.plugin.PluginDto;
-import org.sonar.server.plugins.PluginType;
+import org.sonar.core.plugin.PluginType;
import org.sonar.server.plugins.ServerPlugin;
import org.sonar.server.plugins.ServerPluginRepository;
import org.junit.Test;
import org.sonar.core.platform.PluginInfo;
import org.sonar.process.systeminfo.protobuf.ProtobufSystemInfo;
-import org.sonar.server.plugins.PluginType;
+import org.sonar.core.plugin.PluginType;
import org.sonar.server.plugins.ServerPluginRepository;
import org.sonar.updatecenter.common.Version;
import org.junit.Test;
import org.sonar.core.platform.PluginInfo;
import org.sonar.process.systeminfo.protobuf.ProtobufSystemInfo;
-import org.sonar.server.plugins.PluginType;
+import org.sonar.core.plugin.PluginType;
import org.sonar.server.plugins.ServerPluginRepository;
import org.sonar.updatecenter.common.Version;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
-import static org.sonar.server.plugins.PluginType.BUNDLED;
+import static org.sonar.core.plugin.PluginType.BUNDLED;
public class GeneratePluginIndexTest {
import org.sonar.db.plugin.PluginDto;
import org.sonar.db.plugin.PluginDto.Type;
import org.sonar.server.plugins.PluginFilesAndMd5;
-import org.sonar.server.plugins.PluginType;
+import org.sonar.core.plugin.PluginType;
import org.sonar.server.plugins.ServerPlugin;
import org.sonar.server.plugins.ServerPluginRepository;
import org.sonar.db.DbSession;
import org.sonar.db.plugin.PluginDto;
import org.sonar.db.plugin.PluginDto.Type;
-import org.sonar.server.plugins.PluginType;
+import org.sonar.core.plugin.PluginType;
import org.sonar.server.plugins.ServerPlugin;
import org.sonar.server.plugins.ServerPluginRepository;
import org.sonar.server.plugins.UpdateCenterMatrixFactory;
ofNullable(installedPlugin).ifPresent(serverPlugin -> {
builder.setFilename(installedPlugin.getJar().getFile().getName());
builder.setHash(installedPlugin.getJar().getMd5());
+ builder.setType(installedPlugin.getType().name());
});
ofNullable(pluginInfo.getVersion()).ifPresent(v -> builder.setVersion(isNotBlank(pluginInfo.getDisplayVersion()) ? pluginInfo.getDisplayVersion() : v.getName()));
import org.sonar.core.platform.PluginInfo;
import org.sonar.server.exceptions.NotFoundException;
import org.sonar.server.plugins.PluginFilesAndMd5.FileAndMd5;
-import org.sonar.server.plugins.PluginType;
+import org.sonar.core.plugin.PluginType;
import org.sonar.server.plugins.ServerPlugin;
import org.sonar.server.plugins.ServerPluginRepository;
import org.sonar.server.ws.TestRequest;
import org.sonar.db.DbTester;
import org.sonar.db.plugin.PluginDto.Type;
import org.sonar.server.plugins.PluginFilesAndMd5.FileAndMd5;
-import org.sonar.server.plugins.PluginType;
+import org.sonar.core.plugin.PluginType;
import org.sonar.server.plugins.ServerPlugin;
import org.sonar.server.plugins.ServerPluginRepository;
import org.sonar.server.plugins.UpdateCenterMatrixFactory;
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2022 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.core.plugin;
+
+public enum PluginType {
+ EXTERNAL, BUNDLED
+}
package org.sonar.scanner.bootstrap;
import org.sonar.core.platform.PluginInfo;
+import org.sonar.core.plugin.PluginType;
import org.sonar.updatecenter.common.Version;
public class ScannerPlugin {
private final String key;
private final long updatedAt;
private final PluginInfo info;
+ private final PluginType type;
- public ScannerPlugin(String key, long updatedAt, PluginInfo info) {
+ public ScannerPlugin(String key, long updatedAt, PluginType type, PluginInfo info) {
this.key = key;
this.updatedAt = updatedAt;
+ this.type = type;
this.info = info;
}
return updatedAt;
}
+ public PluginType getType() {
+ return type;
+ }
}
import org.sonar.api.utils.log.Loggers;
import org.sonar.api.utils.log.Profiler;
import org.sonar.core.platform.PluginInfo;
+import org.sonar.core.plugin.PluginType;
import org.sonarqube.ws.client.GetRequest;
import static java.lang.String.format;
private Loaded loadPlugins(Map<String, ScannerPlugin> result) {
for (InstalledPlugin plugin : listInstalledPlugins()) {
Optional<File> jarFile = pluginFiles.get(plugin);
- if (!jarFile.isPresent()) {
+ if (jarFile.isEmpty()) {
return new Loaded(false, plugin.key);
}
PluginInfo info = PluginInfo.create(jarFile.get());
- result.put(info.getKey(), new ScannerPlugin(plugin.key, plugin.updatedAt, info));
+ result.put(info.getKey(), new ScannerPlugin(plugin.key, plugin.updatedAt, PluginType.valueOf(plugin.type), info));
}
return new Loaded(true, null);
}
String key;
String hash;
long updatedAt;
+ String type;
public InstalledPlugin() {
// http://stackoverflow.com/a/18645370/229031
import org.sonar.core.platform.PluginInfo;
import org.sonar.core.platform.PluginJarExploder;
import org.sonar.core.platform.PluginRepository;
+import org.sonar.core.plugin.PluginType;
import static java.util.stream.Collectors.toList;
import static org.sonar.api.utils.Preconditions.checkState;
for (Object[] localPlugin : installer.installLocals()) {
String pluginKey = (String) localPlugin[0];
PluginInfo pluginInfo = new PluginInfo(pluginKey);
- pluginsByKeys.put(pluginKey, new ScannerPlugin(pluginInfo.getKey(), (long) localPlugin[2], pluginInfo));
+ pluginsByKeys.put(pluginKey, new ScannerPlugin(pluginInfo.getKey(), (long) localPlugin[2], PluginType.BUNDLED, pluginInfo));
pluginInstancesByKeys.put(pluginKey, (Plugin) localPlugin[1]);
}
return pluginsByKeys.values().stream().map(ScannerPlugin::getInfo).collect(toList());
}
+ public Collection<PluginInfo> getExternalPluginsInfos() {
+ return pluginsByKeys.values().stream().filter(p -> p.getType() == PluginType.EXTERNAL).map(ScannerPlugin::getInfo).collect(toList());
+ }
+
+ public Collection<PluginInfo> getBundledPluginsInfos() {
+ return pluginsByKeys.values().stream().filter(p -> p.getType() == PluginType.BUNDLED).map(ScannerPlugin::getInfo).collect(toList());
+ }
+
@Override
public PluginInfo getPluginInfo(String key) {
ScannerPlugin info = pluginsByKeys.get(key);
import javax.annotation.Priority;
import org.sonar.api.Plugin;
import org.sonar.core.platform.PluginInfo;
+import org.sonar.core.plugin.PluginType;
import org.sonar.scanner.bootstrap.PluginInstaller;
import org.sonar.scanner.bootstrap.ScannerPlugin;
private final List<Object[]> mediumTestPlugins = new ArrayList<>();
public FakePluginInstaller add(String pluginKey, File jarFile, long lastUpdatedAt) {
- pluginsByKeys.put(pluginKey, new ScannerPlugin(pluginKey, lastUpdatedAt, PluginInfo.create(jarFile)));
+ pluginsByKeys.put(pluginKey, new ScannerPlugin(pluginKey, lastUpdatedAt, PluginType.BUNDLED, PluginInfo.create(jarFile)));
return this;
}
File analysisLog = writer.getFileStructure().analysisLog();
try (BufferedWriter fileWriter = Files.newBufferedWriter(analysisLog.toPath(), StandardCharsets.UTF_8)) {
writePlugins(fileWriter);
+ writeBundledAnalyzers(fileWriter);
writeGlobalSettings(fileWriter);
writeProjectSettings(fileWriter);
writeModulesSettings(fileWriter);
}
private void writePlugins(BufferedWriter fileWriter) throws IOException {
- fileWriter.write("SonarQube plugins:\n");
- for (PluginInfo p : pluginRepo.getPluginInfos()) {
+ fileWriter.write("Plugins:\n");
+ for (PluginInfo p : pluginRepo.getExternalPluginsInfos()) {
+ fileWriter.append(String.format(" - %s %s (%s)", p.getName(), p.getVersion(), p.getKey())).append('\n');
+ }
+ }
+
+ private void writeBundledAnalyzers(BufferedWriter fileWriter) throws IOException {
+ fileWriter.write("Bundled analyzers:\n");
+ for (PluginInfo p : pluginRepo.getBundledPluginsInfos()) {
fileWriter.append(String.format(" - %s %s (%s)", p.getName(), p.getVersion(), p.getKey())).append('\n');
}
}
import org.sonar.core.platform.PluginClassLoader;
import org.sonar.core.platform.PluginInfo;
import org.sonar.core.platform.PluginJarExploder;
+import org.sonar.core.plugin.PluginType;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.fail;
@Test
public void install_and_load_plugins() {
PluginInfo info = new PluginInfo("java");
- ImmutableMap<String, ScannerPlugin> plugins = ImmutableMap.of("java", new ScannerPlugin("java", 1L, info));
+ ImmutableMap<String, ScannerPlugin> plugins = ImmutableMap.of("java", new ScannerPlugin("java", 1L, PluginType.EXTERNAL, info));
Plugin instance = mock(Plugin.class);
when(loader.load(anyMap())).thenReturn(ImmutableMap.of("java", instance));
when(installer.installRemotes()).thenReturn(plugins);
assertThat(underTest.getPluginInfo("java")).isSameAs(info);
assertThat(underTest.getPluginInstance("java")).isSameAs(instance);
assertThat(underTest.getPluginInstances()).containsOnly(instance);
+ assertThat(underTest.getBundledPluginsInfos()).isEmpty();
+ assertThat(underTest.getExternalPluginsInfos()).isEqualTo(underTest.getPluginInfos());
underTest.stop();
verify(loader).unload(anyCollection());
import com.google.common.collect.ImmutableMap;
import java.io.File;
+import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.List;
public class AnalysisContextReportPublisherTest {
- private static final String BIZ = "BIZ";
- private static final String FOO = "FOO";
private static final String SONAR_SKIP = "sonar.skip";
private static final String COM_FOO = "com.foo";
@Rule
public TemporaryFolder temp = new TemporaryFolder();
- private ScannerPluginRepository pluginRepo = mock(ScannerPluginRepository.class);
+ private final ScannerPluginRepository pluginRepo = mock(ScannerPluginRepository.class);
private AnalysisContextReportPublisher publisher;
private System2 system2;
private GlobalServerSettings globalServerSettings;
@Test
public void shouldOnlyDumpPluginsByDefault() throws Exception {
- when(pluginRepo.getPluginInfos()).thenReturn(singletonList(new PluginInfo("xoo").setName("Xoo").setVersion(Version.create("1.0"))));
+ when(pluginRepo.getExternalPluginsInfos()).thenReturn(singletonList(new PluginInfo("xoo").setName("Xoo").setVersion(Version.create("1.0"))));
ScannerReportWriter writer = new ScannerReportWriter(temp.newFolder());
DefaultInputModule rootModule = new DefaultInputModule(ProjectDefinition.create()
List<String> lines = FileUtils.readLines(writer.getFileStructure().analysisLog(), StandardCharsets.UTF_8);
assertThat(lines).containsExactly(
- "SonarQube plugins:",
+ "Plugins:",
+ "Bundled analyzers:",
"Global server settings:",
"Project server settings:",
" - com.foo=bar",
List<String> lines = FileUtils.readLines(writer.getFileStructure().analysisLog(), StandardCharsets.UTF_8);
assertThat(lines).containsExactly(
- "SonarQube plugins:",
+ "Plugins:",
+ "Bundled analyzers:",
"Global server settings:",
"Project server settings:",
"Project scanner properties:",
" - sonar.projectKey=foo"
);
}
+
+ @Test
+ public void init_splitsPluginsByTypeInTheFile() throws IOException {
+ ScannerReportWriter writer = new ScannerReportWriter(temp.newFolder());
+ DefaultInputModule parent = new DefaultInputModule(ProjectDefinition.create()
+ .setBaseDir(temp.newFolder())
+ .setWorkDir(temp.newFolder())
+ .setProperty("sonar.projectKey", "parent")
+ .setProperty(SONAR_SKIP, "true"));
+ when(hierarchy.root()).thenReturn(parent);
+
+ when(pluginRepo.getExternalPluginsInfos()).thenReturn(List.of(new PluginInfo("xoo").setName("Xoo").setVersion(Version.create("1.0"))));
+ when(pluginRepo.getBundledPluginsInfos()).thenReturn(List.of(new PluginInfo("java").setName("Java").setVersion(Version.create("9.7"))));
+
+ publisher.init(writer);
+
+ List<String> lines = FileUtils.readLines(writer.getFileStructure().analysisLog(), StandardCharsets.UTF_8);
+
+ System.out.println(lines);
+
+ assertThat(lines).contains("Plugins:",
+ " - Xoo 1.0 (xoo)",
+ "Bundled analyzers:",
+ " - Java 9.7 (java)");
+ }
}
import org.sonar.api.batch.fs.internal.DefaultInputModule;
import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
import org.sonar.api.batch.scm.ScmProvider;
+import org.sonar.core.plugin.PluginType;
import org.sonar.scanner.ProjectInfo;
import org.sonar.scanner.bootstrap.ScannerPlugin;
import org.sonar.scanner.bootstrap.ScannerPluginRepository;
Date date = new Date();
when(qProfiles.findAll()).thenReturn(Collections.singletonList(new QProfile("q1", "Q1", "java", date)));
when(pluginRepository.getPluginsByKey()).thenReturn(ImmutableMap.of(
- "java", new ScannerPlugin("java", 12345L, null),
- "php", new ScannerPlugin("php", 45678L, null)));
+ "java", new ScannerPlugin("java", 12345L, PluginType.BUNDLED, null),
+ "php", new ScannerPlugin("php", 45678L, PluginType.BUNDLED, null)));
File outputDir = temp.newFolder();
ScannerReportWriter writer = new ScannerReportWriter(outputDir);
when(referenceBranchSupplier.getFromProperties()).thenReturn("newCodeReference");
{
"key": "scmgit",
"hash": "abc",
+ "type": "BUNDLED",
"updatedAt": 100
},
{
"key": "java",
"hash": "def",
+ "type": "EXTERNAL",
"updatedAt": 200
}
]
{
"key": "java",
"hash": "def",
+ "type": "BUNDLED",
"updatedAt": 200
},
{
"key": "cobol",
"hash": "ghi",
+ "type": "EXTERNAL",
"updatedAt": 300
}
]
{
"key": "scmgit",
"hash": "abc",
+ "type": "BUNDLED",
"updatedAt": 100
},
{
"key": "java",
"hash": "def",
+ "type": "EXTERNAL",
"updatedAt": 200
}
]
optional bool sonarLintSupported = 15;
optional string documentationPath = 16;
optional int64 updatedAt = 17;
+ optional string type = 18;
}
// WS api/plugins/pending