package org.sonar.xoo;
import org.sonar.api.SonarPlugin;
-import org.sonar.xoo.lang.DependencySensor;
-import org.sonar.xoo.lang.MeasureSensor;
-import org.sonar.xoo.lang.SymbolReferencesSensor;
-import org.sonar.xoo.lang.SyntaxHighlightingSensor;
-import org.sonar.xoo.lang.XooCpdMapping;
-import org.sonar.xoo.lang.XooTokenizer;
-import org.sonar.xoo.rule.ChecksSensor;
-import org.sonar.xoo.rule.CreateIssueByInternalKeySensor;
-import org.sonar.xoo.rule.DeprecatedResourceApiSensor;
-import org.sonar.xoo.rule.OneIssueOnDirPerFileSensor;
-import org.sonar.xoo.rule.OneIssuePerLineSensor;
-import org.sonar.xoo.rule.RandomAccessSensor;
-import org.sonar.xoo.rule.XooFakeExporter;
-import org.sonar.xoo.rule.XooFakeImporter;
-import org.sonar.xoo.rule.XooFakeImporterWithMessages;
-import org.sonar.xoo.rule.XooQualityProfile;
-import org.sonar.xoo.rule.XooRulesDefinition;
+import org.sonar.xoo.extensions.XooProjectBuilder;
+import org.sonar.xoo.lang.*;
+import org.sonar.xoo.rule.*;
import org.sonar.xoo.scm.XooBlameCommand;
import org.sonar.xoo.scm.XooScmProvider;
OneIssuePerLineSensor.class,
OneIssueOnDirPerFileSensor.class,
- CreateIssueByInternalKeySensor.class
- );
+ CreateIssueByInternalKeySensor.class,
+
+ // Other
+ XooProjectBuilder.class);
}
}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 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.xoo.extensions;
+
+import org.sonar.api.batch.bootstrap.ProjectBuilder;
+import org.sonar.api.batch.bootstrap.ProjectDefinition;
+import org.sonar.api.config.Settings;
+
+import java.io.File;
+
+public class XooProjectBuilder extends ProjectBuilder {
+
+ private Settings settings;
+
+ public XooProjectBuilder(Settings settings) {
+ this.settings = settings;
+ }
+
+ @Override
+ public void build(Context context) {
+ if (!settings.getBoolean("sonar.xoo.enableProjectBuilder")) {
+ return;
+ }
+ ProjectDefinition root = context.projectReactor().getRoot();
+
+ ProjectDefinition module = ProjectDefinition.create()
+ .setKey(root.getKey() + ":module1")
+ .setName("Module 1");
+
+ module.setBaseDir(new File(root.getBaseDir(), "module1"));
+ module.setWorkDir(new File(root.getWorkDir(), "module1"));
+
+ module.setSources("src");
+
+ root.addSubProject(module);
+ }
+
+}
private final ProjectRepositories projectReferentials;
private DefaultAnalysisMode analysisMode;
- public ModuleSettings(GlobalSettings batchSettings, ProjectDefinition project, ProjectRepositories projectReferentials,
+ public ModuleSettings(GlobalSettings batchSettings, ProjectDefinition moduleDefinition, ProjectRepositories projectReferentials,
DefaultAnalysisMode analysisMode) {
super(batchSettings.getDefinitions());
this.projectReferentials = projectReferentials;
getEncryption().setPathToSecretKey(batchSettings.getString(CoreProperties.ENCRYPTION_SECRET_KEY_PATH));
LoggerFactory.getLogger(ModuleSettings.class).info("Load module settings");
- init(project, batchSettings);
+ init(moduleDefinition, batchSettings);
}
- private ModuleSettings init(ProjectDefinition project, GlobalSettings batchSettings) {
- addProjectProperties(project, batchSettings);
- addBuildProperties(project);
+ private ModuleSettings init(ProjectDefinition moduleDefinition, GlobalSettings batchSettings) {
+ addProjectProperties(moduleDefinition, batchSettings);
+ addBuildProperties(moduleDefinition);
return this;
}
- private void addProjectProperties(ProjectDefinition project, GlobalSettings batchSettings) {
+ private void addProjectProperties(ProjectDefinition moduleDefinition, GlobalSettings batchSettings) {
addProperties(batchSettings.getProperties());
- addProperties(projectReferentials.settings(project.getKeyWithBranch()));
+ addProperties(projectReferentials.settings(moduleDefinition.getKeyWithBranch()));
}
private void addBuildProperties(ProjectDefinition project) {
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 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.mediumtest.fs;
+
+import com.google.common.collect.ImmutableMap;
+import org.apache.commons.io.FileUtils;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.sonar.api.CoreProperties;
+import org.sonar.batch.mediumtest.BatchMediumTester;
+import org.sonar.batch.mediumtest.TaskResult;
+import org.sonar.batch.protocol.input.ActiveRule;
+import org.sonar.xoo.XooPlugin;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Date;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class ProjectBuilderMediumTest {
+
+ @org.junit.Rule
+ public TemporaryFolder temp = new TemporaryFolder();
+
+ public BatchMediumTester tester = BatchMediumTester.builder()
+ .registerPlugin("xoo", new XooPlugin())
+ .addDefaultQProfile("xoo", "Sonar Way")
+ .bootstrapProperties(ImmutableMap.of(CoreProperties.ANALYSIS_MODE, CoreProperties.ANALYSIS_MODE_PREVIEW))
+ .setPreviousAnalysisDate(new Date())
+ .activateRule(new ActiveRule("xoo", "OneIssuePerLine", null, "One issue per line", "MAJOR", "OneIssuePerLine.internal", "xoo"))
+ .build();
+
+ @Before
+ public void prepare() {
+ tester.start();
+ }
+
+ @After
+ public void stop() {
+ tester.stop();
+ }
+
+ @Test
+ public void testProjectBuilder() throws IOException {
+
+ File baseDir = temp.newFolder();
+ File module1Dir = new File(baseDir, "module1");
+ module1Dir.mkdir();
+
+ File srcDir = new File(module1Dir, "src");
+ srcDir.mkdir();
+
+ File xooFile = new File(srcDir, "sample.xoo");
+ FileUtils.write(xooFile, "1\n2\n3\n4\n5\n6\n7\n8\n9\n10");
+
+ TaskResult result = tester.newTask()
+ .properties(ImmutableMap.<String, String>builder()
+ .put("sonar.task", "scan")
+ .put("sonar.projectBaseDir", baseDir.getAbsolutePath())
+ .put("sonar.projectKey", "com.foo.project")
+ .put("sonar.projectName", "Foo Project")
+ .put("sonar.projectVersion", "1.0-SNAPSHOT")
+ .put("sonar.projectDescription", "Description of Foo Project")
+ .put("sonar.sources", ".")
+ .put("sonar.xoo.enableProjectBuilder", "true")
+ .build())
+ .start();
+
+ assertThat(result.issues()).hasSize(10);
+
+ boolean foundIssueAtLine1 = false;
+ for (org.sonar.api.issue.Issue issue : result.issues()) {
+ if (issue.line() == 1) {
+ foundIssueAtLine1 = true;
+ assertThat(issue.componentKey()).isEqualTo("com.foo.project:module1:src/sample.xoo");
+ assertThat(issue.message()).isEqualTo("This issue is generated on each line");
+ assertThat(issue.effortToFix()).isNull();
+ }
+ }
+ assertThat(foundIssueAtLine1).isTrue();
+ }
+
+ @Test
+ public void testProjectBuilderWithBranch() throws IOException {
+
+ File baseDir = temp.newFolder();
+ File module1Dir = new File(baseDir, "module1");
+ module1Dir.mkdir();
+
+ File srcDir = new File(module1Dir, "src");
+ srcDir.mkdir();
+
+ File xooFile = new File(srcDir, "sample.xoo");
+ FileUtils.write(xooFile, "1\n2\n3\n4\n5\n6\n7\n8\n9\n10");
+
+ TaskResult result = tester.newTask()
+ .properties(ImmutableMap.<String, String>builder()
+ .put("sonar.task", "scan")
+ .put("sonar.projectBaseDir", baseDir.getAbsolutePath())
+ .put("sonar.projectKey", "com.foo.project")
+ .put("sonar.projectName", "Foo Project")
+ .put("sonar.projectVersion", "1.0-SNAPSHOT")
+ .put("sonar.projectDescription", "Description of Foo Project")
+ .put("sonar.branch", "my-branch")
+ .put("sonar.sources", ".")
+ .put("sonar.xoo.enableProjectBuilder", "true")
+ .build())
+ .start();
+
+ assertThat(result.issues()).hasSize(10);
+
+ boolean foundIssueAtLine1 = false;
+ for (org.sonar.api.issue.Issue issue : result.issues()) {
+ if (issue.line() == 1) {
+ foundIssueAtLine1 = true;
+ assertThat(issue.componentKey()).isEqualTo("com.foo.project:module1:my-branch:src/sample.xoo");
+ assertThat(issue.message()).isEqualTo("This issue is generated on each line");
+ assertThat(issue.effortToFix()).isNull();
+ }
+ }
+ assertThat(foundIssueAtLine1).isTrue();
+ }
+
+}
import javax.annotation.Nullable;
import java.io.File;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
import java.util.Map.Entry;
-import java.util.Properties;
/**
* Defines project metadata (key, name, source directories, ...). It's generally used by the
* @since 4.5
*/
public String getKeyWithBranch() {
- String branch = properties.get(CoreProperties.PROJECT_BRANCH_PROPERTY);
+ String branch = getBranch();
String projectKey = getKey();
if (StringUtils.isNotBlank(branch)) {
projectKey = String.format("%s:%s", projectKey, branch);
return projectKey;
}
+ @CheckForNull
+ private String getBranch() {
+ String branch = properties.get(CoreProperties.PROJECT_BRANCH_PROPERTY);
+ if (StringUtils.isNotBlank(branch)) {
+ return branch;
+ } else if (getParent() != null) {
+ return getParent().getBranch();
+ }
+ return null;
+ }
+
public String getVersion() {
return properties.get(CoreProperties.PROJECT_VERSION_PROPERTY);
}