*/
package org.sonar.plugins.core.sensors;
-import org.sonar.api.batch.*;
+import org.sonar.api.batch.Event;
+import org.sonar.api.batch.Sensor;
+import org.sonar.api.batch.SensorContext;
+import org.sonar.api.batch.TimeMachine;
+import org.sonar.api.batch.TimeMachineQuery;
import org.sonar.api.measures.CoreMetrics;
import org.sonar.api.measures.Measure;
import org.sonar.api.measures.Metric;
}
public boolean shouldExecuteOnProject(Project project) {
- return true;
+ // Views will define a fake profile with a null id
+ return profile.getId() != null;
}
public void analyse(Project project, SensorContext context) {
- if (profile == null) {
- return;
- }
-
Measure pastProfileMeasure = getPreviousMeasure(project, CoreMetrics.PROFILE);
if (pastProfileMeasure == null) {
// first analysis
}
public boolean shouldExecuteOnProject(Project project) {
- return true;
+ // Views will define a fake profile with a null id
+ return profile.getId() != null;
}
public void analyse(Project project, SensorContext context) {
- if (profile != null) {
- Measure measure = new Measure(CoreMetrics.PROFILE, profile.getName());
- Measure measureVersion = new Measure(CoreMetrics.PROFILE_VERSION, Integer.valueOf(profile.getVersion()).doubleValue());
- if (profile.getId() != null) {
- measure.setValue(profile.getId().doubleValue());
-
- profile.setUsed(true);
- session.merge(profile);
- }
- context.saveMeasure(measure);
- context.saveMeasure(measureVersion);
+ Measure measure = new Measure(CoreMetrics.PROFILE, profile.getName());
+ Measure measureVersion = new Measure(CoreMetrics.PROFILE_VERSION, Integer.valueOf(profile.getVersion()).doubleValue());
+ if (profile.getId() != null) {
+ measure.setValue(profile.getId().doubleValue());
+
+ profile.setUsed(true);
+ session.merge(profile);
}
+ context.saveMeasure(measure);
+ context.saveMeasure(measureVersion);
}
@Override
import org.sonar.api.measures.Measure;
import org.sonar.api.profiles.RulesProfile;
import org.sonar.api.resources.Project;
-import org.sonar.api.resources.Resource;
import java.util.Arrays;
import java.util.Collections;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Matchers.same;
import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
}
@Test
- public void shouldExecute() {
- ProfileEventsSensor sensor = new ProfileEventsSensor(null, null);
+ public void shouldExecuteWhenProfileWithId() {
+ RulesProfile profile = mock(RulesProfile.class);
+ when(profile.getId()).thenReturn(123);
+ ProfileEventsSensor sensor = new ProfileEventsSensor(profile, null);
assertThat(sensor.shouldExecuteOnProject(project), is(true));
verifyZeroInteractions(project);
}
@Test
- public void shouldDoNothingIfNoProfile() {
- ProfileEventsSensor sensor = new ProfileEventsSensor(null, null);
-
- sensor.analyse(project, context);
+ public void shouldNotExecuteIfProfileWithoutId() {
+ RulesProfile profile = mock(RulesProfile.class);
+ when(profile.getId()).thenReturn(null);
+ ProfileEventsSensor sensor = new ProfileEventsSensor(profile, null);
- verify(context, never()).createEvent(any(Resource.class), anyString(), anyString(), anyString(), any(Date.class));
+ assertThat(sensor.shouldExecuteOnProject(project), is(false));
+ verifyZeroInteractions(project);
}
@Test
public class DefaultProfileLoader implements ProfileLoader {
private ProfilesDao dao;
- private Settings settings;
- public DefaultProfileLoader(ProfilesDao dao, Settings settings) {
+ public DefaultProfileLoader(ProfilesDao dao) {
this.dao = dao;
- this.settings = settings;
}
- public RulesProfile load(Project project) {
+ public RulesProfile load(Project project, Settings settings) {
String profileName = StringUtils.defaultIfBlank(
- settings.getString("sonar.profile"),
- settings.getString("sonar.profile." + project.getLanguageKey())
- );
+ settings.getString("sonar.profile"),
+ settings.getString("sonar.profile." + project.getLanguageKey())
+ );
if (StringUtils.isBlank(profileName)) {
// This means that the current language is not supported by any installed plugin, otherwise at least a
*/
package org.sonar.batch;
+import org.sonar.api.config.Settings;
import org.sonar.api.profiles.RulesProfile;
import org.sonar.api.resources.Project;
/**
* Loads quality profile for specified project.
*/
- RulesProfile load(Project project);
+ RulesProfile load(Project project, Settings settings);
}
import org.picocontainer.injectors.ProviderAdapter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.sonar.api.config.Settings;
import org.sonar.api.profiles.RulesProfile;
import org.sonar.api.resources.Project;
private RulesProfile profile;
- public RulesProfile provide(Project project, ProfileLoader profileLoader) {
+ public RulesProfile provide(Project project, ProfileLoader profileLoader, Settings settings) {
if (profile == null) {
- profile = profileLoader.load(project);
+ profile = profileLoader.load(project, settings);
LOG.info("Quality profile : {}", profile);
}
return profile;
*/
package org.sonar.batch.bootstrap;
-import org.sonar.core.resource.DefaultResourcePermissions;
-
import org.sonar.api.CoreProperties;
import org.sonar.api.config.Settings;
import org.sonar.api.platform.ComponentContainer;
import org.sonar.batch.scan.ScanTask;
import org.sonar.batch.tasks.ListTask;
import org.sonar.batch.tasks.Tasks;
+import org.sonar.core.resource.DefaultResourcePermissions;
public class TaskContainer extends ComponentContainer {
private void installCoreTasks() {
add(
- ScanTask.DEFINITION, ScanTask.class,
- ListTask.DEFINITION, ListTask.class
- );
+ ScanTask.DEFINITION, ScanTask.class,
+ ListTask.DEFINITION, ListTask.class);
}
private void installTaskExtensions() {
}
public void execute(Project project) {
- initLanguage(project);
+ if (project.getLanguage() == null) {
+ initLanguage(project);
+ }
}
private void initLanguage(Project project) {
import org.sonar.api.resources.Project;
import org.sonar.api.scan.filesystem.FileExclusions;
import org.sonar.api.scan.filesystem.PathResolver;
-import org.sonar.batch.DefaultProfileLoader;
import org.sonar.batch.DefaultProjectClasspath;
import org.sonar.batch.DefaultSensorContext;
import org.sonar.batch.DefaultTimeMachine;
private void addCoreComponents() {
ProjectDefinition moduleDefinition = getComponentByType(ProjectTree.class).getProjectDefinition(module);
add(
- moduleDefinition,
- module.getConfiguration(),
- module,
- ModuleSettings.class);
+ moduleDefinition,
+ module.getConfiguration(),
+ module,
+ ModuleSettings.class);
// hack to initialize commons-configuration before ExtensionProviders
getComponentByType(ModuleSettings.class);
add(
- EventBus.class,
- PhaseExecutor.class,
- PhasesTimeProfiler.class,
- UnsupportedProperties.class,
- PhaseExecutor.getPhaseClasses(),
- moduleDefinition.getContainerExtensions(),
+ EventBus.class,
+ PhaseExecutor.class,
+ PhasesTimeProfiler.class,
+ UnsupportedProperties.class,
+ PhaseExecutor.getPhaseClasses(),
+ moduleDefinition.getContainerExtensions(),
- // TODO move outside project, but not possible yet because of dependency of project settings (cf plsql)
- Languages.class,
+ // TODO move outside project, but not possible yet because of dependency of project settings (cf plsql)
+ Languages.class,
- // file system
- PathResolver.class,
- FileExclusions.class,
- LanguageFilters.class,
- ExclusionFilters.class,
- DefaultProjectClasspath.class,
- new ModuleFileSystemProvider(),
- DeprecatedFileSystemAdapter.class,
- FileSystemLogger.class,
+ // file system
+ PathResolver.class,
+ FileExclusions.class,
+ LanguageFilters.class,
+ ExclusionFilters.class,
+ DefaultProjectClasspath.class,
+ new ModuleFileSystemProvider(),
+ DeprecatedFileSystemAdapter.class,
+ FileSystemLogger.class,
- // the Snapshot component will be removed when asynchronous measures are improved (required for AsynchronousMeasureSensor)
- getComponentByType(ResourcePersister.class).getSnapshot(module),
+ // the Snapshot component will be removed when asynchronous measures are improved (required for AsynchronousMeasureSensor)
+ getComponentByType(ResourcePersister.class).getSnapshot(module),
- TimeMachineConfiguration.class,
- org.sonar.api.database.daos.MeasuresDao.class,
- DefaultSensorContext.class,
- BatchExtensionDictionnary.class,
- DefaultTimeMachine.class,
- ViolationFilters.class,
- ResourceFilters.class,
- DefaultProfileLoader.class,
- DryRunExporter.class,
- new ProfileProvider());
+ TimeMachineConfiguration.class,
+ org.sonar.api.database.daos.MeasuresDao.class,
+ DefaultSensorContext.class,
+ BatchExtensionDictionnary.class,
+ DefaultTimeMachine.class,
+ ViolationFilters.class,
+ ResourceFilters.class,
+ DryRunExporter.class,
+ new ProfileProvider());
}
private void addExtensions() {
protected void doAfterStart() {
DefaultIndex index = getComponentByType(DefaultIndex.class);
index.setCurrentProject(module,
- getComponentByType(ResourceFilters.class),
- getComponentByType(ViolationFilters.class),
- getComponentByType(RulesProfile.class));
+ getComponentByType(ResourceFilters.class),
+ getComponentByType(ViolationFilters.class),
+ getComponentByType(RulesProfile.class));
getComponentByType(PhaseExecutor.class).execute(module);
}
import org.sonar.api.platform.ComponentContainer;
import org.sonar.api.resources.Project;
import org.sonar.batch.DefaultFileLinesContextFactory;
-import org.sonar.batch.DefaultProjectTree;
import org.sonar.batch.DefaultResourceCreationLock;
import org.sonar.batch.ProjectConfigurator;
import org.sonar.batch.ProjectTree;
@Override
protected void doBeforeStart() {
addBatchComponents();
- addProjectComponents();
fixMavenExecutor();
addBatchExtensions();
}
- protected void addProjectComponents() {
- add(DefaultProjectTree.class);
- }
-
private void addBatchComponents() {
add(
- DefaultResourceCreationLock.class,
- DefaultPersistenceManager.class,
- DependencyPersister.class,
- EventPersister.class,
- LinkPersister.class,
- MeasurePersister.class,
- MemoryOptimizer.class,
- DefaultResourcePersister.class,
- SourcePersister.class,
- DefaultNotificationManager.class,
- MetricProvider.class,
- ProjectExclusions.class,
- ProjectReactorReady.class,
- ProjectConfigurator.class,
- DefaultIndex.class,
- DefaultFileLinesContextFactory.class,
- ProjectLock.class,
- LastSnapshots.class,
- ScanGraph.create(),
- TestPlanBuilder.class,
- TestableBuilder.class,
- ScanPerspectives.class,
- ScanGraphStore.class);
+ DefaultResourceCreationLock.class,
+ DefaultPersistenceManager.class,
+ DependencyPersister.class,
+ EventPersister.class,
+ LinkPersister.class,
+ MeasurePersister.class,
+ MemoryOptimizer.class,
+ DefaultResourcePersister.class,
+ SourcePersister.class,
+ DefaultNotificationManager.class,
+ MetricProvider.class,
+ ProjectConfigurator.class,
+ DefaultIndex.class,
+ DefaultFileLinesContextFactory.class,
+ ProjectLock.class,
+ LastSnapshots.class,
+ ScanGraph.create(),
+ TestPlanBuilder.class,
+ TestableBuilder.class,
+ ScanPerspectives.class,
+ ScanGraphStore.class);
}
private void fixMavenExecutor() {
import org.sonar.api.platform.ComponentContainer;
import org.sonar.api.task.Task;
import org.sonar.api.task.TaskDefinition;
+import org.sonar.batch.DefaultProfileLoader;
+import org.sonar.batch.DefaultProjectTree;
import org.sonar.batch.bootstrap.TaskContainer;
import org.sonar.batch.phases.Phases;
public class ScanTask implements Task {
public static final TaskDefinition DEFINITION = TaskDefinition.builder()
- .description("Scan project")
- .key(CoreProperties.SCAN_TASK)
- .taskClass(ScanTask.class)
- .build();
+ .description("Scan project")
+ .key(CoreProperties.SCAN_TASK)
+ .taskClass(ScanTask.class)
+ .build();
private final ComponentContainer taskContainer;
scan(new ProjectScanContainer(taskContainer));
}
+ // Add components specific to project scan (views will use different ones)
void scan(ComponentContainer scanContainer) {
- scanContainer.add(new Phases().enable(Phases.Phase.values()));
+ scanContainer.add(
+ new Phases().enable(Phases.Phase.values()),
+ DefaultProjectTree.class,
+ ProjectExclusions.class,
+ ProjectReactorReady.class,
+ DefaultProfileLoader.class);
scanContainer.execute();
}
}
settings.setProperty("sonar.profile.java", "legacy profile");
when(dao.getProfile(Java.KEY, "legacy profile")).thenReturn(RulesProfile.create("legacy profile", "java"));
- RulesProfile profile = new DefaultProfileLoader(dao, settings).load(javaProject);
+ RulesProfile profile = new DefaultProfileLoader(dao).load(javaProject, settings);
assertThat(profile.getName()).isEqualTo("legacy profile");
}
thrown.expect(SonarException.class);
thrown.expectMessage("Quality profile not found : unknown, language java");
- new DefaultProfileLoader(dao, settings).load(javaProject);
+ new DefaultProfileLoader(dao).load(javaProject, settings);
}
/**
thrown.expect(SonarException.class);
thrown.expectMessage("You must install a plugin that supports the language 'cobol'");
- new DefaultProfileLoader(dao, new Settings()).load(cobolProject);
+ new DefaultProfileLoader(dao).load(cobolProject, new Settings());
}
private Project newProject(String language) {
*/
package org.sonar.batch;
+import org.junit.Test;
+import org.sonar.api.config.Settings;
+import org.sonar.api.profiles.RulesProfile;
+import org.sonar.api.resources.Project;
+
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
-import org.junit.Test;
-import org.sonar.api.profiles.RulesProfile;
-import org.sonar.api.resources.Project;
-
public class ProfileProviderTest {
@Test
public void shouldProvideProfile() {
ProfileLoader loader = mock(ProfileLoader.class);
Project project = new Project("project");
RulesProfile profile = RulesProfile.create();
- when(loader.load(project)).thenReturn(profile);
+ when(loader.load(eq(project), any(Settings.class))).thenReturn(profile);
- assertThat(provider.provide(project, loader), is(profile));
- assertThat(provider.provide(project, loader), is(profile));
- verify(loader).load(project);
+ assertThat(provider.provide(project, loader, new Settings()), is(profile));
+ assertThat(provider.provide(project, loader, new Settings()), is(profile));
+ verify(loader).load(eq(project), any(Settings.class));
verifyNoMoreInteractions(loader);
}
}
import org.junit.Test;
import org.sonar.api.CoreProperties;
+import org.sonar.api.batch.bootstrap.ProjectReactor;
+import org.sonar.api.config.Settings;
import org.sonar.api.platform.ComponentContainer;
+import org.sonar.batch.ProjectConfigurator;
import org.sonar.batch.bootstrap.TaskContainer;
import org.sonar.batch.phases.Phases;
public void should_enable_all_phases() {
ScanTask task = new ScanTask(mock(TaskContainer.class));
ComponentContainer projectScanContainer = new ComponentContainer();
+ projectScanContainer.add(mock(ProjectConfigurator.class), mock(ProjectReactor.class), mock(Settings.class));
task.scan(projectScanContainer);
Phases phases = projectScanContainer.getComponentByType(Phases.class);