diff options
author | Julien HENRY <julien.henry@sonarsource.com> | 2017-08-08 15:23:15 +0200 |
---|---|---|
committer | Julien HENRY <julien.henry@sonarsource.com> | 2017-09-07 08:33:31 +0200 |
commit | 6f777618d0ec3283600bccaae820a8b8783356db (patch) | |
tree | e0045b4286c4c67b0bbff27fc83a10828f95dcf9 /sonar-scanner-engine/src/main/java/org/sonar/scanner | |
parent | e4ec4b3ee79847c5bbbdce748982e4f1f18f7753 (diff) | |
download | sonarqube-6f777618d0ec3283600bccaae820a8b8783356db.tar.gz sonarqube-6f777618d0ec3283600bccaae820a8b8783356db.zip |
SONAR-9679 Add plugins and their updated_at date to the scanner report
Diffstat (limited to 'sonar-scanner-engine/src/main/java/org/sonar/scanner')
6 files changed, 121 insertions, 40 deletions
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/PluginInstaller.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/PluginInstaller.java index 8465d10093c..aeba67788c2 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/PluginInstaller.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/PluginInstaller.java @@ -19,10 +19,9 @@ */ package org.sonar.scanner.bootstrap; +import java.util.List; import java.util.Map; -import org.sonar.api.Plugin; import org.sonar.api.batch.ScannerSide; -import org.sonar.core.platform.PluginInfo; @ScannerSide public interface PluginInstaller { @@ -32,11 +31,11 @@ public interface PluginInstaller { * already in local cache. * @return information about all installed plugins, grouped by key */ - Map<String, PluginInfo> installRemotes(); + Map<String, ScannerPlugin> installRemotes(); /** - * Used only by tests. + * Used only by medium tests. * @see org.sonar.scanner.mediumtest.ScannerMediumTester */ - Map<String, Plugin> installLocals(); + List<Object[]> installLocals(); } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/ScannerPlugin.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/ScannerPlugin.java new file mode 100644 index 00000000000..86f7672e461 --- /dev/null +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/ScannerPlugin.java @@ -0,0 +1,57 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 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.scanner.bootstrap; + +import org.sonar.core.platform.PluginInfo; +import org.sonar.updatecenter.common.Version; + +public class ScannerPlugin { + + private final String key; + private final long updatedAt; + private final PluginInfo info; + + public ScannerPlugin(String key, long updatedAt, PluginInfo info) { + this.key = key; + this.updatedAt = updatedAt; + this.info = info; + } + + public PluginInfo getInfo() { + return info; + } + + public String getName() { + return info.getName(); + } + + public Version getVersion() { + return info.getVersion(); + } + + public String getKey() { + return key; + } + + public long getUpdatedAt() { + return updatedAt; + } + +} diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/ScannerPluginInstaller.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/ScannerPluginInstaller.java index a8f40fdb6e1..a37a98d3a79 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/ScannerPluginInstaller.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/ScannerPluginInstaller.java @@ -27,9 +27,9 @@ import java.io.InputStream; import java.io.Reader; import java.util.Collections; import java.util.HashMap; +import java.util.List; import java.util.Map; import org.apache.commons.io.FileUtils; -import org.sonar.api.Plugin; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; import org.sonar.api.utils.log.Profiler; @@ -60,12 +60,12 @@ public class ScannerPluginInstaller implements PluginInstaller { } @Override - public Map<String, PluginInfo> installRemotes() { + public Map<String, ScannerPlugin> installRemotes() { return loadPlugins(listInstalledPlugins()); } - private Map<String, PluginInfo> loadPlugins(InstalledPlugin[] remotePlugins) { - Map<String, PluginInfo> infosByKey = new HashMap<>(remotePlugins.length); + private Map<String, ScannerPlugin> loadPlugins(InstalledPlugin[] remotePlugins) { + Map<String, ScannerPlugin> infosByKey = new HashMap<>(remotePlugins.length); Profiler profiler = Profiler.create(LOG).startDebug("Load plugins"); @@ -73,7 +73,7 @@ public class ScannerPluginInstaller implements PluginInstaller { if (pluginPredicate.apply(installedPlugin.key)) { File jarFile = download(installedPlugin); PluginInfo info = PluginInfo.create(jarFile); - infosByKey.put(info.getKey(), info); + infosByKey.put(info.getKey(), new ScannerPlugin(installedPlugin.key, installedPlugin.updatedAt, info)); } } @@ -82,12 +82,12 @@ public class ScannerPluginInstaller implements PluginInstaller { } /** - * Returns empty on purpose. This method is used only by tests. + * Returns empty on purpose. This method is used only by medium tests. * @see org.sonar.scanner.mediumtest.ScannerMediumTester */ @Override - public Map<String, Plugin> installLocals() { - return Collections.emptyMap(); + public List<Object[]> installLocals() { + return Collections.emptyList(); } @VisibleForTesting @@ -125,6 +125,7 @@ public class ScannerPluginInstaller implements PluginInstaller { String key; String hash; String filename; + long updatedAt; } private class FileDownloader implements FileCache.Downloader { diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/ScannerPluginRepository.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/ScannerPluginRepository.java index d8d9c6a9536..2db16dc26ef 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/ScannerPluginRepository.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/ScannerPluginRepository.java @@ -23,6 +23,7 @@ import com.google.common.base.Preconditions; import java.util.Collection; import java.util.HashMap; import java.util.Map; +import java.util.function.Function; import javax.annotation.CheckForNull; import org.picocontainer.Startable; import org.sonar.api.Plugin; @@ -32,6 +33,9 @@ import org.sonar.core.platform.PluginInfo; import org.sonar.core.platform.PluginLoader; import org.sonar.core.platform.PluginRepository; +import static java.util.stream.Collectors.toList; +import static java.util.stream.Collectors.toMap; + /** * Orchestrates the installation and loading of plugins */ @@ -42,7 +46,7 @@ public class ScannerPluginRepository implements PluginRepository, Startable { private final PluginLoader loader; private Map<String, Plugin> pluginInstancesByKeys; - private Map<String, PluginInfo> infosByKeys; + private Map<String, ScannerPlugin> pluginsByKeys; private Map<ClassLoader, String> keysByClassLoader; public ScannerPluginRepository(PluginInstaller installer, PluginLoader loader) { @@ -52,15 +56,18 @@ public class ScannerPluginRepository implements PluginRepository, Startable { @Override public void start() { - infosByKeys = new HashMap<>(installer.installRemotes()); - pluginInstancesByKeys = new HashMap<>(loader.load(infosByKeys)); - - // this part is only used by tests - for (Map.Entry<String, Plugin> entry : installer.installLocals().entrySet()) { - String pluginKey = entry.getKey(); + pluginsByKeys = new HashMap<>(installer.installRemotes()); + pluginInstancesByKeys = new HashMap<>( + loader.load(pluginsByKeys.values().stream() + .map(ScannerPlugin::getInfo) + .collect(toMap(PluginInfo::getKey, Function.identity())))); + + // this part is only used by medium tests + for (Object[] localPlugin : installer.installLocals()) { + String pluginKey = (String) localPlugin[0]; PluginInfo pluginInfo = new PluginInfo(pluginKey); - infosByKeys.put(pluginKey, pluginInfo); - pluginInstancesByKeys.put(pluginKey, entry.getValue()); + pluginsByKeys.put(pluginKey, new ScannerPlugin(pluginInfo.getKey(), (long) localPlugin[2], pluginInfo)); + pluginInstancesByKeys.put(pluginKey, (Plugin) localPlugin[1]); } keysByClassLoader = new HashMap<>(); @@ -77,11 +84,11 @@ public class ScannerPluginRepository implements PluginRepository, Startable { } private void logPlugins() { - if (infosByKeys.isEmpty()) { + if (pluginsByKeys.isEmpty()) { LOG.debug("No plugins loaded"); } else { LOG.debug("Plugins:"); - for (PluginInfo p : infosByKeys.values()) { + for (ScannerPlugin p : pluginsByKeys.values()) { LOG.debug(" * {} {} ({})", p.getName(), p.getVersion(), p.getKey()); } } @@ -93,20 +100,24 @@ public class ScannerPluginRepository implements PluginRepository, Startable { loader.unload(pluginInstancesByKeys.values()); pluginInstancesByKeys.clear(); - infosByKeys.clear(); + pluginsByKeys.clear(); keysByClassLoader.clear(); } + public Map<String, ScannerPlugin> getPluginsByKey() { + return pluginsByKeys; + } + @Override public Collection<PluginInfo> getPluginInfos() { - return infosByKeys.values(); + return pluginsByKeys.values().stream().map(ScannerPlugin::getInfo).collect(toList()); } @Override public PluginInfo getPluginInfo(String key) { - PluginInfo info = infosByKeys.get(key); + ScannerPlugin info = pluginsByKeys.get(key); Preconditions.checkState(info != null, "Plugin [%s] does not exist", key); - return info; + return info.getInfo(); } @Override @@ -118,6 +129,6 @@ public class ScannerPluginRepository implements PluginRepository, Startable { @Override public boolean hasPlugin(String key) { - return infosByKeys.containsKey(key); + return pluginsByKeys.containsKey(key); } } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/mediumtest/FakePluginInstaller.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/mediumtest/FakePluginInstaller.java index 123dfe19ec0..8ba0187aedb 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/mediumtest/FakePluginInstaller.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/mediumtest/FakePluginInstaller.java @@ -20,34 +20,37 @@ package org.sonar.scanner.mediumtest; import java.io.File; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; import org.sonar.api.Plugin; import org.sonar.core.platform.PluginInfo; import org.sonar.scanner.bootstrap.PluginInstaller; +import org.sonar.scanner.bootstrap.ScannerPlugin; public class FakePluginInstaller implements PluginInstaller { - private final Map<String, PluginInfo> infosByKeys = new HashMap<>(); - private final Map<String, Plugin> instancesByKeys = new HashMap<>(); + private final Map<String, ScannerPlugin> pluginsByKeys = new HashMap<>(); + private final List<Object[]> mediumTestPlugins = new ArrayList<>(); - public FakePluginInstaller add(String pluginKey, File jarFile) { - infosByKeys.put(pluginKey, PluginInfo.create(jarFile)); + public FakePluginInstaller add(String pluginKey, File jarFile, long lastUpdatedAt) { + pluginsByKeys.put(pluginKey, new ScannerPlugin(pluginKey, lastUpdatedAt, PluginInfo.create(jarFile))); return this; } - public FakePluginInstaller add(String pluginKey, Plugin instance) { - instancesByKeys.put(pluginKey, instance); + public FakePluginInstaller add(String pluginKey, Plugin instance, long lastUpdatedAt) { + mediumTestPlugins.add(new Object[] {pluginKey, instance, lastUpdatedAt}); return this; } @Override - public Map<String, PluginInfo> installRemotes() { - return infosByKeys; + public Map<String, ScannerPlugin> installRemotes() { + return pluginsByKeys; } @Override - public Map<String, Plugin> installLocals() { - return instancesByKeys; + public List<Object[]> installLocals() { + return mediumTestPlugins; } } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/MetadataPublisher.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/MetadataPublisher.java index df162b78f24..15f0a0cfcf8 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/MetadataPublisher.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/MetadataPublisher.java @@ -19,6 +19,7 @@ */ package org.sonar.scanner.report; +import java.util.Map.Entry; import org.sonar.api.CoreProperties; import org.sonar.api.batch.AnalysisMode; import org.sonar.api.batch.bootstrap.ProjectDefinition; @@ -26,6 +27,8 @@ import org.sonar.api.batch.fs.internal.DefaultInputModule; import org.sonar.api.batch.fs.internal.InputModuleHierarchy; import org.sonar.api.config.Configuration; import org.sonar.scanner.ProjectAnalysisInfo; +import org.sonar.scanner.bootstrap.ScannerPlugin; +import org.sonar.scanner.bootstrap.ScannerPluginRepository; import org.sonar.scanner.cpd.CpdSettings; import org.sonar.scanner.protocol.output.ScannerReport; import org.sonar.scanner.protocol.output.ScannerReportWriter; @@ -40,15 +43,17 @@ public class MetadataPublisher implements ReportPublisherStep { private final InputModuleHierarchy moduleHierarchy; private final CpdSettings cpdSettings; private final AnalysisMode mode; + private final ScannerPluginRepository pluginRepository; public MetadataPublisher(ProjectAnalysisInfo projectAnalysisInfo, InputModuleHierarchy moduleHierarchy, Configuration settings, - ModuleQProfiles qProfiles, CpdSettings cpdSettings, AnalysisMode mode) { + ModuleQProfiles qProfiles, CpdSettings cpdSettings, AnalysisMode mode, ScannerPluginRepository pluginRepository) { this.projectAnalysisInfo = projectAnalysisInfo; this.moduleHierarchy = moduleHierarchy; this.settings = settings; this.qProfiles = qProfiles; this.cpdSettings = cpdSettings; this.mode = mode; + this.pluginRepository = pluginRepository; } @Override @@ -76,6 +81,11 @@ public class MetadataPublisher implements ReportPublisherStep { .setName(qp.getName()) .setRulesUpdatedAt(qp.getRulesUpdatedAt().getTime()).build()); } + for (Entry<String, ScannerPlugin> pluginEntry : pluginRepository.getPluginsByKey().entrySet()) { + builder.getMutablePluginsByKey().put(pluginEntry.getKey(), ScannerReport.Metadata.Plugin.newBuilder() + .setKey(pluginEntry.getKey()) + .setUpdatedAt(pluginEntry.getValue().getUpdatedAt()).build()); + } writer.writeMetadata(builder.build()); } } |