]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-3676 Create properties to define project links
authorFabrice Bellingard <fabrice.bellingard@sonarsource.com>
Fri, 5 Oct 2012 07:53:10 +0000 (09:53 +0200)
committerFabrice Bellingard <fabrice.bellingard@sonarsource.com>
Fri, 5 Oct 2012 10:19:36 +0000 (12:19 +0200)
=> even for non-Maven projects. The new properties are:
   - sonar.links.homepage
   - sonar.links.ci
   - sonar.links.issue
   - sonar.links.scm
   - sonar.links.scm_dev

plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/ProjectLinksSensor.java
plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/ProjectLinksSensorTest.java
sonar-batch/src/main/java/org/sonar/batch/MavenProjectConverter.java
sonar-batch/src/test/java/org/sonar/batch/MavenProjectConverterTest.java
sonar-batch/src/test/resources/org/sonar/batch/MavenProjectConverterTest/projectWithLinks/pom.xml [new file with mode: 0644]
sonar-batch/src/test/resources/org/sonar/batch/MavenProjectConverterTest/projectWithLinksAndProperties/pom.xml [new file with mode: 0644]
sonar-plugin-api/src/main/java/org/sonar/api/CoreProperties.java

index c32b14de1c7c24c5a09aa528a5cde8158fab2836..890a0d74e78988c74685544880923ae90b205f24 100644 (file)
@@ -24,6 +24,7 @@ import org.sonar.api.CoreProperties;
 import org.sonar.api.Extension;
 import org.sonar.api.Properties;
 import org.sonar.api.Property;
+import org.sonar.api.PropertyField;
 import org.sonar.api.PropertyType;
 import org.sonar.api.SonarPlugin;
 import org.sonar.api.checks.NoSonarFilter;
@@ -126,6 +127,117 @@ import java.util.List;
     project = false,
     global = true,
     category = CoreProperties.CATEGORY_GENERAL),
