diff options
author | Julien HENRY <julien.henry@sonarsource.com> | 2013-10-02 16:00:16 +0200 |
---|---|---|
committer | Julien HENRY <julien.henry@sonarsource.com> | 2013-10-02 16:10:29 +0200 |
commit | d1ed91b890bfec5df267fff19faca781848be242 (patch) | |
tree | 12d724f59edc85c9bdc54d2c9fc5f4cde773b57e /plugins/sonar-core-plugin | |
parent | f6af69b24e93bb1262b9c02d8865e88cffa8d9a5 (diff) | |
download | sonarqube-d1ed91b890bfec5df267fff19faca781848be242.tar.gz sonarqube-d1ed91b890bfec5df267fff19faca781848be242.zip |
SONAR-2657 Expose changed files API in ModuleFileSystem
Diffstat (limited to 'plugins/sonar-core-plugin')
8 files changed, 208 insertions, 541 deletions
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java index 4fcf1dc68b3..adea1718036 100644 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java @@ -19,11 +19,12 @@ */ package org.sonar.plugins.core; -import org.sonar.plugins.core.batch.PartialScanFilter; - -import org.sonar.plugins.core.utils.HashBuilder; import com.google.common.collect.ImmutableList; -import org.sonar.api.*; +import org.sonar.api.CoreProperties; +import org.sonar.api.Properties; +import org.sonar.api.Property; +import org.sonar.api.PropertyType; +import org.sonar.api.SonarPlugin; import org.sonar.api.checks.NoSonarFilter; import org.sonar.api.config.PropertyDefinition; import org.sonar.api.resources.Java; @@ -35,21 +36,91 @@ import org.sonar.plugins.core.charts.DistributionAreaChart; import org.sonar.plugins.core.charts.DistributionBarChart; import org.sonar.plugins.core.charts.XradarChart; import org.sonar.plugins.core.colorizers.JavaColorizerFormat; -import org.sonar.plugins.core.dashboards.*; -import org.sonar.plugins.core.issue.*; +import org.sonar.plugins.core.dashboards.GlobalDefaultDashboard; +import org.sonar.plugins.core.dashboards.ProjectDefaultDashboard; +import org.sonar.plugins.core.dashboards.ProjectHotspotDashboard; +import org.sonar.plugins.core.dashboards.ProjectIssuesDashboard; +import org.sonar.plugins.core.dashboards.ProjectTimeMachineDashboard; +import org.sonar.plugins.core.issue.CountFalsePositivesDecorator; +import org.sonar.plugins.core.issue.CountUnresolvedIssuesDecorator; +import org.sonar.plugins.core.issue.InitialOpenIssuesSensor; +import org.sonar.plugins.core.issue.InitialOpenIssuesStack; +import org.sonar.plugins.core.issue.IssueHandlers; +import org.sonar.plugins.core.issue.IssueTracking; +import org.sonar.plugins.core.issue.IssueTrackingDecorator; +import org.sonar.plugins.core.issue.IssuesDensityDecorator; +import org.sonar.plugins.core.issue.WeightedIssuesDecorator; import org.sonar.plugins.core.issue.ignore.IgnoreIssuesPlugin; -import org.sonar.plugins.core.issue.notification.*; +import org.sonar.plugins.core.issue.notification.ChangesOnMyIssueNotificationDispatcher; +import org.sonar.plugins.core.issue.notification.IssueChangesEmailTemplate; +import org.sonar.plugins.core.issue.notification.NewFalsePositiveNotificationDispatcher; +import org.sonar.plugins.core.issue.notification.NewIssuesEmailTemplate; +import org.sonar.plugins.core.issue.notification.NewIssuesNotificationDispatcher; +import org.sonar.plugins.core.issue.notification.SendIssueNotificationsPostJob; import org.sonar.plugins.core.measurefilters.MyFavouritesFilter; import org.sonar.plugins.core.measurefilters.ProjectFilter; import org.sonar.plugins.core.notifications.alerts.NewAlerts; import org.sonar.plugins.core.security.ApplyProjectRolesDecorator; -import org.sonar.plugins.core.sensors.*; +import org.sonar.plugins.core.sensors.BranchCoverageDecorator; +import org.sonar.plugins.core.sensors.CheckAlertThresholds; +import org.sonar.plugins.core.sensors.CommentDensityDecorator; +import org.sonar.plugins.core.sensors.CoverageDecorator; +import org.sonar.plugins.core.sensors.CoverageMeasurementFilter; +import org.sonar.plugins.core.sensors.DirectoriesDecorator; +import org.sonar.plugins.core.sensors.FileHashSensor; +import org.sonar.plugins.core.sensors.FilesDecorator; +import org.sonar.plugins.core.sensors.GenerateAlertEvents; +import org.sonar.plugins.core.sensors.ItBranchCoverageDecorator; +import org.sonar.plugins.core.sensors.ItCoverageDecorator; +import org.sonar.plugins.core.sensors.ItLineCoverageDecorator; +import org.sonar.plugins.core.sensors.LineCoverageDecorator; +import org.sonar.plugins.core.sensors.ManualMeasureDecorator; +import org.sonar.plugins.core.sensors.OverallBranchCoverageDecorator; +import org.sonar.plugins.core.sensors.OverallCoverageDecorator; +import org.sonar.plugins.core.sensors.OverallLineCoverageDecorator; +import org.sonar.plugins.core.sensors.ProfileEventsSensor; +import org.sonar.plugins.core.sensors.ProfileSensor; +import org.sonar.plugins.core.sensors.ProjectLinksSensor; +import org.sonar.plugins.core.sensors.UnitTestDecorator; +import org.sonar.plugins.core.sensors.VersionEventsSensor; import org.sonar.plugins.core.technicaldebt.TechnicalDebtDecorator; -import org.sonar.plugins.core.timemachine.*; +import org.sonar.plugins.core.timemachine.NewCoverageAggregator; +import org.sonar.plugins.core.timemachine.NewCoverageFileAnalyzer; +import org.sonar.plugins.core.timemachine.NewItCoverageFileAnalyzer; +import org.sonar.plugins.core.timemachine.NewOverallCoverageFileAnalyzer; +import org.sonar.plugins.core.timemachine.TendencyDecorator; +import org.sonar.plugins.core.timemachine.TimeMachineConfigurationPersister; +import org.sonar.plugins.core.timemachine.VariationDecorator; import org.sonar.plugins.core.web.Lcom4Viewer; import org.sonar.plugins.core.web.TestsViewer; -import org.sonar.plugins.core.widgets.*; -import org.sonar.plugins.core.widgets.issues.*; +import org.sonar.plugins.core.widgets.AlertsWidget; +import org.sonar.plugins.core.widgets.ComplexityWidget; +import org.sonar.plugins.core.widgets.CoverageWidget; +import org.sonar.plugins.core.widgets.CustomMeasuresWidget; +import org.sonar.plugins.core.widgets.DescriptionWidget; +import org.sonar.plugins.core.widgets.DocumentationCommentsWidget; +import org.sonar.plugins.core.widgets.DuplicationsWidget; +import org.sonar.plugins.core.widgets.EventsWidget; +import org.sonar.plugins.core.widgets.HotspotMetricWidget; +import org.sonar.plugins.core.widgets.HotspotMostViolatedResourcesWidget; +import org.sonar.plugins.core.widgets.HotspotMostViolatedRulesWidget; +import org.sonar.plugins.core.widgets.ItCoverageWidget; +import org.sonar.plugins.core.widgets.MeasureFilterListWidget; +import org.sonar.plugins.core.widgets.MeasureFilterTreemapWidget; +import org.sonar.plugins.core.widgets.RulesWidget; +import org.sonar.plugins.core.widgets.SizeWidget; +import org.sonar.plugins.core.widgets.TechnicalDebtPyramidWidget; +import org.sonar.plugins.core.widgets.TechnicalDebtWidget; +import org.sonar.plugins.core.widgets.TimeMachineWidget; +import org.sonar.plugins.core.widgets.TimelineWidget; +import org.sonar.plugins.core.widgets.TreemapWidget; +import org.sonar.plugins.core.widgets.WelcomeWidget; +import org.sonar.plugins.core.widgets.issues.ActionPlansWidget; +import org.sonar.plugins.core.widgets.issues.FalsePositiveIssuesWidget; +import org.sonar.plugins.core.widgets.issues.IssueFilterWidget; +import org.sonar.plugins.core.widgets.issues.MyUnresolvedIssuesWidget; +import org.sonar.plugins.core.widgets.issues.UnresolvedIssuesPerAssigneeWidget; +import org.sonar.plugins.core.widgets.issues.UnresolvedIssuesStatusesWidget; import java.util.Arrays; import java.util.List; @@ -209,127 +280,125 @@ public final class CorePlugin extends SonarPlugin { ImmutableList.Builder<Object> extensions = ImmutableList.builder(); extensions.add( - DefaultResourceTypes.class, - UserManagedMetrics.class, - Periods.class, + DefaultResourceTypes.class, + UserManagedMetrics.class, + Periods.class, - // pages - Lcom4Viewer.class, - TestsViewer.class, + // pages + Lcom4Viewer.class, + TestsViewer.class, - // measure filters - ProjectFilter.class, - MyFavouritesFilter.class, + // measure filters + ProjectFilter.class, + MyFavouritesFilter.class, - // widgets - AlertsWidget.class, - CoverageWidget.class, - ItCoverageWidget.class, - DescriptionWidget.class, - ComplexityWidget.class, - RulesWidget.class, - SizeWidget.class, - EventsWidget.class, - CustomMeasuresWidget.class, - TimelineWidget.class, - TimeMachineWidget.class, - HotspotMetricWidget.class, - TreemapWidget.class, - MeasureFilterListWidget.class, - MeasureFilterTreemapWidget.class, - WelcomeWidget.class, - DocumentationCommentsWidget.class, - DuplicationsWidget.class, - TechnicalDebtWidget.class, - TechnicalDebtPyramidWidget.class, + // widgets + AlertsWidget.class, + CoverageWidget.class, + ItCoverageWidget.class, + DescriptionWidget.class, + ComplexityWidget.class, + RulesWidget.class, + SizeWidget.class, + EventsWidget.class, + CustomMeasuresWidget.class, + TimelineWidget.class, + TimeMachineWidget.class, + HotspotMetricWidget.class, + TreemapWidget.class, + MeasureFilterListWidget.class, + MeasureFilterTreemapWidget.class, + WelcomeWidget.class, + DocumentationCommentsWidget.class, + DuplicationsWidget.class, + TechnicalDebtWidget.class, + TechnicalDebtPyramidWidget.class, - // dashboards - ProjectDefaultDashboard.class, - ProjectHotspotDashboard.class, - ProjectIssuesDashboard.class, - ProjectTimeMachineDashboard.class, - GlobalDefaultDashboard.class, + // dashboards + ProjectDefaultDashboard.class, + ProjectHotspotDashboard.class, + ProjectIssuesDashboard.class, + ProjectTimeMachineDashboard.class, + GlobalDefaultDashboard.class, - // chart - XradarChart.class, - DistributionBarChart.class, - DistributionAreaChart.class, + // chart + XradarChart.class, + DistributionBarChart.class, + DistributionAreaChart.class, - // colorizers - JavaColorizerFormat.class, + // colorizers + JavaColorizerFormat.class, - // issues - IssueTrackingDecorator.class, - IssueTracking.class, - IssueHandlers.class, - CountUnresolvedIssuesDecorator.class, - CountFalsePositivesDecorator.class, - WeightedIssuesDecorator.class, - IssuesDensityDecorator.class, - InitialOpenIssuesSensor.class, - InitialOpenIssuesStack.class, - HotspotMostViolatedResourcesWidget.class, - HotspotMostViolatedRulesWidget.class, - MyUnresolvedIssuesWidget.class, - FalsePositiveIssuesWidget.class, - ActionPlansWidget.class, - UnresolvedIssuesPerAssigneeWidget.class, - UnresolvedIssuesStatusesWidget.class, - IssueFilterWidget.class, - org.sonar.api.issue.NoSonarFilter.class, + // issues + IssueTrackingDecorator.class, + IssueTracking.class, + IssueHandlers.class, + CountUnresolvedIssuesDecorator.class, + CountFalsePositivesDecorator.class, + WeightedIssuesDecorator.class, + IssuesDensityDecorator.class, + InitialOpenIssuesSensor.class, + InitialOpenIssuesStack.class, + HotspotMostViolatedResourcesWidget.class, + HotspotMostViolatedRulesWidget.class, + MyUnresolvedIssuesWidget.class, + FalsePositiveIssuesWidget.class, + ActionPlansWidget.class, + UnresolvedIssuesPerAssigneeWidget.class, + UnresolvedIssuesStatusesWidget.class, + IssueFilterWidget.class, + org.sonar.api.issue.NoSonarFilter.class, - // issue notifications - SendIssueNotificationsPostJob.class, - NewIssuesEmailTemplate.class, - IssueChangesEmailTemplate.class, - ChangesOnMyIssueNotificationDispatcher.class, - ChangesOnMyIssueNotificationDispatcher.newMetadata(), - NewIssuesNotificationDispatcher.class, - NewIssuesNotificationDispatcher.newMetadata(), - NewFalsePositiveNotificationDispatcher.class, - NewFalsePositiveNotificationDispatcher.newMetadata(), + // issue notifications + SendIssueNotificationsPostJob.class, + NewIssuesEmailTemplate.class, + IssueChangesEmailTemplate.class, + ChangesOnMyIssueNotificationDispatcher.class, + ChangesOnMyIssueNotificationDispatcher.newMetadata(), + NewIssuesNotificationDispatcher.class, + NewIssuesNotificationDispatcher.newMetadata(), + NewFalsePositiveNotificationDispatcher.class, + NewFalsePositiveNotificationDispatcher.newMetadata(), - // batch - ProfileSensor.class, - ProfileEventsSensor.class, - ProjectLinksSensor.class, - UnitTestDecorator.class, - VersionEventsSensor.class, - CheckAlertThresholds.class, - GenerateAlertEvents.class, - LineCoverageDecorator.class, - CoverageDecorator.class, - BranchCoverageDecorator.class, - ItLineCoverageDecorator.class, - ItCoverageDecorator.class, - ItBranchCoverageDecorator.class, - OverallLineCoverageDecorator.class, - OverallCoverageDecorator.class, - OverallBranchCoverageDecorator.class, - CoverageMeasurementFilter.class, - ApplyProjectRolesDecorator.class, - CommentDensityDecorator.class, - NoSonarFilter.class, - DirectoriesDecorator.class, - FilesDecorator.class, - IndexProjectPostJob.class, - ManualMeasureDecorator.class, - HashBuilder.class, - FileHashSensor.class, - PartialScanFilter.class, + // batch + ProfileSensor.class, + ProfileEventsSensor.class, + ProjectLinksSensor.class, + UnitTestDecorator.class, + VersionEventsSensor.class, + CheckAlertThresholds.class, + GenerateAlertEvents.class, + LineCoverageDecorator.class, + CoverageDecorator.class, + BranchCoverageDecorator.class, + ItLineCoverageDecorator.class, + ItCoverageDecorator.class, + ItBranchCoverageDecorator.class, + OverallLineCoverageDecorator.class, + OverallCoverageDecorator.class, + OverallBranchCoverageDecorator.class, + CoverageMeasurementFilter.class, + ApplyProjectRolesDecorator.class, + CommentDensityDecorator.class, + NoSonarFilter.class, + DirectoriesDecorator.class, + FilesDecorator.class, + IndexProjectPostJob.class, + ManualMeasureDecorator.class, + FileHashSensor.class, - // time machine - TendencyDecorator.class, - VariationDecorator.class, - TimeMachineConfigurationPersister.class, - NewCoverageFileAnalyzer.class, - NewItCoverageFileAnalyzer.class, - NewOverallCoverageFileAnalyzer.class, - NewCoverageAggregator.class, + // time machine + TendencyDecorator.class, + VariationDecorator.class, + TimeMachineConfigurationPersister.class, + NewCoverageFileAnalyzer.class, + NewItCoverageFileAnalyzer.class, + NewOverallCoverageFileAnalyzer.class, + NewCoverageAggregator.class, - // Notify alerts on my favourite projects - NewAlerts.class, - NewAlerts.newMetadata()); + // Notify alerts on my favourite projects + NewAlerts.class, + NewAlerts.newMetadata()); extensions.addAll(ExclusionProperties.definitions()); extensions.addAll(IgnoreIssuesPlugin.getExtensions()); @@ -341,7 +410,6 @@ public final class CorePlugin extends SonarPlugin { return extensions.build(); } - static List<PropertyDefinition> propertyDefinitions() { return Arrays.asList( PropertyDefinition.builder(CoreProperties.CORE_VIOLATION_LOCALE_PROPERTY) diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/batch/PartialScanFilter.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/batch/PartialScanFilter.java deleted file mode 100644 index 903a5ca36e4..00000000000 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/batch/PartialScanFilter.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * 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.plugins.core.batch; - -import com.google.common.collect.Maps; -import org.apache.commons.io.IOUtils; -import org.apache.commons.lang.StringUtils; -import org.picocontainer.Startable; -import org.sonar.api.CoreProperties; -import org.sonar.api.batch.bootstrap.ProjectDefinition; -import org.sonar.api.config.Settings; -import org.sonar.api.database.model.Snapshot; -import org.sonar.api.scan.filesystem.FileSystemFilter; -import org.sonar.api.scan.filesystem.PathResolver; -import org.sonar.api.utils.SonarException; -import org.sonar.batch.components.PastSnapshot; -import org.sonar.batch.components.PastSnapshotFinder; -import org.sonar.core.source.SnapshotDataType; -import org.sonar.core.source.jdbc.SnapshotDataDao; -import org.sonar.core.source.jdbc.SnapshotDataDto; -import org.sonar.plugins.core.utils.HashBuilder; - -import java.io.File; -import java.io.IOException; -import java.io.StringReader; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; -import java.util.Map; - -/** - * When enabled this filter will only allow modified files to be analyzed. - * @since 4.0 - */ -public class PartialScanFilter implements FileSystemFilter, Startable { - - private PathResolver pathResolver; - private HashBuilder hashBuilder; - private Settings settings; - private SnapshotDataDao snapshotDataDao; - private PastSnapshotFinder pastSnapshotFinder; - private Snapshot snapshot; - private ProjectDefinition module; - - private Map<String, String> fileHashMap = Maps.newHashMap(); - - public PartialScanFilter(Settings settings, ProjectDefinition module, PathResolver pathResolver, HashBuilder hashBuilder, - Snapshot snapshot, - SnapshotDataDao snapshotDataDao, - PastSnapshotFinder pastSnapshotFinder) { - this.settings = settings; - this.module = module; - this.pathResolver = pathResolver; - this.hashBuilder = hashBuilder; - this.snapshot = snapshot; - this.snapshotDataDao = snapshotDataDao; - this.pastSnapshotFinder = pastSnapshotFinder; - } - - @Override - public void start() { - // Extract previous checksum of all files of this module and store - // them in a map - if (settings.getBoolean(CoreProperties.PARTIAL_ANALYSIS)) { - if (!settings.getBoolean(CoreProperties.DRY_RUN)) { - throw new SonarException("Partial analysis is only supported with dry run mode"); - } - PastSnapshot pastSnapshot = pastSnapshotFinder.findPreviousAnalysis(snapshot); - if (pastSnapshot.isRelatedToSnapshot()) { - Collection<SnapshotDataDto> selectSnapshotData = snapshotDataDao.selectSnapshotData(pastSnapshot.getProjectSnapshot().getId().longValue(), - Arrays.asList(SnapshotDataType.FILE_HASH.getValue())); - if (!selectSnapshotData.isEmpty()) { - SnapshotDataDto snapshotDataDto = selectSnapshotData.iterator().next(); - String data = snapshotDataDto.getData(); - try { - List<String> lines = IOUtils.readLines(new StringReader(data)); - for (String line : lines) { - String[] keyValue = StringUtils.split(line, "="); - if (keyValue.length == 2) { - fileHashMap.put(keyValue[0], keyValue[1]); - } - } - } catch (IOException e) { - throw new SonarException("Unable to read previous file hashes", e); - } - } - } - } - } - - @Override - public void stop() { - } - - @Override - public boolean accept(File file, Context context) { - if (!settings.getBoolean(CoreProperties.PARTIAL_ANALYSIS)) { - return true; - } - String relativePath = pathResolver.relativePath(module.getBaseDir(), file); - String previousHash = fileHashMap.get(relativePath); - if (previousHash == null) { - return true; - } - String currentHash = hashBuilder.computeHash(file); - return !currentHash.equals(previousHash); - } - -} diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/FileHashSensor.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/FileHashSensor.java index 8e3f8d0600e..93c943a3490 100644 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/FileHashSensor.java +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/FileHashSensor.java @@ -27,30 +27,30 @@ import org.sonar.api.scan.filesystem.FileType; import org.sonar.api.scan.filesystem.ModuleFileSystem; import org.sonar.api.scan.filesystem.PathResolver; import org.sonar.batch.index.ComponentDataCache; +import org.sonar.batch.scan.filesystem.FileHashCache; import org.sonar.core.source.SnapshotDataType; -import org.sonar.plugins.core.utils.HashBuilder; import java.io.File; import java.util.List; /** - * This sensor will compute md5 checksum of each file of the current module and store it in DB + * This sensor will retrieve hash of each file of the current module and store it in DB * in order to compare it during next analysis and see if the file was modified. - * This is used by the partial analysis mode. - * @see org.sonar.plugins.core.batch.PartialScanFilter + * This is used by the incremental preview mode. + * @see org.sonar.plugins.core.batch.IncrementalPreviewFilter * @since 4.0 */ public final class FileHashSensor implements Sensor { private ModuleFileSystem moduleFileSystem; private PathResolver pathResolver; - private HashBuilder hashBuilder; private ComponentDataCache componentDataCache; + private FileHashCache fileHashCache; - public FileHashSensor(ModuleFileSystem moduleFileSystem, PathResolver pathResolver, HashBuilder hashBuilder, ComponentDataCache componentDataCache) { + public FileHashSensor(FileHashCache fileHashCache, ModuleFileSystem moduleFileSystem, PathResolver pathResolver, ComponentDataCache componentDataCache) { + this.fileHashCache = fileHashCache; this.moduleFileSystem = moduleFileSystem; this.pathResolver = pathResolver; - this.hashBuilder = hashBuilder; this.componentDataCache = componentDataCache; } @@ -69,8 +69,8 @@ public final class FileHashSensor implements Sensor { private void analyse(StringBuilder fileHashMap, Project project, FileType fileType) { List<File> files = moduleFileSystem.files(FileQuery.on(fileType).onLanguage(project.getLanguageKey())); for (File file : files) { - String md5 = hashBuilder.computeHash(file); - fileHashMap.append(pathResolver.relativePath(moduleFileSystem.baseDir(), file)).append("=").append(md5).append("\n"); + String hash = fileHashCache.getCurrentHash(file); + fileHashMap.append(pathResolver.relativePath(moduleFileSystem.baseDir(), file)).append("=").append(hash).append("\n"); } } diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/utils/HashBuilder.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/utils/HashBuilder.java deleted file mode 100644 index 87b78a11c77..00000000000 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/utils/HashBuilder.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * 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.plugins.core.utils; - -import org.apache.commons.io.IOUtils; -import org.sonar.api.BatchExtension; -import org.sonar.api.utils.SonarException; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; - -/** - * @since 4.0 - */ -public final class HashBuilder implements BatchExtension { - - public String computeHash(File file) { - FileInputStream fis = null; - try { - fis = new FileInputStream(file); - return org.apache.commons.codec.digest.DigestUtils.md5Hex(fis); - } catch (IOException e) { - throw new SonarException("Unable to compute file hash", e); - } finally { - IOUtils.closeQuietly(fis); - } - } -} diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/utils/package-info.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/utils/package-info.java deleted file mode 100644 index 6d0f75f915b..00000000000 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/utils/package-info.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * 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. - */ -@ParametersAreNonnullByDefault -package org.sonar.plugins.core.utils; - -import javax.annotation.ParametersAreNonnullByDefault; diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/batch/PartialScanFilterTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/batch/PartialScanFilterTest.java deleted file mode 100644 index 7cd784988d9..00000000000 --- a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/batch/PartialScanFilterTest.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - * 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.plugins.core.batch; - -import org.apache.commons.io.FileUtils; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.junit.rules.TemporaryFolder; -import org.sonar.api.CoreProperties; -import org.sonar.api.batch.bootstrap.ProjectDefinition; -import org.sonar.api.config.Settings; -import org.sonar.api.database.model.Snapshot; -import org.sonar.api.scan.filesystem.FileSystemFilter; -import org.sonar.api.scan.filesystem.PathResolver; -import org.sonar.api.utils.SonarException; -import org.sonar.batch.components.PastSnapshot; -import org.sonar.batch.components.PastSnapshotFinder; -import org.sonar.core.source.SnapshotDataType; -import org.sonar.core.source.jdbc.SnapshotDataDao; -import org.sonar.core.source.jdbc.SnapshotDataDto; -import org.sonar.plugins.core.utils.HashBuilder; - -import java.io.File; -import java.util.Arrays; -import java.util.Date; - -import static org.fest.assertions.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -public class PartialScanFilterTest { - - @Rule - public TemporaryFolder temp = new TemporaryFolder(); - - @Rule - public ExpectedException thrown = ExpectedException.none(); - - private PartialScanFilter filter; - - private Settings settings; - - private PastSnapshotFinder pastSnapshotFinder; - - private Snapshot snapshot; - - private File baseDir; - - private SnapshotDataDao snapshotDataDao; - - @Before - public void prepare() throws Exception { - settings = new Settings(); - pastSnapshotFinder = mock(PastSnapshotFinder.class); - snapshot = mock(Snapshot.class); - baseDir = temp.newFolder(); - snapshotDataDao = mock(SnapshotDataDao.class); - filter = new PartialScanFilter(settings, ProjectDefinition.create().setBaseDir(baseDir), new PathResolver(), new HashBuilder(), snapshot, - snapshotDataDao, pastSnapshotFinder); - } - - @Test - public void should_not_run_by_default() throws Exception { - filter.start(); - assertThat(filter.accept(temp.newFile(), mock(FileSystemFilter.Context.class))).isTrue(); - } - - @Test - public void should_throw_if_partial_mode_and_not_in_dryrun() throws Exception { - settings.setProperty(CoreProperties.PARTIAL_ANALYSIS, true); - - thrown.expect(SonarException.class); - thrown.expectMessage("Partial analysis is only supported with dry run mode"); - filter.start(); - } - - @Test - public void should_include_if_no_previous_snapshot() throws Exception { - settings.setProperty(CoreProperties.PARTIAL_ANALYSIS, true); - settings.setProperty(CoreProperties.DRY_RUN, true); - - when(pastSnapshotFinder.findPreviousAnalysis(snapshot)).thenReturn(new PastSnapshot("foo")); - - filter.start(); - assertThat(filter.accept(new File(baseDir, "src/main/java/foo/Bar.java"), mock(FileSystemFilter.Context.class))).isTrue(); - } - - @Test - public void should_include_if_no_previous_snapshot_data() throws Exception { - settings.setProperty(CoreProperties.PARTIAL_ANALYSIS, true); - settings.setProperty(CoreProperties.DRY_RUN, true); - - Snapshot previousSnapshot = mock(Snapshot.class); - PastSnapshot pastSnapshot = new PastSnapshot("foo", new Date(), previousSnapshot); - when(pastSnapshotFinder.findPreviousAnalysis(snapshot)).thenReturn(pastSnapshot); - - filter.start(); - assertThat(filter.accept(new File(baseDir, "src/main/java/foo/Bar.java"), mock(FileSystemFilter.Context.class))).isTrue(); - } - - @Test - public void should_include_if_different_hash() throws Exception { - settings.setProperty(CoreProperties.PARTIAL_ANALYSIS, true); - settings.setProperty(CoreProperties.DRY_RUN, true); - - Snapshot previousSnapshot = mock(Snapshot.class); - when(previousSnapshot.getId()).thenReturn(123); - PastSnapshot pastSnapshot = new PastSnapshot("foo", new Date(), previousSnapshot); - when(pastSnapshotFinder.findPreviousAnalysis(snapshot)).thenReturn(pastSnapshot); - - SnapshotDataDto snapshotDataDto = new SnapshotDataDto(); - snapshotDataDto.setData("src/main/java/foo/Bar.java=abcd1234\n"); - when(snapshotDataDao.selectSnapshotData(123, Arrays.asList(SnapshotDataType.FILE_HASH.getValue()))) - .thenReturn(Arrays.asList(snapshotDataDto)); - - filter.start(); - File file = new File(baseDir, "src/main/java/foo/Bar.java"); - FileUtils.write(file, "foo"); - assertThat(filter.accept(file, mock(FileSystemFilter.Context.class))).isTrue(); - } - - @Test - public void should_exclude_if_same_hash() throws Exception { - settings.setProperty(CoreProperties.PARTIAL_ANALYSIS, true); - settings.setProperty(CoreProperties.DRY_RUN, true); - - Snapshot previousSnapshot = mock(Snapshot.class); - when(previousSnapshot.getId()).thenReturn(123); - PastSnapshot pastSnapshot = new PastSnapshot("foo", new Date(), previousSnapshot); - when(pastSnapshotFinder.findPreviousAnalysis(snapshot)).thenReturn(pastSnapshot); - - SnapshotDataDto snapshotDataDto = new SnapshotDataDto(); - snapshotDataDto.setData("src/main/java/foo/Bar.java=acbd18db4cc2f85cedef654fccc4a4d8\n"); - when(snapshotDataDao.selectSnapshotData(123, Arrays.asList(SnapshotDataType.FILE_HASH.getValue()))) - .thenReturn(Arrays.asList(snapshotDataDto)); - - filter.start(); - File file = new File(baseDir, "src/main/java/foo/Bar.java"); - FileUtils.write(file, "foo"); - assertThat(filter.accept(file, mock(FileSystemFilter.Context.class))).isFalse(); - } -} diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/FileHashSensorTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/FileHashSensorTest.java index 0f3d59db57b..a7bbfa49697 100644 --- a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/FileHashSensorTest.java +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/FileHashSensorTest.java @@ -33,7 +33,7 @@ import org.sonar.api.scan.filesystem.FileQuery; import org.sonar.api.scan.filesystem.ModuleFileSystem; import org.sonar.api.scan.filesystem.PathResolver; import org.sonar.batch.index.ComponentDataCache; -import org.sonar.plugins.core.utils.HashBuilder; +import org.sonar.batch.scan.filesystem.FileHashCache; import java.io.File; import java.util.Arrays; @@ -61,11 +61,14 @@ public class FileHashSensorTest { private Project project; + private FileHashCache fileHashCache; + @Before public void prepare() { fileSystem = mock(ModuleFileSystem.class); componentDataCache = mock(ComponentDataCache.class); - sensor = new FileHashSensor(fileSystem, new PathResolver(), new HashBuilder(), componentDataCache); + fileHashCache = mock(FileHashCache.class); + sensor = new FileHashSensor(fileHashCache, fileSystem, new PathResolver(), componentDataCache); PropertiesConfiguration conf = new PropertiesConfiguration(); conf.setProperty("sonar.language", "java"); project = new Project("java_project").setConfiguration(conf).setLanguage(Java.INSTANCE); @@ -82,15 +85,16 @@ public class FileHashSensorTest { File baseDir = temp.newFolder(); File file1 = new File(baseDir, "src/com/foo/Bar.java"); FileUtils.write(file1, "Bar"); + when(fileHashCache.getCurrentHash(file1)).thenReturn("barhash"); File file2 = new File(baseDir, "src/com/foo/Foo.java"); FileUtils.write(file2, "Foo"); + when(fileHashCache.getCurrentHash(file2)).thenReturn("foohash"); when(fileSystem.baseDir()).thenReturn(baseDir); when(fileSystem.files(any(FileQuery.class))).thenReturn(Arrays.asList(file1, file2)).thenReturn(Collections.<File> emptyList()); sensor.analyse(project, mock(SensorContext.class)); verify(componentDataCache).setStringData("java_project", "hash", - "src/com/foo/Bar.java=ddc35f88fa71b6ef142ae61f35364653\n" - + "src/com/foo/Foo.java=1356c67d7ad1638d816bfb822dd2c25d\n"); + "src/com/foo/Bar.java=barhash\n" + + "src/com/foo/Foo.java=foohash\n"); } - } diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/utils/HashBuilderTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/utils/HashBuilderTest.java deleted file mode 100644 index a0819b57450..00000000000 --- a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/utils/HashBuilderTest.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * 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.plugins.core.utils; - -import org.apache.commons.io.FileUtils; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TemporaryFolder; -import org.sonar.api.utils.SonarException; - -import java.io.File; - -import static org.fest.assertions.Assertions.assertThat; - -public class HashBuilderTest { - - @Rule - public TemporaryFolder temp = new TemporaryFolder(); - - @Test - public void should_compute_hash() throws Exception { - File tempFile = temp.newFile(); - FileUtils.write(tempFile, "foobar"); - assertThat(new HashBuilder().computeHash(tempFile)).isEqualTo("3858f62230ac3c915f300c664312c63f"); - } - - @Test(expected = SonarException.class) - public void should_throw_on_not_existing_file() throws Exception { - File tempFolder = temp.newFolder(); - new HashBuilder().computeHash(new File(tempFolder, "unknowFile.txt")); - } -} |