+  @Property(
+    key = CoreProperties.LINKS_HOME_PAGE,
+    defaultValue = "",
+    name = "Project Home Page",
+    description = "HTTP URL of the home page of the project.",
+    project = false,
+    global = false,
+    category = CoreProperties.CATEGORY_GENERAL),
+  @Property(
+    key = CoreProperties.LINKS_CI,
+    defaultValue = "",
+    name = "CI server",
+    description = "HTTP URL of the continuous integration server.",
+    project = false,
+    global = false,
+    category = CoreProperties.CATEGORY_GENERAL),
+  @Property(
+    key = CoreProperties.LINKS_ISSUE_TRACKER,
+    defaultValue = "",
+    name = "Issue Tracker",
+    description = "HTTP URL of the issue tracker.",
+    project = false,
+    global = false,
+    category = CoreProperties.CATEGORY_GENERAL),
+  @Property(
+    key = CoreProperties.LINKS_SOURCES,
+    defaultValue = "",
+    name = "SCM server",
+    description = "HTTP URL of the server which hosts the sources of the project.",
+    project = false,
+    global = false,
+    category = CoreProperties.CATEGORY_GENERAL),
+  @Property(
+    key = CoreProperties.LINKS_SOURCES_DEV,
+    defaultValue = "",
+    name = "SCM connection for developers",
+    description = "HTTP URL used by developers to connect to the SCM server for the project.",
+    project = false,
+    global = false,
+    category = CoreProperties.CATEGORY_GENERAL),
+  @Property(
+    key = "sonar.test.jira.servers",
+    name = "Jira Servers",
+    description = "List of jira server definitions",
+    global = true,
+    project = true,
+    category = "DEV",
+    fields = {
+      @PropertyField(
+        key = "key",
+        name = "Key",
+        type = PropertyType.STRING,
+        indicativeSize = 10),
+      @PropertyField(
+        key = "url",
+        name = "Url",
+        description = "l'url du serveur jira",
+        type = PropertyType.STRING,
+        indicativeSize = 20),
+      @PropertyField(
+        key = "port",
+        name = "Port",
+        type = PropertyType.INTEGER,
+        indicativeSize = 5)}),
+  @Property(
+    key = "sonar.demo",
+    name = "Demo",
+    global = true,
+    project = true,
+    category = "DEV",
+    fields = {
+      @PropertyField(
+        key = "text",
+        name = "text",
+        type = PropertyType.TEXT),
+      @PropertyField(
+        key = "boolean",
+        name = "boolean",
+        type = PropertyType.BOOLEAN),
+      @PropertyField(
+        key = "float",
+        name = "float",
+        type = PropertyType.FLOAT),
+      @PropertyField(
+        key = "license",
+        name = "license",
+        type = PropertyType.LICENSE),
+      @PropertyField(
+        key = "metric",
+        name = "metric",
+        type = PropertyType.METRIC),
+      @PropertyField(
+        key = "password",
+        name = "password",
+        type = PropertyType.PASSWORD),
+      @PropertyField(
+        key = "regexp",
+        name = "regexp",
+        type = PropertyType.REGULAR_EXPRESSION),
+      @PropertyField(
+        key = "list",
+        name = "list",
+        type = PropertyType.SINGLE_SELECT_LIST,
+        options = {"AAA", "BBB"})}),
+  @Property(
+    key = "sonar.test.jira",
+    name = "Jira",
+    project = true,
+    category = "DEV",
+    type = PropertyType.PROPERTY_SET,
+    propertySetKey = "sonar.test.jira.servers"),
   @Property(
     key = CoreProperties.PROJECT_LANGUAGE_PROPERTY,
     defaultValue = Java.KEY,
index a5aed4757040f6b04eed2901221624a210264601..406b067ab28e1ae5c4bccc022d5173f77e8a2e15 100644 (file)
 package org.sonar.plugins.core.sensors;
 
 import org.apache.commons.lang.StringUtils;
-import org.apache.maven.model.CiManagement;
-import org.apache.maven.model.IssueManagement;
-import org.apache.maven.model.Scm;
-import org.apache.maven.project.MavenProject;
+import org.sonar.api.CoreProperties;
 import org.sonar.api.batch.Sensor;
 import org.sonar.api.batch.SensorContext;
-import org.sonar.api.batch.SupportedEnvironment;
+import org.sonar.api.config.Settings;
 import org.sonar.api.resources.Project;
 import org.sonar.api.resources.ProjectLink;
+import org.sonar.core.i18n.I18nManager;
 
-@SupportedEnvironment("maven")
-public class ProjectLinksSensor implements Sensor {
+import java.util.Locale;
 
-  public static final String KEY_HOME = "homepage";
-  public static final String KEY_CONTINUOUS_INTEGRATION = "ci";
-  public static final String KEY_ISSUE_TRACKER = "issue";
-  public static final String KEY_SCM = "scm";
-  public static final String KEY_SCM_DEVELOPER_CONNECTION = "scm_dev";
+public class ProjectLinksSensor implements Sensor {
 
-  private MavenProject pom;
+  private Settings settings;
+  private I18nManager i18nManager;
 
-  public ProjectLinksSensor(MavenProject pom) {
-    this.pom = pom;
+  public ProjectLinksSensor(Settings settings, I18nManager i18nManager) {
+    this.settings = settings;
+    this.i18nManager = i18nManager;
   }
 
   public boolean shouldExecuteOnProject(Project project) {
@@ -50,26 +45,18 @@ public class ProjectLinksSensor implements Sensor {
   }
 
   public void analyse(Project project, SensorContext context) {
-    updateLink(context, KEY_HOME, "Home", pom.getUrl());
-
-    Scm scm = pom.getScm();
-    if (scm == null) {
-      scm = new Scm();
-    }
-    updateLink(context, KEY_SCM, "Sources", scm.getUrl());
-    updateLink(context, KEY_SCM_DEVELOPER_CONNECTION, "Developer connection", scm.getDeveloperConnection());
-
-    CiManagement ci = pom.getCiManagement();
-    if (ci == null) {
-      ci = new CiManagement();
-    }
-    updateLink(context, KEY_CONTINUOUS_INTEGRATION, "Continuous integration", ci.getUrl());
+    handleLink(context, CoreProperties.LINKS_HOME_PAGE);
+    handleLink(context, CoreProperties.LINKS_CI);
+    handleLink(context, CoreProperties.LINKS_ISSUE_TRACKER);
+    handleLink(context, CoreProperties.LINKS_SOURCES);
+    handleLink(context, CoreProperties.LINKS_SOURCES_DEV);
+  }
 
-    IssueManagement issues = pom.getIssueManagement();
-    if (issues == null) {
-      issues = new IssueManagement();
-    }
-    updateLink(context, KEY_ISSUE_TRACKER, "Issues", issues.getUrl());
+  private void handleLink(SensorContext context, String linkProperty) {
+    String home = settings.getString(linkProperty);
+    String linkType = StringUtils.substringAfterLast(linkProperty, ".");
+    String name = i18nManager.message(Locale.getDefault(), "project_links." + linkType, linkProperty);
+    updateLink(context, linkType, name, home);
   }
 
   private void updateLink(SensorContext context, String key, String name, String url) {
index 0fd9f9505fb2612d03ce652e4b58e206d9b43c2f..f87147e55e23ff2ce4e88fdc798b4c42b72c776a 100644 (file)
 package org.sonar.plugins.core.sensors;
 
 import org.apache.commons.lang.StringUtils;
-import org.apache.maven.project.MavenProject;
 import org.junit.Test;
 import org.mockito.ArgumentMatcher;
+import org.sonar.api.CoreProperties;
 import org.sonar.api.batch.SensorContext;
+import org.sonar.api.config.Settings;
 import org.sonar.api.resources.Project;
 import org.sonar.api.resources.ProjectLink;
-import org.sonar.api.test.MavenTestUtils;
+import org.sonar.core.i18n.I18nManager;
 
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertThat;
+import java.util.Locale;
+
+import static org.fest.assertions.Assertions.assertThat;
 import static org.mockito.Matchers.argThat;
 import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
 
 public class ProjectLinksSensorTest {
 
+  @Test
+  public void testToString() {
+    assertThat(new ProjectLinksSensor(null, null).toString()).isEqualTo("ProjectLinksSensor");
+  }
+
   @Test
   public void shouldExecuteOnlyForLatestAnalysis() {
-    MavenProject pom = mock(MavenProject.class);
     Project project = mock(Project.class);
     when(project.isLatestAnalysis()).thenReturn(true).thenReturn(false);
-    assertThat(new ProjectLinksSensor(pom).shouldExecuteOnProject(project), is(true));
-    assertThat(new ProjectLinksSensor(pom).shouldExecuteOnProject(project), is(false));
-    verify(project, times(2)).isLatestAnalysis();
-    verifyNoMoreInteractions(project);
+    assertThat(new ProjectLinksSensor(null, null).shouldExecuteOnProject(project)).isTrue();
+    assertThat(new ProjectLinksSensor(null, null).shouldExecuteOnProject(project)).isFalse();
   }
 
   @Test
   public void shouldSaveLinks() {
-    SensorContext context = mock(SensorContext.class);
-    MavenProject pom = MavenTestUtils.loadPom("/org/sonar/plugins/core/sensors/ProjectLinksSensorTest/shouldSaveLinks.xml");
+    Settings settings = new Settings();
+    settings.setProperty(CoreProperties.LINKS_HOME_PAGE, "http://home");
+    I18nManager i18nManager = mock(I18nManager.class);
+    when(i18nManager.message(Locale.getDefault(), "project_links.homepage", CoreProperties.LINKS_HOME_PAGE)).thenReturn("HOME");
     Project project = mock(Project.class);
+    SensorContext context = mock(SensorContext.class);
 
-    new ProjectLinksSensor(pom).analyse(project, context);
+    new ProjectLinksSensor(settings, i18nManager).analyse(project, context);
 
-    verify(context).saveLink(argThat(new MatchLink(ProjectLinksSensor.KEY_HOME, "Home", "http://sonar.codehaus.org")));
-    verify(context).saveLink(argThat(new MatchLink(ProjectLinksSensor.KEY_ISSUE_TRACKER, "Issues", "http://jira.codehaus.org/browse/SONAR")));
-    verify(context).saveLink(argThat(new MatchLink(ProjectLinksSensor.KEY_CONTINUOUS_INTEGRATION, "Continuous integration", "http://bamboo.ci.codehaus.org/browse/SONAR/")));
-    verify(context).saveLink(argThat(new MatchLink(ProjectLinksSensor.KEY_SCM, "Sources", "http://svn.sonar.codehaus.org")));
-    verify(context).saveLink(argThat(new MatchLink(ProjectLinksSensor.KEY_SCM_DEVELOPER_CONNECTION, "Developer connection", "scm:svn:https://svn.codehaus.org/sonar/trunk")));
+    verify(context).saveLink(argThat(new MatchLink("homepage", "HOME", "http://home")));
   }
 
   @Test
-  public void shouldDeleteMissingLinks() {
-    SensorContext context = mock(SensorContext.class);
-    MavenProject pom = MavenTestUtils.loadPom("/org/sonar/plugins/core/sensors/ProjectLinksSensorTest/shouldDeleteMissingLinks.xml");
+  public void shouldDeleteLink() {
+    Settings settings = new Settings();
+    settings.setProperty(CoreProperties.LINKS_HOME_PAGE, "");
+    I18nManager i18nManager = mock(I18nManager.class);
+    when(i18nManager.message(Locale.getDefault(), "project_links.homepage", CoreProperties.LINKS_HOME_PAGE)).thenReturn("HOME");
     Project project = mock(Project.class);
+    SensorContext context = mock(SensorContext.class);
 
-    new ProjectLinksSensor(pom).analyse(project, context);
+    new ProjectLinksSensor(settings, i18nManager).analyse(project, context);
 
-    verify(context).deleteLink(ProjectLinksSensor.KEY_HOME);
-    verify(context).deleteLink(ProjectLinksSensor.KEY_ISSUE_TRACKER);
-    verify(context).deleteLink(ProjectLinksSensor.KEY_CONTINUOUS_INTEGRATION);
-    verify(context).deleteLink(ProjectLinksSensor.KEY_SCM);
-    verify(context).deleteLink(ProjectLinksSensor.KEY_SCM_DEVELOPER_CONNECTION);
+    verify(context).deleteLink("homepage");
   }
 
   private class MatchLink extends ArgumentMatcher<ProjectLink> {
index a05c3c5dc110867f412a3abbd63e2845ff81f454..1c25beabf6aa5303a22dd051c405c761265fa354 100644 (file)
  */
 package org.sonar.batch;
 
-import java.io.File;
-import java.io.IOException;
-import java.util.List;
-import java.util.Map;
-
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.Maps;
+import org.apache.commons.lang.StringUtils;
+import org.apache.maven.model.CiManagement;
+import org.apache.maven.model.IssueManagement;
+import org.apache.maven.model.Scm;
 import org.apache.maven.project.MavenProject;
+import org.sonar.api.CoreProperties;
 import org.sonar.api.batch.bootstrap.ProjectDefinition;
 import org.sonar.api.utils.SonarException;
 
-import com.google.common.collect.Maps;
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
 
 public final class MavenProjectConverter {
 
   private static final String UNABLE_TO_DETERMINE_PROJECT_STRUCTURE_EXCEPTION_MESSAGE = "Unable to determine structure of project." +
-      " Probably you use Maven Advanced Reactor Options, which is not supported by Sonar and should not be used.";
+    " Probably you use Maven Advanced Reactor Options, which is not supported by Sonar and should not be used.";
 
   public static ProjectDefinition convert(List<MavenProject> poms, MavenProject root) {
     Map<String, MavenProject> paths = Maps.newHashMap(); // projects by canonical path to pom.xml
@@ -78,24 +84,57 @@ public final class MavenProjectConverter {
     return rootProject;
   }
 
-  /**
-   * Visibility has been relaxed for tests.
-   */
+  @VisibleForTesting
   static ProjectDefinition convert(MavenProject pom) {
     String key = new StringBuilder().append(pom.getGroupId()).append(":").append(pom.getArtifactId()).toString();
     ProjectDefinition definition = ProjectDefinition.create();
     // IMPORTANT NOTE : reference on properties from POM model must not be saved, instead they should be copied explicitly - see SONAR-2896
+    Properties properties = pom.getModel().getProperties();
+    convertMavenLinksToProperties(pom, properties);
     definition
-        .setProperties(pom.getModel().getProperties())
+        .setProperties(properties)
         .setKey(key)
         .setVersion(pom.getVersion())
         .setName(pom.getName())
         .setDescription(pom.getDescription())
         .addContainerExtension(pom);
     synchronizeFileSystem(pom, definition);
+
     return definition;
   }
 
+  /**
+   * For SONAR-3676
+   */
+  private static void convertMavenLinksToProperties(MavenProject pom, Properties properties) {
+    setPropertyIfNotAlreadyExists(properties, CoreProperties.LINKS_HOME_PAGE, pom.getUrl());
+
+    Scm scm = pom.getScm();
+    if (scm == null) {
+      scm = new Scm();
+    }
+    setPropertyIfNotAlreadyExists(properties, CoreProperties.LINKS_SOURCES, scm.getUrl());
+    setPropertyIfNotAlreadyExists(properties, CoreProperties.LINKS_SOURCES_DEV, scm.getDeveloperConnection());
+
+    CiManagement ci = pom.getCiManagement();
+    if (ci == null) {
+      ci = new CiManagement();
+    }
+    setPropertyIfNotAlreadyExists(properties, CoreProperties.LINKS_CI, ci.getUrl());
+
+    IssueManagement issues = pom.getIssueManagement();
+    if (issues == null) {
+      issues = new IssueManagement();
+    }
+    setPropertyIfNotAlreadyExists(properties, CoreProperties.LINKS_ISSUE_TRACKER, issues.getUrl());
+  }
+
+  private static void setPropertyIfNotAlreadyExists(Properties properties, String propertyKey, String propertyValue) {
+    if (StringUtils.isBlank(properties.getProperty(propertyKey))) {
+      properties.setProperty(propertyKey, StringUtils.defaultString(propertyValue));
+    }
+  }
+
   public static void synchronizeFileSystem(MavenProject pom, ProjectDefinition into) {
     into.setBaseDir(pom.getBasedir());
     into.setWorkDir(new File(resolvePath(pom.getBuild().getDirectory(), pom.getBasedir()), "sonar"));
index 38abbf99fd012acc334a245606f6523083191036..91c77da73fa3e86a12ad134e286b3e5b6604c49a 100644 (file)
@@ -37,6 +37,7 @@ import java.net.URISyntaxException;
 import java.util.Arrays;
 import java.util.Properties;
 
+import static org.fest.assertions.Assertions.assertThat;
 import static org.hamcrest.Matchers.containsString;
 import static org.hamcrest.Matchers.is;
 import static org.junit.Assert.assertNull;
@@ -150,6 +151,38 @@ public class MavenProjectConverterTest {
     assertThat(rootDef.getBaseDir(), is(rootDir));
   }
 
+  @Test
+  public void shouldConvertLinksToProperties() throws Exception {
+    MavenProject pom = loadPom("/org/sonar/batch/MavenProjectConverterTest/projectWithLinks/pom.xml", true);
+
+    ProjectDefinition rootDef = MavenProjectConverter.convert(Arrays.asList(pom), pom);
+
+    Properties props = rootDef.getProperties();
+    assertThat(props.getProperty(CoreProperties.LINKS_HOME_PAGE)).isEqualTo("http://home.com");
+    assertThat(props.getProperty(CoreProperties.LINKS_CI)).isEqualTo("http://ci.com");
+    assertThat(props.getProperty(CoreProperties.LINKS_ISSUE_TRACKER)).isEqualTo("http://issues.com");
+    assertThat(props.getProperty(CoreProperties.LINKS_SOURCES)).isEqualTo("http://sources.com");
+    assertThat(props.getProperty(CoreProperties.LINKS_SOURCES_DEV)).isEqualTo("http://sources-dev.com");
+  }
+
+  @Test
+  public void shouldNotConvertLinksToPropertiesIfPropertyAlreadyDefined() throws Exception {
+    MavenProject pom = loadPom("/org/sonar/batch/MavenProjectConverterTest/projectWithLinksAndProperties/pom.xml", true);
+
+    ProjectDefinition rootDef = MavenProjectConverter.convert(Arrays.asList(pom), pom);
+
+    Properties props = rootDef.getProperties();
+
+    // Those properties have been fed by the POM elements <ciManagement>, <issueManagement>, ...
+    assertThat(props.getProperty(CoreProperties.LINKS_CI)).isEqualTo("http://ci.com");
+    assertThat(props.getProperty(CoreProperties.LINKS_ISSUE_TRACKER)).isEqualTo("http://issues.com");
+    assertThat(props.getProperty(CoreProperties.LINKS_SOURCES_DEV)).isEqualTo("http://sources-dev.com");
+
+    // ... but those ones have been overridden by <properties> in the POM
+    assertThat(props.getProperty(CoreProperties.LINKS_SOURCES)).isEqualTo("http://sources.com-OVERRIDEN-BY-PROPS");
+    assertThat(props.getProperty(CoreProperties.LINKS_HOME_PAGE)).isEqualTo("http://home.com-OVERRIDEN-BY-PROPS");
+  }
+
   private MavenProject loadPom(String pomPath, boolean isRoot) throws URISyntaxException, IOException, XmlPullParserException {
     File pomFile = new File(getClass().getResource(pomPath).toURI());
     Model model = new MavenXpp3Reader().read(new StringReader(FileUtils.readFileToString(pomFile)));
diff --git a/sonar-batch/src/test/resources/org/sonar/batch/MavenProjectConverterTest/projectWithLinks/pom.xml b/sonar-batch/src/test/resources/org/sonar/batch/MavenProjectConverterTest/projectWithLinks/pom.xml
new file mode 100644 (file)
index 0000000..460e896
--- /dev/null
@@ -0,0 +1,18 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>org.test</groupId>
+  <artifactId>parent</artifactId>
+  <version>0.1-SNAPSHOT</version>
+  <packaging>pom</packaging>
+  <url>http://home.com</url>
+  <ciManagement>
+    <url>http://ci.com</url>
+  </ciManagement>
+  <issueManagement>
+    <url>http://issues.com</url>
+  </issueManagement>
+  <scm>
+    <url>http://sources.com</url>
+    <developerConnection>http://sources-dev.com</developerConnection>
+  </scm>
+</project>
\ No newline at end of file
diff --git a/sonar-batch/src/test/resources/org/sonar/batch/MavenProjectConverterTest/projectWithLinksAndProperties/pom.xml b/sonar-batch/src/test/resources/org/sonar/batch/MavenProjectConverterTest/projectWithLinksAndProperties/pom.xml
new file mode 100644 (file)
index 0000000..5b024e5
--- /dev/null
@@ -0,0 +1,27 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>org.test</groupId>
+  <artifactId>parent</artifactId>
+  <version>0.1-SNAPSHOT</version>
+  <packaging>pom</packaging>
+  <url>http://home.com</url>
+  <ciManagement>
+    <url>http://ci.com</url>
+  </ciManagement>
+  <issueManagement>
+    <url>http://issues.com</url>
+  </issueManagement>
+  <scm>
+    <url>http://sources.com</url>
+    <developerConnection>http://sources-dev.com</developerConnection>
+  </scm>
+
+
+
+  <properties>
+    <sonar.links.homepage>http://home.com-OVERRIDEN-BY-PROPS</sonar.links.homepage>
+    <sonar.links.scm>http://sources.com-OVERRIDEN-BY-PROPS</sonar.links.scm>
+  </properties>
+
+
+</project>
\ No newline at end of file
index c6e91e815fc9ba9170fb8910ab645ab741467800..c72cd3781ab3eff010bcf907f6dfaa7a6de4042f 100644 (file)
@@ -301,4 +301,29 @@ public interface CoreProperties {
    * @since 2.11
    */
   String SERVER_ID_IP_ADDRESS = "sonar.server_id.ip_address";
+
+  /**
+   * @since 3.3
+   */
+  String LINKS_HOME_PAGE = "sonar.links.homepage";
+
+  /**
+   * @since 3.3
+   */
+  String LINKS_CI = "sonar.links.ci";
+
+  /**
+   * @since 3.3
+   */
+  String LINKS_ISSUE_TRACKER = "sonar.links.issue";
+
+  /**
+   * @since 3.3
+   */
+  String LINKS_SOURCES = "sonar.links.scm";
+
+  /**
+   * @since 3.3
+   */
+  String LINKS_SOURCES_DEV = "sonar.links.scm_dev";
 }