diff --git a/pom.xml b/pom.xml
index 78ccec51..4e11119b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -22,6 +22,7 @@
echo
sonar-orchestrator
+ sonar-orchestrator-config
sonar-orchestrator-junit4
sonar-orchestrator-junit5
@@ -41,8 +42,6 @@
GNU LGPL v3
3.5.2
- 2.7
- 2.6
1.3
18.0
4.13.2
@@ -54,9 +53,7 @@
orchestrator
- 11
- 8
- 8
+ 11
@@ -66,16 +63,43 @@
jsr305
3.0.1
+
+ commons-io
+ commons-io
+ 2.19.0
+
+
+ org.apache.commons
+ commons-lang3
+ 3.18.0
+
+
+ org.apache.commons
+ commons-text
+ 1.14.0
+
+
+ org.junit
+ junit-bom
+ 5.13.4
+ pom
+ import
+
org.assertj
assertj-core
- 3.9.1
+ 3.27.3
org.mockito
mockito-core
5.16.0
+
+ org.wiremock
+ wiremock-standalone
+ 3.13.1
+
diff --git a/sonar-orchestrator-config/pom.xml b/sonar-orchestrator-config/pom.xml
new file mode 100644
index 00000000..6e569120
--- /dev/null
+++ b/sonar-orchestrator-config/pom.xml
@@ -0,0 +1,47 @@
+
+
+ 4.0.0
+
+ org.sonarsource.orchestrator
+ orchestrator-parent
+ 5.6.2-SNAPSHOT
+
+ sonar-orchestrator-config
+ Orchestrator Configuration
+
+
+
+ com.google.code.findbugs
+ jsr305
+ provided
+
+
+ commons-io
+ commons-io
+
+
+ org.apache.commons
+ commons-lang3
+
+
+ org.apache.commons
+ commons-text
+
+
+ org.junit.jupiter
+ junit-jupiter
+ test
+
+
+ org.assertj
+ assertj-core
+ test
+
+
+ org.wiremock
+ wiremock-standalone
+ test
+
+
+
+
diff --git a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/config/Configuration.java b/sonar-orchestrator-config/src/main/java/com/sonar/orchestrator/config/Configuration.java
similarity index 68%
rename from sonar-orchestrator/src/main/java/com/sonar/orchestrator/config/Configuration.java
rename to sonar-orchestrator-config/src/main/java/com/sonar/orchestrator/config/Configuration.java
index 8ebb6ea8..4ba3cce9 100644
--- a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/config/Configuration.java
+++ b/sonar-orchestrator-config/src/main/java/com/sonar/orchestrator/config/Configuration.java
@@ -1,5 +1,5 @@
/*
- * Orchestrator
+ * Orchestrator Configuration
* Copyright (C) 2011-2025 SonarSource SA
* mailto:info AT sonarsource DOT com
*
@@ -19,12 +19,11 @@
*/
package com.sonar.orchestrator.config;
-import com.sonar.orchestrator.locator.ArtifactoryFactory;
-import com.sonar.orchestrator.locator.FileLocation;
-import com.sonar.orchestrator.locator.Locators;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URI;
+import java.nio.file.Files;
+import java.nio.file.Path;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
@@ -35,62 +34,45 @@
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang.text.StrSubstitutor;
+import org.apache.commons.text.StringSubstitutor;
-import static com.sonar.orchestrator.util.OrchestratorUtils.checkState;
-import static com.sonar.orchestrator.util.OrchestratorUtils.defaultIfNull;
-import static com.sonar.orchestrator.util.OrchestratorUtils.isEmpty;
-import static java.lang.String.format;
import static java.nio.charset.StandardCharsets.UTF_8;
-import static java.util.Objects.requireNonNull;
import static org.apache.commons.io.FileUtils.getUserDirectory;
+import static org.apache.commons.lang3.ObjectUtils.getIfNull;
+import static org.apache.commons.lang3.StringUtils.isEmpty;
public class Configuration {
- private static final String ENV_SHARED_DIR = "SONAR_IT_SOURCES";
- private static final String PROP_SHARED_DIR = "orchestrator.it_sources";
private final Map props;
private final FileSystem fileSystem;
- private final Locators locators;
- private Configuration(File homeDir, Map props) {
+ private Configuration(Path homeDir, Map props) {
this.props = Collections.unmodifiableMap(new HashMap<>(props));
this.fileSystem = new FileSystem(homeDir, this);
- this.locators = new Locators(this.fileSystem, ArtifactoryFactory.createArtifactory(this));
}
- public FileSystem fileSystem() {
- return fileSystem;
+ public static Configuration createEnv() {
+ return builder().addEnvVariables().addSystemProperties().build();
}
- public Locators locators() {
- return locators;
+ public static Configuration create(Properties properties) {
+ return builder().addProperties(properties).build();
}
- /**
- * File located in the shared directory defined by the system property orchestrator.it_sources or environment variable SONAR_IT_SOURCES.
- * Example : getFileLocationOfShared("javascript/performancing/pom.xml")
- */
- public FileLocation getFileLocationOfShared(String relativePath) {
- // try to read it_sources
- // in the System.getProperties
- // in the prop file (from orchestrator.properties file)
- // in the environment variable
- String rootPath;
- rootPath = System.getProperty(PROP_SHARED_DIR);
- if (rootPath == null) {
- rootPath = props.get(PROP_SHARED_DIR);
- }
- if (rootPath == null) {
- rootPath = System.getenv(ENV_SHARED_DIR);
- }
- requireNonNull(rootPath, format("Property '%s' or environment variable '%s' is missing", PROP_SHARED_DIR, ENV_SHARED_DIR));
+ public static Configuration create(Map properties) {
+ return builder().addProperties(properties).build();
+ }
+
+ public static Configuration create() {
+ return builder().build();
+ }
- File rootDir = new File(rootPath);
- checkState(rootDir.isDirectory() && rootDir.exists(),
- "Please check the definition of it_sources (%s or %s) because the directory does not exist: %s", PROP_SHARED_DIR, ENV_SHARED_DIR, rootDir);
+ public static Builder builder() {
+ return new Builder();
+ }
- return FileLocation.of(new File(rootDir, relativePath));
+ public FileSystem fileSystem() {
+ return fileSystem;
}
public String getString(String key) {
@@ -102,7 +84,7 @@ public String getString(String key) {
}
public String getString(String key, @Nullable String defaultValue) {
- return defaultIfNull(props.get(key), defaultValue);
+ return getIfNull(props.get(key), defaultValue);
}
@CheckForNull
@@ -133,32 +115,24 @@ public Map asMap() {
return props;
}
- public static Configuration createEnv() {
- return builder().addEnvVariables().addSystemProperties().build();
- }
-
- public static Configuration create(Properties properties) {
- return builder().addProperties(properties).build();
- }
-
- public static Configuration create(Map properties) {
- return builder().addProperties(properties).build();
- }
-
- public static Configuration create() {
- return builder().build();
- }
-
- public static Builder builder() {
- return new Builder();
- }
-
public static final class Builder {
- private Map props = new HashMap<>();
+ private final Map props = new HashMap<>();
private Builder() {
}
+ private static Map interpolateProperties(Map map) {
+ Map copy = new HashMap<>();
+ for (Map.Entry entry : map.entrySet()) {
+ copy.put(entry.getKey(), interpolate(entry.getValue(), map));
+ }
+ return copy;
+ }
+
+ private static String interpolate(String prop, Map with) {
+ return StringSubstitutor.replace(prop, with, "${", "}");
+ }
+
public Builder addConfiguration(Configuration c) {
return addMap(c.asMap());
}
@@ -180,9 +154,7 @@ public Builder addProperties(Properties p) {
}
public Builder addProperties(Map p) {
- for (Map.Entry entry : p.entrySet()) {
- props.put(entry.getKey(), entry.getValue());
- }
+ props.putAll(p);
return this;
}
@@ -198,20 +170,20 @@ public Builder setProperty(String key, @Nullable String value) {
return this;
}
- public Builder setProperty(String key, File file) {
- props.put(key, file.getAbsolutePath());
+ public Builder setProperty(String key, Path file) {
+ props.put(key, file.toAbsolutePath().toString());
return this;
}
- private File loadProperties() {
- File homeDir = Stream.of(
+ private Path loadProperties() {
+ Path homeDir = Stream.of(
props.get("orchestrator.home"),
props.get("ORCHESTRATOR_HOME"),
props.get("SONAR_USER_HOME"))
.filter(s -> !isEmpty(s))
.findFirst()
- .map(File::new)
- .orElse(new File(getUserDirectory(), ".sonar/orchestrator"));
+ .map(Path::of)
+ .orElse(getUserDirectory().toPath().resolve(".sonar/orchestrator"));
String configUrl = Stream.of(
props.get("orchestrator.configUrl"),
@@ -219,9 +191,9 @@ private File loadProperties() {
.filter(s -> !isEmpty(s))
.findFirst()
.orElseGet(() -> {
- File file = new File(homeDir, "orchestrator.properties");
+ Path file = homeDir.resolve("orchestrator.properties");
try {
- return file.exists() ? file.getAbsoluteFile().toURI().toURL().toString() : null;
+ return Files.exists(file) ? file.toAbsolutePath().toUri().toURL().toString() : null;
} catch (MalformedURLException e) {
throw new IllegalStateException("Unable to read configuration file", e);
}
@@ -245,20 +217,8 @@ private File loadProperties() {
return homeDir;
}
- private static Map interpolateProperties(Map map) {
- Map copy = new HashMap<>();
- for (Map.Entry entry : map.entrySet()) {
- copy.put(entry.getKey(), interpolate(entry.getValue(), map));
- }
- return copy;
- }
-
- private static String interpolate(String prop, Map with) {
- return StrSubstitutor.replace(prop, with, "${", "}");
- }
-
public Configuration build() {
- File homeDir = loadProperties();
+ Path homeDir = loadProperties();
Map interpolatedProperties = interpolateProperties(props);
return new Configuration(homeDir, interpolatedProperties);
}
diff --git a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/config/FileSystem.java b/sonar-orchestrator-config/src/main/java/com/sonar/orchestrator/config/FileSystem.java
similarity index 67%
rename from sonar-orchestrator/src/main/java/com/sonar/orchestrator/config/FileSystem.java
rename to sonar-orchestrator-config/src/main/java/com/sonar/orchestrator/config/FileSystem.java
index 668f2baa..26d3be76 100644
--- a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/config/FileSystem.java
+++ b/sonar-orchestrator-config/src/main/java/com/sonar/orchestrator/config/FileSystem.java
@@ -1,5 +1,5 @@
/*
- * Orchestrator
+ * Orchestrator Configuration
* Copyright (C) 2011-2025 SonarSource SA
* mailto:info AT sonarsource DOT com
*
@@ -19,7 +19,7 @@
*/
package com.sonar.orchestrator.config;
-import java.io.File;
+import java.nio.file.Path;
import java.util.List;
import java.util.Objects;
import javax.annotation.CheckForNull;
@@ -30,69 +30,69 @@
import static org.apache.commons.io.FileUtils.getUserDirectory;
public class FileSystem {
- private File orchestratorHome;
+ private final Path orchestratorHome;
@Nullable
- private File mavenHome;
- private File mavenLocalRepository;
- private File sonarQubeZipsDir;
- private File workspace;
+ private final Path mavenHome;
+ private final Path mavenLocalRepository;
+ private final Path sonarQubeZipsDir;
+ private final Path workspace;
@Nullable
- private File javaHome;
+ private final Path javaHome;
@Nullable
- private File antHome;
+ private final Path antHome;
- public FileSystem(File homeDir, Configuration config) {
+ public FileSystem(Path homeDir, Configuration config) {
this.orchestratorHome = homeDir;
this.mavenHome = initDir(config, asList("maven.home", "MAVEN_HOME"), null);
- this.mavenLocalRepository = initDir(config, asList("maven.localRepository", "MAVEN_LOCAL_REPOSITORY"), new File(getUserDirectory(), ".m2/repository"));
- this.sonarQubeZipsDir = initDir(config, singletonList("orchestrator.sonarInstallsDir"), new File(orchestratorHome, "zips"));
- this.workspace = initDir(config, singletonList("orchestrator.workspaceDir"), new File("target"));
+ this.mavenLocalRepository = initDir(config, asList("maven.localRepository", "MAVEN_LOCAL_REPOSITORY"), getUserDirectory().toPath().resolve(".m2/repository"));
+ this.sonarQubeZipsDir = initDir(config, singletonList("orchestrator.sonarInstallsDir"), orchestratorHome.resolve("zips"));
+ this.workspace = initDir(config, singletonList("orchestrator.workspaceDir"), Path.of("target"));
this.javaHome = initDir(config, asList("java.home", "JAVA_HOME"), null);
this.antHome = initDir(config, asList("ant.home", "ANT_HOME"), null);
}
- public File mavenLocalRepository() {
+ @CheckForNull
+ private static Path initDir(Configuration config, List propertyKeys, @Nullable Path defaultPath) {
+ return propertyKeys.stream()
+ .map(config::getString)
+ .filter(Objects::nonNull)
+ .findFirst()
+ .map(Path::of)
+ .orElse(defaultPath);
+ }
+
+ public Path mavenLocalRepository() {
return mavenLocalRepository;
}
@CheckForNull
- public File mavenHome() {
+ public Path mavenHome() {
return mavenHome;
}
@CheckForNull
- public File antHome() {
+ public Path antHome() {
return antHome;
}
@CheckForNull
- public File javaHome() {
+ public Path javaHome() {
return javaHome;
}
- public File getOrchestratorHome() {
+ public Path getOrchestratorHome() {
return orchestratorHome;
}
- public File getCacheDir() {
- return new File(orchestratorHome, "cache");
+ public Path getCacheDir() {
+ return orchestratorHome.resolve("cache");
}
- public File getSonarQubeZipsDir() {
+ public Path getSonarQubeZipsDir() {
return sonarQubeZipsDir;
}
- public File workspace() {
+ public Path workspace() {
return workspace;
}
-
- @CheckForNull
- private static File initDir(Configuration config, List propertyKeys, @Nullable File defaultFile) {
- return propertyKeys.stream()
- .map(config::getString)
- .filter(Objects::nonNull)
- .findFirst()
- .map(File::new)
- .orElse(defaultFile);
- }
}
diff --git a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/config/package-info.java b/sonar-orchestrator-config/src/main/java/com/sonar/orchestrator/config/package-info.java
similarity index 96%
rename from sonar-orchestrator/src/main/java/com/sonar/orchestrator/config/package-info.java
rename to sonar-orchestrator-config/src/main/java/com/sonar/orchestrator/config/package-info.java
index 631a0749..dc1dd2dd 100644
--- a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/config/package-info.java
+++ b/sonar-orchestrator-config/src/main/java/com/sonar/orchestrator/config/package-info.java
@@ -1,5 +1,5 @@
/*
- * Orchestrator
+ * Orchestrator Configuration
* Copyright (C) 2011-2025 SonarSource SA
* mailto:info AT sonarsource DOT com
*
diff --git a/sonar-orchestrator/src/test/java/com/sonar/orchestrator/config/ConfigurationTest.java b/sonar-orchestrator-config/src/test/java/com/sonar/orchestrator/config/ConfigurationTest.java
similarity index 50%
rename from sonar-orchestrator/src/test/java/com/sonar/orchestrator/config/ConfigurationTest.java
rename to sonar-orchestrator-config/src/test/java/com/sonar/orchestrator/config/ConfigurationTest.java
index 284d327a..3e64ff06 100644
--- a/sonar-orchestrator/src/test/java/com/sonar/orchestrator/config/ConfigurationTest.java
+++ b/sonar-orchestrator-config/src/test/java/com/sonar/orchestrator/config/ConfigurationTest.java
@@ -1,5 +1,5 @@
/*
- * Orchestrator
+ * Orchestrator Configuration
* Copyright (C) 2011-2025 SonarSource SA
* mailto:info AT sonarsource DOT com
*
@@ -19,38 +19,33 @@
*/
package com.sonar.orchestrator.config;
-import com.google.common.collect.ImmutableMap;
-import com.sonar.orchestrator.PropertyAndEnvTest;
-import com.sonar.orchestrator.locator.FileLocation;
-import com.sonar.orchestrator.test.MockHttpServer;
+import com.github.tomakehurst.wiremock.WireMockServer;
import java.io.File;
import java.io.IOException;
-import java.net.URISyntaxException;
import java.net.URL;
-import java.util.HashMap;
+import java.nio.file.Path;
import java.util.Map;
import java.util.Properties;
import org.apache.commons.io.FileUtils;
-import org.apache.commons.io.FilenameUtils;
-import org.apache.commons.lang.StringUtils;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.junit.rules.TemporaryFolder;
-
-import static com.sonar.orchestrator.TestModules.setEnv;
+import org.apache.commons.lang3.Strings;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+
+import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
+import static com.github.tomakehurst.wiremock.client.WireMock.get;
+import static com.github.tomakehurst.wiremock.client.WireMock.notFound;
+import static com.github.tomakehurst.wiremock.client.WireMock.urlMatching;
+import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.assertj.core.data.MapEntry.entry;
-public class ConfigurationTest extends PropertyAndEnvTest {
-
- @Rule
- public ExpectedException thrown = ExpectedException.none();
- @Rule
- public TemporaryFolder temp = new TemporaryFolder();
+class ConfigurationTest {
@Test
- public void getString() {
+ void getString() {
Properties props = new Properties();
props.setProperty("foo", "bar");
Configuration config = Configuration.create(props);
@@ -61,7 +56,7 @@ public void getString() {
}
@Test
- public void getInt() {
+ void getInt() {
Properties props = new Properties();
props.setProperty("one", "1");
Configuration config = Configuration.create(props);
@@ -71,7 +66,7 @@ public void getInt() {
}
@Test
- public void asMap() {
+ void asMap() {
Properties props = new Properties();
props.setProperty("foo", "1");
props.setProperty("bar", "2");
@@ -82,24 +77,23 @@ public void asMap() {
}
@Test
- public void asMap_immutable() {
- thrown.expect(UnsupportedOperationException.class);
-
+ void asMap_immutable() {
Properties props = new Properties();
props.setProperty("foo", "bar");
Configuration config = Configuration.create(props);
- config.asMap().put("new", "property");
+ Map map = config.asMap();
+ assertThatThrownBy(() -> map.put("new", "property")).isInstanceOf(UnsupportedOperationException.class);
}
@Test
- public void createEnv() {
+ void createEnv() {
Configuration config = Configuration.createEnv();
assertThat(config.getString("java.io.tmpdir")).isNotNull();
}
@Test
- public void interpolateProperties() {
+ void interpolateProperties() {
Properties props = new Properties();
props.setProperty("where", "FR");
props.setProperty("codeStory", "devoxx${where}");
@@ -109,7 +103,7 @@ public void interpolateProperties() {
}
@Test
- public void loadPropertiesFile() {
+ void loadPropertiesFile() {
URL url = getClass().getResource("/com/sonar/orchestrator/config/ConfigurationTest/sample.properties");
Properties props = new Properties();
props.setProperty("foo", "bar");
@@ -122,10 +116,9 @@ public void loadPropertiesFile() {
}
@Test
- public void loadPropertiesFileFromHomeByDefault() throws IOException {
+ void loadPropertiesFileFromHomeByDefault(@TempDir Path homeDir) throws IOException {
URL url = getClass().getResource("/com/sonar/orchestrator/config/ConfigurationTest/sample.properties");
- File homeDir = temp.newFolder();
- FileUtils.copyURLToFile(url, new File(homeDir, "orchestrator.properties"));
+ FileUtils.copyURLToFile(url, new File(homeDir.toFile(), "orchestrator.properties"));
Properties props = new Properties();
props.setProperty("foo", "bar");
props.setProperty("orchestrator.home", homeDir.toString());
@@ -149,89 +142,34 @@ public void shouldOverridePropertiesFile() {
assertThat(config.getString("loadedFromFile")).isEqualTo("vrai");
}
- @Test
- public void getFileLocationOfShared() throws URISyntaxException {
- URL url = getClass().getResource("/com/sonar/orchestrator/config/ConfigurationTest/sample.properties");
- Properties props = new Properties();
- props.setProperty("orchestrator.configUrl", url.toString());
- props.setProperty("orchestrator.it_sources", FilenameUtils.getFullPath(url.toURI().getPath()));
- Configuration config = Configuration.create(props);
-
- FileLocation location = config.getFileLocationOfShared("sample.properties");
- assertThat(location.getFile()).isFile();
- assertThat(location.getFile()).exists();
- assertThat(location.getFile().getName()).isEqualTo("sample.properties");
- }
-
- @Test
- public void getFileLocationOfSharedApplyPriority() throws URISyntaxException {
- URL url = getClass().getResource("/com/sonar/orchestrator/config/ConfigurationTest/sample.properties");
- Properties props = new Properties();
- props.setProperty("orchestrator.configUrl", url.toString());
- Map envVariables = new HashMap<>(System.getenv());
- envVariables.put("SONAR_IT_SOURCES", FilenameUtils.getFullPath(url.toURI().getPath()));
- setEnv(ImmutableMap.copyOf(envVariables));
- props.setProperty("orchestrator.it_sources", FilenameUtils.getFullPath(url.toURI().getPath()));
- Configuration config = Configuration.create(props);
-
- FileLocation location = config.getFileLocationOfShared("sample.properties");
- assertThat(location.getFile().exists()).isTrue();
- }
-
- @Test
- public void getFileLocationOfShared_bad_place() {
- thrown.expect(IllegalStateException.class);
-
- URL url = getClass().getResource("/com/sonar/orchestrator/config/ConfigurationTest/sample.properties");
- Properties props = new Properties();
- props.setProperty("orchestrator.configUrl", url.toString());
- props.setProperty("orchestrator.it_sources", "/com/sonar/orchestrator/config/ConfigurationTest");
- Configuration config = Configuration.create(props);
-
- config.getFileLocationOfShared("/bad/path");
- }
-
- @Test
- public void getFileLocationOfShared_not_a_directory() {
- thrown.expect(IllegalStateException.class);
-
- URL url = getClass().getResource("/com/sonar/orchestrator/config/ConfigurationTest/sample.properties");
- Properties props = new Properties();
- props.setProperty("orchestrator.configUrl", url.toString());
- props.setProperty("orchestrator.it_sources", "/com/sonar/orchestrator/config/ConfigurationTest/sample.properties");
- Configuration config = Configuration.create(props);
-
- config.getFileLocationOfShared(".");
- }
-
@Test
public void loadRemotePropertiesFile() throws Exception {
- MockHttpServer server = new MockHttpServer();
- server.start();
- server.setMockResponseData("foo=bar");
+ WireMockServer wireMockServer = new WireMockServer(options().dynamicPort());
try {
+ wireMockServer.start();
+ wireMockServer.stubFor(get(urlMatching(".*")).willReturn(aResponse().withBody("foo=bar")));
Properties props = new Properties();
- props.setProperty("orchestrator.configUrl", "http://localhost:" + server.getPort() + "/jenkins/orchestrator.properties");
+ props.setProperty("orchestrator.configUrl", wireMockServer.baseUrl() + "/jenkins/orchestrator.properties");
Configuration config = Configuration.create(props);
assertThat(config.getString("foo")).isEqualTo("bar");
} finally {
- server.stop();
+ wireMockServer.stop();
}
}
- @Test(expected = IllegalStateException.class)
+ @Test
public void loadRemotePropertiesFile_fail_if_not_found() throws Exception {
- MockHttpServer server = new MockHttpServer();
- server.start();
- server.setMockResponseStatus(404);
+ WireMockServer wireMockServer = new WireMockServer(options().dynamicPort());
try {
+ wireMockServer.start();
+ wireMockServer.stubFor(get(urlMatching(".*")).willReturn(notFound()));
Properties props = new Properties();
- props.setProperty("orchestrator.configUrl", "http://localhost:" + server.getPort());
+ props.setProperty("orchestrator.configUrl", wireMockServer.baseUrl());
- Configuration.create(props);
+ assertThatThrownBy(() -> Configuration.create(props)).isInstanceOf(IllegalStateException.class);
} finally {
- server.stop();
+ wireMockServer.stop();
}
}
@@ -239,10 +177,10 @@ public void loadRemotePropertiesFile_fail_if_not_found() throws Exception {
* ORCH-88
*/
@Test
- public void interpolate_config_url() {
+ void interpolate_config_url() {
URL url = getClass().getResource("/com/sonar/orchestrator/config/ConfigurationTest/sample.properties");
Properties props = new Properties();
- String value = StringUtils.replace(url.toString(), "sample.properties", "${filename}");
+ String value = Strings.CS.replace(url.toString(), "sample.properties", "${filename}");
props.setProperty("orchestrator.configUrl", value);
props.setProperty("filename", "sample.properties");
@@ -252,7 +190,7 @@ public void interpolate_config_url() {
}
@Test
- public void should_support_h2_as_embedded_database() {
+ void should_support_h2_as_embedded_database() {
Properties props = new Properties();
props.setProperty("sonar.jdbc.dialect", "embedded");
@@ -260,28 +198,12 @@ public void should_support_h2_as_embedded_database() {
assertThat(config.getString("sonar.jdbc.dialect")).isEqualTo("h2");
}
- @Test
- public void configure_orchestrator_home_with_deprecated_property() throws Exception {
- String property = "SONAR_USER_HOME";
- testOrchestratorHome(property);
- }
-
- @Test
- public void configure_orchestrator_home() throws Exception {
- testOrchestratorHome("orchestrator.home");
- }
-
- @Test
- public void configure_orchestrator_home_with_env_variable() throws Exception {
- testOrchestratorHome("ORCHESTRATOR_HOME");
- }
-
- private void testOrchestratorHome(String property) throws IOException {
- File dir = temp.newFolder();
-
- Configuration underTest = Configuration.builder().setProperty(property, dir.getCanonicalPath()).build();
+ @ParameterizedTest
+ @ValueSource(strings = {"SONAR_USER_HOME", "ORCHESTRATOR_HOME", "orchestrator.home"})
+ void configure_orchestrator_home_with_deprecated_property(String property, @TempDir Path dir) {
+ Configuration underTest = Configuration.builder().setProperty(property, dir).build();
- assertThat(underTest.fileSystem().getOrchestratorHome().getCanonicalPath()).isEqualTo(dir.getCanonicalPath());
+ assertThat(underTest.fileSystem().getOrchestratorHome()).isEqualTo(dir);
}
}
diff --git a/sonar-orchestrator/src/test/java/com/sonar/orchestrator/config/FileSystemTest.java b/sonar-orchestrator-config/src/test/java/com/sonar/orchestrator/config/FileSystemTest.java
similarity index 54%
rename from sonar-orchestrator/src/test/java/com/sonar/orchestrator/config/FileSystemTest.java
rename to sonar-orchestrator-config/src/test/java/com/sonar/orchestrator/config/FileSystemTest.java
index 8e2fa4eb..e568fd7d 100644
--- a/sonar-orchestrator/src/test/java/com/sonar/orchestrator/config/FileSystemTest.java
+++ b/sonar-orchestrator-config/src/test/java/com/sonar/orchestrator/config/FileSystemTest.java
@@ -1,5 +1,5 @@
/*
- * Orchestrator
+ * Orchestrator Configuration
* Copyright (C) 2011-2025 SonarSource SA
* mailto:info AT sonarsource DOT com
*
@@ -19,69 +19,58 @@
*/
package com.sonar.orchestrator.config;
-import java.io.File;
import java.io.IOException;
+import java.nio.file.Path;
import org.apache.commons.io.FileUtils;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
import static org.assertj.core.api.Assertions.assertThat;
-public class FileSystemTest {
+class FileSystemTest {
- @Rule
- public TemporaryFolder temp = new TemporaryFolder();
- private File homeDir;
-
- @Before
- public void setUp() throws Exception {
- homeDir = temp.newFolder();
- }
+ @TempDir
+ private Path homeDir;
@Test
- public void test_defaults() throws Exception {
+ void test_defaults() throws Exception {
FileSystem underTest = new FileSystem(homeDir, Configuration.create());
- File userHome = FileUtils.getUserDirectory();
+ Path userHome = FileUtils.getUserDirectory().toPath();
// optional directories
assertThat(underTest.javaHome()).isNull();
assertThat(underTest.antHome()).isNull();
assertThat(underTest.mavenHome()).isNull();
- verifySameDirs(underTest.mavenLocalRepository(), new File(userHome, ".m2/repository"));
- verifySameDirs(underTest.workspace(), new File("target"));
+ verifySameDirs(underTest.mavenLocalRepository(), userHome.resolve(".m2/repository"));
+ verifySameDirs(underTest.workspace(), Path.of("target"));
verifySameDirs(underTest.getOrchestratorHome(), homeDir);
- verifySameDirs(underTest.getCacheDir(), new File(homeDir, "cache"));
- verifySameDirs(underTest.getSonarQubeZipsDir(), new File(homeDir, "zips"));
+ verifySameDirs(underTest.getCacheDir(), homeDir.resolve("cache"));
+ verifySameDirs(underTest.getSonarQubeZipsDir(), homeDir.resolve("zips"));
}
@Test
- public void configure_java_home() throws Exception {
- File dir = temp.newFolder();
- FileSystem underTest = new FileSystem(homeDir, Configuration.builder().setProperty("java.home", dir.getCanonicalPath()).build());
+ void configure_java_home(@TempDir Path dir) throws Exception {
+ FileSystem underTest = new FileSystem(homeDir, Configuration.builder().setProperty("java.home", dir).build());
verifySameDirs(underTest.javaHome(), dir);
}
@Test
- public void configure_maven_home() throws Exception {
- File dir = temp.newFolder();
- FileSystem underTest = new FileSystem(homeDir, Configuration.builder().setProperty("maven.home", dir.getCanonicalPath()).build());
+ void configure_maven_home(@TempDir Path dir) throws Exception {
+ FileSystem underTest = new FileSystem(homeDir, Configuration.builder().setProperty("maven.home", dir).build());
verifySameDirs(underTest.mavenHome(), dir);
}
@Test
- public void configure_maven_local_repository() throws Exception {
- File dir = temp.newFolder();
- FileSystem underTest = new FileSystem(homeDir, Configuration.builder().setProperty("maven.localRepository", dir.getCanonicalPath()).build());
+ void configure_maven_local_repository(@TempDir Path dir) throws Exception {
+ FileSystem underTest = new FileSystem(homeDir, Configuration.builder().setProperty("maven.localRepository", dir).build());
verifySameDirs(underTest.mavenLocalRepository(), dir);
}
- private static void verifySameDirs(File dir1, File dir2) throws IOException {
- assertThat(dir1.getCanonicalPath()).isEqualTo(dir2.getCanonicalPath());
+ private static void verifySameDirs(Path dir1, Path dir2) {
+ assertThat(dir1.toAbsolutePath()).isEqualTo(dir2.toAbsolutePath());
}
}
diff --git a/sonar-orchestrator/src/test/resources/com/sonar/orchestrator/config/ConfigurationTest/sample.properties b/sonar-orchestrator-config/src/test/resources/com/sonar/orchestrator/config/ConfigurationTest/sample.properties
similarity index 100%
rename from sonar-orchestrator/src/test/resources/com/sonar/orchestrator/config/ConfigurationTest/sample.properties
rename to sonar-orchestrator-config/src/test/resources/com/sonar/orchestrator/config/ConfigurationTest/sample.properties
diff --git a/sonar-orchestrator-junit5/pom.xml b/sonar-orchestrator-junit5/pom.xml
index ab3528e7..78548da2 100644
--- a/sonar-orchestrator-junit5/pom.xml
+++ b/sonar-orchestrator-junit5/pom.xml
@@ -19,7 +19,6 @@
org.junit.jupiter
junit-jupiter-api
- 5.9.2
org.sonarsource.orchestrator
@@ -31,7 +30,6 @@
org.junit.jupiter
junit-jupiter-engine
- 5.9.2
test
diff --git a/sonar-orchestrator/pom.xml b/sonar-orchestrator/pom.xml
index f6c70716..25b620d3 100644
--- a/sonar-orchestrator/pom.xml
+++ b/sonar-orchestrator/pom.xml
@@ -23,6 +23,11 @@
jsr305
provided
+
+ ${project.groupId}
+ sonar-orchestrator-config
+ ${project.version}
+
com.squareup.okhttp3
okhttp
@@ -36,12 +41,10 @@
commons-io
commons-io
- ${commonsIO.version}
- commons-lang
- commons-lang
- ${commonsLang.version}
+ org.apache.commons
+ commons-lang3
org.apache.commons
diff --git a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/Orchestrator.java b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/Orchestrator.java
index cfb5406e..5072930d 100644
--- a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/Orchestrator.java
+++ b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/Orchestrator.java
@@ -27,7 +27,6 @@
import com.sonar.orchestrator.build.SynchronousAnalyzer;
import com.sonar.orchestrator.config.Configuration;
import com.sonar.orchestrator.config.FileSystem;
-import com.sonar.orchestrator.config.Licenses;
import com.sonar.orchestrator.container.Server;
import com.sonar.orchestrator.container.SonarDistribution;
import com.sonar.orchestrator.db.Database;
@@ -35,8 +34,10 @@
import com.sonar.orchestrator.http.HttpCall;
import com.sonar.orchestrator.http.HttpMethod;
import com.sonar.orchestrator.http.HttpResponse;
+import com.sonar.orchestrator.licenses.Licenses;
import com.sonar.orchestrator.locator.FileLocation;
import com.sonar.orchestrator.locator.Location;
+import com.sonar.orchestrator.locator.Locators;
import com.sonar.orchestrator.server.Packaging;
import com.sonar.orchestrator.server.PackagingResolver;
import com.sonar.orchestrator.server.ServerCommandLineFactory;
@@ -44,6 +45,7 @@
import com.sonar.orchestrator.server.ServerProcess;
import com.sonar.orchestrator.server.ServerProcessImpl;
import com.sonar.orchestrator.server.StartupLogWatcher;
+import com.sonar.orchestrator.util.SharedDir;
import java.util.Arrays;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -59,6 +61,8 @@ public class Orchestrator {
private static final String SONAR_TOKEN_PROPERTY_NAME = "sonar.token";
private final Configuration config;
+ private final Locators locators;
+ private final SharedDir shareDir;
private final SonarDistribution distribution;
private final Licenses licenses;
private final AtomicBoolean started = new AtomicBoolean(false);
@@ -76,6 +80,8 @@ public class Orchestrator {
*/
public Orchestrator(Configuration config, SonarDistribution distribution, @Nullable StartupLogWatcher startupLogWatcher) {
this.config = requireNonNull(config);
+ this.locators = new Locators(config);
+ this.shareDir = new SharedDir(config);
this.distribution = requireNonNull(distribution);
this.licenses = new Licenses(config);
this.startupLogWatcher = startupLogWatcher;
@@ -89,12 +95,12 @@ public Orchestrator(Configuration config, SonarDistribution distribution, @Nulla
*/
public Server install() {
if (server == null) {
- database = new DefaultDatabase(config);
+ database = new DefaultDatabase(config, locators);
database.start();
- PackagingResolver packagingResolver = new PackagingResolver(config.locators());
+ PackagingResolver packagingResolver = new PackagingResolver(locators);
packaging = packagingResolver.resolve(distribution);
- ServerInstaller serverInstaller = new ServerInstaller(packagingResolver, config, config.locators(), database.getClient());
+ ServerInstaller serverInstaller = new ServerInstaller(packagingResolver, config, locators, database.getClient());
server = serverInstaller.install(distribution);
}
return server;
@@ -129,7 +135,7 @@ public void start() {
activateLicense();
}
- buildRunner = new BuildRunner(config);
+ buildRunner = new BuildRunner(config, locators);
}
/**
@@ -199,6 +205,10 @@ public Configuration getConfiguration() {
return config;
}
+ public Locators getLocators() {
+ return locators;
+ }
+
public Server getServer() {
return server;
}
@@ -208,7 +218,7 @@ public Server getServer() {
* Example : getFileLocationOfShared("javascript/performancing/pom.xml")
*/
public FileLocation getFileLocationOfShared(String relativePath) {
- return config.getFileLocationOfShared(relativePath);
+ return shareDir.getFileLocationOfShared(relativePath);
}
public SonarDistribution getDistribution() {
@@ -248,6 +258,13 @@ private BuildResult executeBuildInternal(Build> build, boolean quietly, boolea
return buildResult;
}
+ public String getDefaultAdminToken() {
+ if (this.adminToken != null) {
+ return this.adminToken;
+ }
+ return generateDefaultAdminToken();
+ }
+
private void setDefaultAdminToken(Build> build) {
if (build.getProperties().containsKey(SONAR_LOGIN_PROPERTY_NAME) || build.getProperties().containsKey(SONAR_TOKEN_PROPERTY_NAME)) {
return;
@@ -267,13 +284,6 @@ private void setDefaultAdminToken(Build> build) {
}
}
- public String getDefaultAdminToken() {
- if (this.adminToken != null) {
- return this.adminToken;
- }
- return generateDefaultAdminToken();
- }
-
private String generateDefaultAdminToken() {
HttpCall httpCall = server.newHttpCall("api/user_tokens/generate")
.setParam("name", UUID.randomUUID().toString())
diff --git a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/build/AbstractBuildExecutor.java b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/build/AbstractBuildExecutor.java
index 4eaf1656..0a937a5e 100644
--- a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/build/AbstractBuildExecutor.java
+++ b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/build/AbstractBuildExecutor.java
@@ -21,6 +21,7 @@
import com.sonar.orchestrator.config.Configuration;
import com.sonar.orchestrator.coverage.JaCoCoArgumentsBuilder;
+import com.sonar.orchestrator.locator.Locators;
import com.sonar.orchestrator.util.CommandExecutor;
import java.util.Map;
import org.slf4j.Logger;
@@ -30,18 +31,18 @@ abstract class AbstractBuildExecutor> {
private static final Logger LOG = LoggerFactory.getLogger(AbstractBuildExecutor.class);
- final BuildResult execute(T build, Configuration config, Map adjustedProperties) {
- return execute(build, config, adjustedProperties, CommandExecutor.create());
+ final BuildResult execute(T build, Configuration config, Locators locators, Map adjustedProperties) {
+ return execute(build, config, locators, adjustedProperties, CommandExecutor.create());
}
- abstract BuildResult execute(T build, Configuration config, Map adjustedProperties, CommandExecutor create);
+ abstract BuildResult execute(T build, Configuration config, Locators locators, Map adjustedProperties, CommandExecutor create);
/**
* Append JaCoCo agent JVM arguments to a given environment variable (SONAR_RUNNER_OPTS, MAVEN_OPTS, ...)
* @param optsVariableName The name of the environment variable to append to
*/
- static void appendCoverageArgumentToOpts(Map environmentVariables, Configuration config, String optsVariableName) {
- String jaCoCoArgument = JaCoCoArgumentsBuilder.getJaCoCoArgument(config);
+ static void appendCoverageArgumentToOpts(Map environmentVariables, Configuration config, Locators locators, String optsVariableName) {
+ String jaCoCoArgument = JaCoCoArgumentsBuilder.getJaCoCoArgument(config, locators);
if (jaCoCoArgument != null) {
if (environmentVariables.containsKey(optsVariableName)) {
String opts = environmentVariables.get(optsVariableName) + " " + jaCoCoArgument;
diff --git a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/build/AntBuild.java b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/build/AntBuild.java
index 14a350c8..d857219a 100644
--- a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/build/AntBuild.java
+++ b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/build/AntBuild.java
@@ -21,6 +21,7 @@
import com.sonar.orchestrator.config.Configuration;
import com.sonar.orchestrator.locator.Location;
+import com.sonar.orchestrator.locator.Locators;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
@@ -33,16 +34,16 @@ public final class AntBuild extends Build {
private Location buildLocation;
private List targets;
- public File getAntHome() {
- return antHome;
+ public static AntBuild create() {
+ return new AntBuild();
}
- public Location getBuildLocation() {
- return buildLocation;
+ public static AntBuild create(Location buildFile, String[] targets, String... keyValueProperties) {
+ return new AntBuild().setBuildLocation(buildFile).setTargets(targets).setProperties(keyValueProperties);
}
- public List getTargets() {
- return targets;
+ public File getAntHome() {
+ return antHome;
}
public AntBuild setAntHome(File antHome) {
@@ -50,16 +51,29 @@ public AntBuild setAntHome(File antHome) {
return this;
}
+ public Location getBuildLocation() {
+ return buildLocation;
+ }
+
public AntBuild setBuildLocation(Location buildLocation) {
this.buildLocation = buildLocation;
return this;
}
+ public List getTargets() {
+ return targets;
+ }
+
public AntBuild setTargets(List targets) {
this.targets = targets;
return this;
}
+ public AntBuild setTargets(String... targets) {
+ this.targets = Arrays.asList(targets);
+ return this;
+ }
+
public AntBuild addTarget(String s) {
if (this.targets == null) {
this.targets = new ArrayList<>();
@@ -68,11 +82,6 @@ public AntBuild addTarget(String s) {
return this;
}
- public AntBuild setTargets(String... targets) {
- this.targets = Arrays.asList(targets);
- return this;
- }
-
@Override
public String toString() {
StringBuilder sb = new StringBuilder("AntBuild{");
@@ -84,15 +93,7 @@ public String toString() {
}
@Override
- BuildResult execute(Configuration config, Map adjustedProperties) {
- return new AntBuildExecutor().execute(this, config, adjustedProperties);
- }
-
- public static AntBuild create() {
- return new AntBuild();
- }
-
- public static AntBuild create(Location buildFile, String[] targets, String... keyValueProperties) {
- return new AntBuild().setBuildLocation(buildFile).setTargets(targets).setProperties(keyValueProperties);
+ BuildResult execute(Configuration config, Locators locators, Map adjustedProperties) {
+ return new AntBuildExecutor().execute(this, config, locators, adjustedProperties);
}
}
diff --git a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/build/AntBuildExecutor.java b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/build/AntBuildExecutor.java
index 9b25ae82..83802999 100644
--- a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/build/AntBuildExecutor.java
+++ b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/build/AntBuildExecutor.java
@@ -20,40 +20,52 @@
package com.sonar.orchestrator.build;
import com.sonar.orchestrator.config.Configuration;
+import com.sonar.orchestrator.locator.Locators;
import com.sonar.orchestrator.util.Command;
import com.sonar.orchestrator.util.CommandExecutor;
import com.sonar.orchestrator.util.StreamConsumer;
import java.io.File;
-import java.io.IOException;
+import java.nio.file.Path;
import java.util.Map;
import javax.annotation.Nullable;
-import org.apache.commons.lang.SystemUtils;
+import org.apache.commons.lang3.SystemUtils;
import org.slf4j.LoggerFactory;
import static com.sonar.orchestrator.util.OrchestratorUtils.checkState;
class AntBuildExecutor extends AbstractBuildExecutor {
+ private static String getAntPath(@Nullable Path antHome) {
+ String program = "ant";
+ if (SystemUtils.IS_OS_WINDOWS) {
+ program += ".bat";
+ }
+ if (antHome != null) {
+ program = antHome.resolve("bin/" + program).toAbsolutePath().toString();
+ }
+ return program;
+ }
+
@Override
- BuildResult execute(AntBuild build, Configuration config, Map adjustedProperties, CommandExecutor commandExecutor) {
+ BuildResult execute(AntBuild build, Configuration config, Locators locators, Map adjustedProperties, CommandExecutor commandExecutor) {
BuildResult result = new BuildResult();
for (String target : build.getTargets()) {
- executeTarget(build, config, adjustedProperties, target, result, commandExecutor);
+ executeTarget(build, config, locators, adjustedProperties, target, result, commandExecutor);
}
return result;
}
- private void executeTarget(AntBuild build, Configuration config, Map adjustedProperties, String target,
+ private void executeTarget(AntBuild build, Configuration config, Locators locators, Map adjustedProperties, String target,
BuildResult result, CommandExecutor commandExecutor) {
try {
- File home = build.getAntHome() != null ? build.getAntHome() : config.fileSystem().antHome();
+ Path home = build.getAntHome() != null ? build.getAntHome().toPath() : config.fileSystem().antHome();
Command command = Command.create(getAntPath(home));
for (Map.Entry env : build.getEnvironmentVariables().entrySet()) {
command.setEnvironmentVariable(env.getKey(), env.getValue());
}
command.addArguments(target.split(" "));
- File antFile = config.locators().locate(build.getBuildLocation());
+ File antFile = locators.locate(build.getBuildLocation());
checkState(antFile.exists(), "Ant build file does not exist: %s", build.getBuildLocation());
command.addArgument("-f").addArgument(antFile.getCanonicalPath());
@@ -71,15 +83,4 @@ private void executeTarget(AntBuild build, Configuration config, Map adjustedProperties);
+ abstract BuildResult execute(Configuration config, Locators locators, Map adjustedProperties);
}
diff --git a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/build/BuildRunner.java b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/build/BuildRunner.java
index 06be33ff..e3d60d94 100644
--- a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/build/BuildRunner.java
+++ b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/build/BuildRunner.java
@@ -21,6 +21,7 @@
import com.sonar.orchestrator.config.Configuration;
import com.sonar.orchestrator.container.Server;
+import com.sonar.orchestrator.locator.Locators;
import java.util.HashMap;
import java.util.Map;
import javax.annotation.Nullable;
@@ -29,13 +30,15 @@ public class BuildRunner {
public static final String SONAR_HOST_URL = "sonar.host.url";
private final Configuration config;
+ private final Locators locators;
- public BuildRunner(Configuration config) {
+ public BuildRunner(Configuration config, Locators locators) {
this.config = config;
+ this.locators = locators;
}
public BuildResult runQuietly(@Nullable Server server, Build> build) {
- return build.execute(config, adjustProperties(server, build));
+ return build.execute(config, locators, adjustProperties(server, build));
}
public BuildResult run(@Nullable Server server, Build> build) {
diff --git a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/build/GradleBuild.java b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/build/GradleBuild.java
index ecbffedf..3be4d0d4 100644
--- a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/build/GradleBuild.java
+++ b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/build/GradleBuild.java
@@ -22,6 +22,7 @@
import com.sonar.orchestrator.config.Configuration;
import com.sonar.orchestrator.locator.FileLocation;
import com.sonar.orchestrator.locator.Location;
+import com.sonar.orchestrator.locator.Locators;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
@@ -37,8 +38,8 @@ public final class GradleBuild extends Build {
private List tasks = new ArrayList<>();
@Override
- BuildResult execute(Configuration config, Map adjustedProperties) {
- return new GradleBuildExecutor().execute(this, config, adjustedProperties);
+ BuildResult execute(Configuration config, Locators locators, Map adjustedProperties) {
+ return new GradleBuildExecutor().execute(this, config, locators, adjustedProperties);
}
public GradleBuild setProjectDirectory(Location projectDirectory) {
diff --git a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/build/GradleBuildExecutor.java b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/build/GradleBuildExecutor.java
index de81acff..586adf79 100644
--- a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/build/GradleBuildExecutor.java
+++ b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/build/GradleBuildExecutor.java
@@ -20,12 +20,13 @@
package com.sonar.orchestrator.build;
import com.sonar.orchestrator.config.Configuration;
+import com.sonar.orchestrator.locator.Locators;
import com.sonar.orchestrator.util.Command;
import com.sonar.orchestrator.util.CommandExecutor;
import com.sonar.orchestrator.util.StreamConsumer;
import java.io.File;
import java.util.Map;
-import org.apache.commons.lang.SystemUtils;
+import org.apache.commons.lang3.SystemUtils;
import org.slf4j.LoggerFactory;
import static com.sonar.orchestrator.util.OrchestratorUtils.checkState;
@@ -44,19 +45,19 @@ public class GradleBuildExecutor extends AbstractBuildExecutor {
}
@Override
- BuildResult execute(GradleBuild build, Configuration config, Map adjustedProperties, CommandExecutor commandExecutor) {
+ BuildResult execute(GradleBuild build, Configuration config, Locators locators, Map adjustedProperties, CommandExecutor commandExecutor) {
BuildResult result = new BuildResult();
for (String task : build.getTasks()) {
- executeTask(build, config, adjustedProperties, task, result, commandExecutor);
+ executeTask(build, config, locators, adjustedProperties, task, result, commandExecutor);
}
return result;
}
- private void executeTask(GradleBuild build, Configuration config, Map adjustedProperties, String task,
+ private void executeTask(GradleBuild build, Configuration config, Locators locators, Map adjustedProperties, String task,
final BuildResult result, CommandExecutor commandExecutor) {
try {
- File projectDir = config.locators().locate(build.getProjectDirectory());
+ File projectDir = locators.locate(build.getProjectDirectory());
File gradlew = getGradleWrapper(projectDir);
checkState(gradlew.exists(), "Gradle wrapper does not exist: '%s'", gradlew.toString());
diff --git a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/build/MavenBuild.java b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/build/MavenBuild.java
index 37cc5550..62c9fa2b 100644
--- a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/build/MavenBuild.java
+++ b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/build/MavenBuild.java
@@ -22,6 +22,7 @@
import com.sonar.orchestrator.config.Configuration;
import com.sonar.orchestrator.locator.FileLocation;
import com.sonar.orchestrator.locator.Location;
+import com.sonar.orchestrator.locator.Locators;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
@@ -142,7 +143,7 @@ public static MavenBuild create(File pom) {
}
@Override
- BuildResult execute(Configuration config, Map adjustedProperties) {
- return new MavenBuildExecutor().execute(this, config, adjustedProperties);
+ BuildResult execute(Configuration config, Locators locators, Map adjustedProperties) {
+ return new MavenBuildExecutor().execute(this, config, locators, adjustedProperties);
}
}
diff --git a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/build/MavenBuildExecutor.java b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/build/MavenBuildExecutor.java
index 58babb12..5315e711 100644
--- a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/build/MavenBuildExecutor.java
+++ b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/build/MavenBuildExecutor.java
@@ -20,23 +20,25 @@
package com.sonar.orchestrator.build;
import com.sonar.orchestrator.config.Configuration;
+import com.sonar.orchestrator.locator.Locators;
import com.sonar.orchestrator.util.Command;
import com.sonar.orchestrator.util.CommandExecutor;
import com.sonar.orchestrator.util.StreamConsumer;
import java.io.File;
import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
import java.util.Map;
import java.util.Optional;
-import org.apache.commons.lang.SystemUtils;
+import org.apache.commons.lang3.SystemUtils;
import org.slf4j.LoggerFactory;
import static com.sonar.orchestrator.util.OrchestratorUtils.checkState;
class MavenBuildExecutor extends AbstractBuildExecutor {
- private final Os os;
-
private static final String MAVEN_OPTS = "MAVEN_OPTS";
+ private final Os os;
// visible for tests
MavenBuildExecutor(Os os) {
@@ -48,19 +50,19 @@ public MavenBuildExecutor() {
}
@Override
- BuildResult execute(MavenBuild build, Configuration config, Map adjustedProperties, CommandExecutor commandExecutor) {
+ BuildResult execute(MavenBuild build, Configuration config, Locators locators, Map adjustedProperties, CommandExecutor commandExecutor) {
BuildResult result = new BuildResult();
for (String goal : build.getGoals()) {
- appendCoverageArgumentToOpts(build.getEnvironmentVariables(), config, MAVEN_OPTS);
- executeGoal(build, config, adjustedProperties, goal, result, commandExecutor);
+ appendCoverageArgumentToOpts(build.getEnvironmentVariables(), config, locators, MAVEN_OPTS);
+ executeGoal(build, config, locators, adjustedProperties, goal, result, commandExecutor);
}
return result;
}
- private void executeGoal(MavenBuild build, Configuration config, Map adjustedProperties, String goal,
+ private void executeGoal(MavenBuild build, Configuration config, Locators locators, Map adjustedProperties, String goal,
final BuildResult result, CommandExecutor commandExecutor) {
try {
- File mavenHome = config.fileSystem().mavenHome();
+ Path mavenHome = config.fileSystem().mavenHome();
Command command = Command.create(buildMvnPath(config));
if (build.getExecutionDir() != null) {
command.setDirectory(build.getExecutionDir());
@@ -70,7 +72,7 @@ private void executeGoal(MavenBuild build, Configuration config, Map binary = Optional.ofNullable(config.getStringByKeys("maven.binary", "MAVEN_BINARY"));
- File home = config.fileSystem().mavenHome();
+ Path home = config.fileSystem().mavenHome();
if (home == null) {
return binary.orElse(os.isWindows() ? "mvn.cmd" : "mvn");
}
if (binary.isPresent()) {
- return new File(home, "bin/" + binary.get()).getCanonicalPath();
+ return home.resolve("bin/" + binary.get()).toAbsolutePath().toString();
}
if (os.isWindows()) {
// .bat is required for maven versions <= 3.2
- File bin = new File(home, "bin/mvn.bat");
- if (bin.exists()) {
- return bin.getCanonicalPath();
+ Path bin = home.resolve("bin/mvn.bat");
+ if (Files.exists(bin)) {
+ return bin.toAbsolutePath().toString();
}
- return new File(home, "bin/mvn.cmd").getCanonicalPath();
+ return home.resolve("bin/mvn.cmd").toAbsolutePath().toString();
}
- return new File(home, "bin/mvn").getCanonicalPath();
+ return home.resolve("bin/mvn").toAbsolutePath().toString();
}
static class Os {
diff --git a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/build/ScannerForMSBuild.java b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/build/ScannerForMSBuild.java
index 35557780..45e33359 100644
--- a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/build/ScannerForMSBuild.java
+++ b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/build/ScannerForMSBuild.java
@@ -20,20 +20,20 @@
package com.sonar.orchestrator.build;
import com.sonar.orchestrator.config.Configuration;
+import com.sonar.orchestrator.locator.ArtifactoryFactory;
import com.sonar.orchestrator.locator.GitHub;
import com.sonar.orchestrator.locator.GitHubImpl;
import com.sonar.orchestrator.locator.Location;
import com.sonar.orchestrator.locator.Locators;
import com.sonar.orchestrator.locator.MavenLocation;
import com.sonar.orchestrator.version.Version;
-import java.util.Optional;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
import java.io.File;
import java.util.Map;
+import java.util.Optional;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import static com.sonar.orchestrator.util.OrchestratorUtils.checkArgument;
import static com.sonar.orchestrator.util.OrchestratorUtils.checkState;
@@ -46,11 +46,11 @@
* @since 3.13
*/
public class ScannerForMSBuild extends Build {
+ public static final String LATEST_RELEASE = "LATEST_RELEASE";
// 4.1.0.1148
static final int DOT_NET_CORE_INTRODUCTION_MAJOR_VERSION = 4;
static final int DOT_NET_CORE_INTRODUCTION_MINOR_VERSION = 1;
public static final String DOT_NET_CORE_INTRODUCTION_VERSION = DOT_NET_CORE_INTRODUCTION_MAJOR_VERSION + "." + DOT_NET_CORE_INTRODUCTION_MINOR_VERSION;
- public static final String LATEST_RELEASE = "LATEST_RELEASE";
private static final Logger LOG = LoggerFactory.getLogger(ScannerForMSBuild.class);
private final GitHub gitHub;
@@ -72,6 +72,46 @@ public class ScannerForMSBuild extends Build {
this.gitHub = gitHub;
}
+ private static Optional getLatestScannerVersionFromArtifactory() {
+ Configuration config = Configuration.createEnv();
+ Locators locators = new Locators(config);
+ MavenLocation build = MavenLocation.builder()
+ .setGroupId("org.sonarsource.scanner.msbuild")
+ .setArtifactId("sonar-scanner")
+ .setVersion(LATEST_RELEASE)
+ .build();
+ return locators.maven().resolveVersion(build);
+ }
+
+ public static ScannerForMSBuild create() {
+ return new ScannerForMSBuild();
+ }
+
+ public static ScannerForMSBuild create(File projectDir, String... keyValueProperties) {
+ return
+ // default value
+ create()
+ // incoming values
+ .setProjectDir(projectDir)
+ .setProperties(keyValueProperties);
+ }
+
+ private static void checkDotNetCoreCompatibility(Version scannerVersion, boolean useDotNetCore) {
+ if (useDotNetCore) {
+ checkArgument(scannerVersion != null, "Default version of SonarScanner for MSBuild embedded by Orchestrator does not support .NET Core. "
+ + "Please provide a scanner version >= %s.", DOT_NET_CORE_INTRODUCTION_VERSION);
+ checkState(scannerVersion.isGreaterThanOrEquals(DOT_NET_CORE_INTRODUCTION_MAJOR_VERSION, DOT_NET_CORE_INTRODUCTION_MINOR_VERSION),
+ "Version of ScannerForMSBuild should be greater than or equals to %s to be able to use .Net Core.",
+ DOT_NET_CORE_INTRODUCTION_VERSION);
+ }
+ }
+
+ private static void checkProjectDir(File dir) {
+ requireNonNull(dir, "Project directory must be set");
+ checkArgument(dir.exists(), "Project directory must exist");
+ checkArgument(dir.isDirectory(), "Project directory must be... a directory");
+ }
+
@CheckForNull
public Version scannerVersion() {
return scannerVersion;
@@ -90,21 +130,7 @@ public ScannerForMSBuild setUseDotNetCore(boolean useDotnetCore) {
}
/**
- * Providing a .NET Core executable to be used during analysis, force usage of .NET Core version of the scanner. If
- * not provided and usage of .NET Core is enabled, orchestrator will assume that the dotnet executable is available in PATH.
- *
- * Note that there is no need to call {@link #setUseDotNetCore(boolean)} if manually setting the dotnet executable.
- *
- * @param dotNetCoreExecutable the path to the .NET Core executable
- * @return The scanner being built
- */
- public ScannerForMSBuild setDotNetCoreExecutable(File dotNetCoreExecutable) {
- this.dotNetCoreExecutable = dotNetCoreExecutable;
- return setUseDotNetCore(true);
- }
-
- /**
- * In order to use .NET Core, the provided version of SonarScanner for MSBuild should be higher or
+ * In order to use .NET Core, the provided version of SonarScanner for MSBuild should be higher or
* equal to {@link ScannerForMSBuild#DOT_NET_CORE_INTRODUCTION_VERSION}.
*
* @return true if using .NET Core and provided version of SonarScanner for MSBuild is compatible.
@@ -122,10 +148,30 @@ public File getDotNetCoreExecutable() {
return dotNetCoreExecutable;
}
+ /**
+ * Providing a .NET Core executable to be used during analysis, force usage of .NET Core version of the scanner. If
+ * not provided and usage of .NET Core is enabled, orchestrator will assume that the dotnet executable is available in PATH.
+ *
+ * Note that there is no need to call {@link #setUseDotNetCore(boolean)} if manually setting the dotnet executable.
+ *
+ * @param dotNetCoreExecutable the path to the .NET Core executable
+ * @return The scanner being built
+ */
+ public ScannerForMSBuild setDotNetCoreExecutable(File dotNetCoreExecutable) {
+ this.dotNetCoreExecutable = dotNetCoreExecutable;
+ return setUseDotNetCore(true);
+ }
+
public File getProjectDir() {
return projectDir;
}
+ public ScannerForMSBuild setProjectDir(File dir) {
+ checkProjectDir(dir);
+ this.projectDir = dir;
+ return this;
+ }
+
@CheckForNull
public Location getLocation() {
return location;
@@ -135,6 +181,11 @@ public boolean isDebugLogs() {
return debugLogs;
}
+ public ScannerForMSBuild setDebugLogs(boolean b) {
+ this.debugLogs = b;
+ return this;
+ }
+
public ScannerForMSBuild setScannerVersion(String s) {
checkArgument(!isEmpty(s), "version must be set");
if (s.equals(LATEST_RELEASE)) {
@@ -151,39 +202,18 @@ public ScannerForMSBuild setScannerVersion(String s) {
return this;
}
- private static Optional getLatestScannerVersionFromArtifactory() {
- Locators locators = Configuration.createEnv().locators();
- MavenLocation build = MavenLocation.builder()
- .setGroupId("org.sonarsource.scanner.msbuild")
- .setArtifactId("sonar-scanner")
- .setVersion(LATEST_RELEASE)
- .build();
- return locators.maven().resolveVersion(build);
- }
-
public ScannerForMSBuild setScannerLocation(Location location) {
requireNonNull(location);
this.location = location;
return this;
}
- public ScannerForMSBuild setProjectDir(File dir) {
- checkProjectDir(dir);
- this.projectDir = dir;
- return this;
- }
-
- public ScannerForMSBuild setProjectKey(@Nullable String s) {
- this.projectKey = s;
- return this;
- }
-
public String getProjectKey() {
return projectKey;
}
- public ScannerForMSBuild setProjectVersion(@Nullable String s) {
- this.projectVersion = s;
+ public ScannerForMSBuild setProjectKey(@Nullable String s) {
+ this.projectKey = s;
return this;
}
@@ -191,8 +221,8 @@ public String getProjectVersion() {
return projectVersion;
}
- public ScannerForMSBuild setProjectName(@Nullable String s) {
- this.projectName = s;
+ public ScannerForMSBuild setProjectVersion(@Nullable String s) {
+ this.projectVersion = s;
return this;
}
@@ -200,28 +230,15 @@ public String getProjectName() {
return projectName;
}
- public ScannerForMSBuild setDebugLogs(boolean b) {
- this.debugLogs = b;
+ public ScannerForMSBuild setProjectName(@Nullable String s) {
+ this.projectName = s;
return this;
}
- public static ScannerForMSBuild create() {
- return new ScannerForMSBuild();
- }
-
- public static ScannerForMSBuild create(File projectDir, String... keyValueProperties) {
- return
- // default value
- create()
- // incoming values
- .setProjectDir(projectDir)
- .setProperties(keyValueProperties);
- }
-
@Override
- BuildResult execute(Configuration config, Map adjustedProperties) {
+ BuildResult execute(Configuration config, Locators locators, Map adjustedProperties) {
check();
- return new ScannerForMSBuildExecutor().execute(this, config, adjustedProperties);
+ return new ScannerForMSBuildExecutor().execute(this, config, locators, adjustedProperties);
}
void check() {
@@ -229,20 +246,4 @@ void check() {
checkDotNetCoreCompatibility(scannerVersion, useDotnetCore);
}
- private static void checkDotNetCoreCompatibility(Version scannerVersion, boolean useDotNetCore) {
- if (useDotNetCore) {
- checkArgument(scannerVersion != null, "Default version of SonarScanner for MSBuild embedded by Orchestrator does not support .NET Core. "
- + "Please provide a scanner version >= %s.", DOT_NET_CORE_INTRODUCTION_VERSION);
- checkState(scannerVersion.isGreaterThanOrEquals(DOT_NET_CORE_INTRODUCTION_MAJOR_VERSION, DOT_NET_CORE_INTRODUCTION_MINOR_VERSION),
- "Version of ScannerForMSBuild should be greater than or equals to %s to be able to use .Net Core.",
- DOT_NET_CORE_INTRODUCTION_VERSION);
- }
- }
-
- private static void checkProjectDir(File dir) {
- requireNonNull(dir, "Project directory must be set");
- checkArgument(dir.exists(), "Project directory must exist");
- checkArgument(dir.isDirectory(), "Project directory must be... a directory");
- }
-
}
diff --git a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/build/ScannerForMSBuildExecutor.java b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/build/ScannerForMSBuildExecutor.java
index a5833303..092e56cb 100644
--- a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/build/ScannerForMSBuildExecutor.java
+++ b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/build/ScannerForMSBuildExecutor.java
@@ -20,6 +20,7 @@
package com.sonar.orchestrator.build;
import com.sonar.orchestrator.config.Configuration;
+import com.sonar.orchestrator.locator.Locators;
import com.sonar.orchestrator.util.Command;
import com.sonar.orchestrator.util.CommandExecutor;
import com.sonar.orchestrator.util.StreamConsumer;
@@ -32,8 +33,8 @@
class ScannerForMSBuildExecutor extends AbstractBuildExecutor {
@Override
- BuildResult execute(ScannerForMSBuild build, Configuration config, Map adjustedProperties, CommandExecutor create) {
- return execute(build, config, adjustedProperties, new ScannerForMSBuildInstaller(config.locators()), create);
+ BuildResult execute(ScannerForMSBuild build, Configuration config, Locators locators, Map adjustedProperties, CommandExecutor create) {
+ return execute(build, config, adjustedProperties, new ScannerForMSBuildInstaller(locators), create);
}
BuildResult execute(ScannerForMSBuild build, Configuration config, Map adjustedProperties, ScannerForMSBuildInstaller installer,
@@ -42,7 +43,7 @@ BuildResult execute(ScannerForMSBuild build, Configuration config, Map adjustedProperties) {
+ BuildResult execute(Configuration config, Locators locators, Map adjustedProperties) {
check();
- return new SonarScannerExecutor().execute(this, config, adjustedProperties);
+ return new SonarScannerExecutor().execute(this, config, locators, adjustedProperties);
}
void check() {
diff --git a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/build/SonarScannerExecutor.java b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/build/SonarScannerExecutor.java
index 8160a6c2..e66110a9 100644
--- a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/build/SonarScannerExecutor.java
+++ b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/build/SonarScannerExecutor.java
@@ -20,6 +20,7 @@
package com.sonar.orchestrator.build;
import com.sonar.orchestrator.config.Configuration;
+import com.sonar.orchestrator.locator.Locators;
import com.sonar.orchestrator.util.Command;
import com.sonar.orchestrator.util.CommandExecutor;
import com.sonar.orchestrator.util.StreamConsumer;
@@ -31,29 +32,6 @@ class SonarScannerExecutor extends AbstractBuildExecutor {
private static final String SONAR_SCANNER_OPTS = "SONAR_SCANNER_OPTS";
- @Override
- BuildResult execute(SonarScanner build, Configuration config, Map adjustedProperties, CommandExecutor create) {
- return execute(build, config, adjustedProperties, new SonarScannerInstaller(config.locators()), create);
- }
-
- BuildResult execute(SonarScanner build, Configuration config, Map adjustedProperties, SonarScannerInstaller installer,
- CommandExecutor commandExecutor) {
- BuildResult result = new BuildResult();
- File scannerScript = installer.install(build.scannerVersion(), build.classifier(), config.fileSystem().workspace());
- try {
- appendCoverageArgumentToOpts(build.getEnvironmentVariables(), config, SONAR_SCANNER_OPTS);
- Command command = createCommand(build, adjustedProperties, scannerScript);
- LoggerFactory.getLogger(SonarScanner.class).info("Execute: {}", command);
- StreamConsumer.Pipe writer = new StreamConsumer.Pipe(result.getLogsWriter());
- int status = commandExecutor.execute(command, writer, build.getTimeoutSeconds() * 1000);
- result.addStatus(status);
- return result;
-
- } catch (Exception e) {
- throw new IllegalStateException("Fail to execute SonarQube Scanner", e);
- }
- }
-
private static Command createCommand(SonarScanner build, Map adjustedProperties, File runnerScript) {
Command command = Command.create(runnerScript.getAbsolutePath());
command.setDirectory(build.getProjectDir());
@@ -75,4 +53,27 @@ private static Command createCommand(SonarScanner build, Map adj
return command;
}
+ @Override
+ BuildResult execute(SonarScanner build, Configuration config, Locators locators, Map adjustedProperties, CommandExecutor create) {
+ return execute(build, config, locators, adjustedProperties, new SonarScannerInstaller(locators), create);
+ }
+
+ BuildResult execute(SonarScanner build, Configuration config, Locators locators, Map adjustedProperties, SonarScannerInstaller installer,
+ CommandExecutor commandExecutor) {
+ BuildResult result = new BuildResult();
+ File scannerScript = installer.install(build.scannerVersion(), build.classifier(), config.fileSystem().workspace().toFile());
+ try {
+ appendCoverageArgumentToOpts(build.getEnvironmentVariables(), config, locators, SONAR_SCANNER_OPTS);
+ Command command = createCommand(build, adjustedProperties, scannerScript);
+ LoggerFactory.getLogger(SonarScanner.class).info("Execute: {}", command);
+ StreamConsumer.Pipe writer = new StreamConsumer.Pipe(result.getLogsWriter());
+ int status = commandExecutor.execute(command, writer, build.getTimeoutSeconds() * 1000);
+ result.addStatus(status);
+ return result;
+
+ } catch (Exception e) {
+ throw new IllegalStateException("Fail to execute SonarQube Scanner", e);
+ }
+ }
+
}
diff --git a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/build/SonarScannerInstaller.java b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/build/SonarScannerInstaller.java
index 7fdccfe7..d3b7a997 100644
--- a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/build/SonarScannerInstaller.java
+++ b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/build/SonarScannerInstaller.java
@@ -27,7 +27,7 @@
import java.net.URL;
import javax.annotation.Nullable;
import org.apache.commons.io.FileUtils;
-import org.apache.commons.lang.SystemUtils;
+import org.apache.commons.lang3.SystemUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/container/Server.java b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/container/Server.java
index fa33dd0b..659ab5e7 100644
--- a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/container/Server.java
+++ b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/container/Server.java
@@ -35,7 +35,7 @@
import okhttp3.HttpUrl;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang3.StringUtils;
import static java.nio.charset.StandardCharsets.UTF_8;
diff --git a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/coverage/JaCoCoArgumentsBuilder.java b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/coverage/JaCoCoArgumentsBuilder.java
index d1808fe6..76adbc74 100644
--- a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/coverage/JaCoCoArgumentsBuilder.java
+++ b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/coverage/JaCoCoArgumentsBuilder.java
@@ -20,6 +20,7 @@
package com.sonar.orchestrator.coverage;
import com.sonar.orchestrator.config.Configuration;
+import com.sonar.orchestrator.locator.Locators;
import com.sonar.orchestrator.locator.MavenLocation;
import java.io.File;
import java.util.Properties;
@@ -36,10 +37,6 @@ public class JaCoCoArgumentsBuilder {
static String jaCoCoVersion;
static MavenLocation agentLocation;
- private JaCoCoArgumentsBuilder() {
- // prevents instantiation
- }
-
static {
Properties props = readProperties("jacoco.properties");
jaCoCoVersion = props.getProperty("jacoco.version");
@@ -51,6 +48,10 @@ private JaCoCoArgumentsBuilder() {
.build();
}
+ private JaCoCoArgumentsBuilder() {
+ // prevents instantiation
+ }
+
static Properties readProperties(String propertyFileName) {
Properties props = new Properties();
try {
@@ -66,7 +67,7 @@ static Properties readProperties(String propertyFileName) {
* @param config
* @return null if code coverage is not enabled
*/
- public static String getJaCoCoArgument(Configuration config) {
+ public static String getJaCoCoArgument(Configuration config, Locators locators) {
String computeCoverage = config.getString("orchestrator.computeCoverage", "false");
if (!"true".equals(computeCoverage)) {
return null;
@@ -75,7 +76,7 @@ public static String getJaCoCoArgument(Configuration config) {
String destFile = config.getString("orchestrator.coverageReportPath", "target/jacoco.exec");
destFile = FilenameUtils.separatorsToUnix(destFile);
- File jacocoLocation = config.locators().locate(agentLocation);
+ File jacocoLocation = locators.locate(agentLocation);
if (jacocoLocation == null) {
throw new IllegalStateException("Unable to locate jacoco: " + agentLocation + " in " + config.fileSystem().mavenLocalRepository());
}
diff --git a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/db/DefaultDatabase.java b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/db/DefaultDatabase.java
index 8978b914..629bfdfe 100644
--- a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/db/DefaultDatabase.java
+++ b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/db/DefaultDatabase.java
@@ -20,6 +20,7 @@
package com.sonar.orchestrator.db;
import com.sonar.orchestrator.config.Configuration;
+import com.sonar.orchestrator.locator.Locators;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
@@ -47,8 +48,8 @@ public final class DefaultDatabase implements Database {
private DatabaseClient databaseClient;
private boolean started = false;
- public DefaultDatabase(Configuration config) {
- this.databaseClient = DatabaseFactory.create(config, config.locators());
+ public DefaultDatabase(Configuration config, Locators locators) {
+ this.databaseClient = DatabaseFactory.create(config, locators);
}
public DefaultDatabase(DatabaseClient client) {
@@ -316,7 +317,7 @@ private List selectOtherConnections(Connection connection) throws SQLExc
}
List spids = new ArrayList<>();
try (Statement stmt = connection.createStatement();
- ResultSet rs = stmt.executeQuery(sql)) {
+ ResultSet rs = stmt.executeQuery(sql)) {
while (rs.next()) {
String spid = rs.getString(1);
if (!isEmpty(spid)) {
diff --git a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/db/H2.java b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/db/H2.java
index fd0136e3..af48f2f0 100644
--- a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/db/H2.java
+++ b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/db/H2.java
@@ -21,7 +21,7 @@
import java.io.File;
import java.net.InetAddress;
-import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/http/HttpCall.java b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/http/HttpCall.java
index 3f6241a4..704a7a19 100644
--- a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/http/HttpCall.java
+++ b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/http/HttpCall.java
@@ -37,7 +37,7 @@
import okhttp3.Request;
import okhttp3.Response;
import org.apache.commons.io.FileUtils;
-import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang3.StringUtils;
import static com.sonar.orchestrator.container.Server.ADMIN_LOGIN;
import static com.sonar.orchestrator.container.Server.ADMIN_PASSWORD;
diff --git a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/config/Licenses.java b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/licenses/Licenses.java
similarity index 96%
rename from sonar-orchestrator/src/main/java/com/sonar/orchestrator/config/Licenses.java
rename to sonar-orchestrator/src/main/java/com/sonar/orchestrator/licenses/Licenses.java
index 6da67c26..61576128 100644
--- a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/config/Licenses.java
+++ b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/licenses/Licenses.java
@@ -17,8 +17,9 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-package com.sonar.orchestrator.config;
+package com.sonar.orchestrator.licenses;
+import com.sonar.orchestrator.config.Configuration;
import com.sonar.orchestrator.container.Edition;
import com.sonar.orchestrator.http.HttpClientFactory;
import com.sonar.orchestrator.http.HttpResponse;
@@ -26,7 +27,7 @@
import java.util.EnumMap;
import java.util.Map;
import okhttp3.HttpUrl;
-import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang3.StringUtils;
import static com.sonar.orchestrator.util.OrchestratorUtils.defaultIfNull;
import static java.lang.String.format;
diff --git a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/licenses/package-info.java b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/licenses/package-info.java
new file mode 100644
index 00000000..4d093e69
--- /dev/null
+++ b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/licenses/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * Orchestrator
+ * Copyright (C) 2011-2025 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.
+ */
+@ParametersAreNonnullByDefault
+package com.sonar.orchestrator.licenses;
+
+import javax.annotation.ParametersAreNonnullByDefault;
+
diff --git a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/locator/Artifactory.java b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/locator/Artifactory.java
index abb6dd80..f9a8e7c3 100644
--- a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/locator/Artifactory.java
+++ b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/locator/Artifactory.java
@@ -32,7 +32,7 @@
import javax.annotation.Nullable;
import okhttp3.HttpUrl;
import org.apache.commons.io.FileUtils;
-import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/locator/ArtifactoryFactory.java b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/locator/ArtifactoryFactory.java
index 4a7eba24..69d83bec 100644
--- a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/locator/ArtifactoryFactory.java
+++ b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/locator/ArtifactoryFactory.java
@@ -38,7 +38,7 @@ public class ArtifactoryFactory {
*
*/
public static Artifactory createArtifactory(Configuration configuration) {
- File downloadTempDir = new File(configuration.fileSystem().workspace(), "temp-downloads");
+ File downloadTempDir = new File(configuration.fileSystem().workspace().toFile(), "temp-downloads");
String baseUrl = defaultIfEmpty(configuration.getStringByKeys("orchestrator.artifactory.url", "ARTIFACTORY_URL"), DEFAULT_ARTIFACTORY_URL);
if (baseUrl.startsWith(DEFAULT_ARTIFACTORY_PREFIX)) {
diff --git a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/locator/DefaultArtifactory.java b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/locator/DefaultArtifactory.java
index f9b0bdd5..3c249a7d 100644
--- a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/locator/DefaultArtifactory.java
+++ b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/locator/DefaultArtifactory.java
@@ -42,7 +42,7 @@ protected DefaultArtifactory(File tempDir, String baseUrl, @Nullable String acce
}
protected static DefaultArtifactory create(Configuration configuration) {
- File downloadTempDir = new File(configuration.fileSystem().workspace(), "temp-downloads");
+ File downloadTempDir = new File(configuration.fileSystem().workspace().toFile(), "temp-downloads");
String baseUrl = defaultIfEmpty(configuration.getStringByKeys("orchestrator.artifactory.url", "ARTIFACTORY_URL"), "https://repox.jfrog.io/repox");
String apiKey = configuration.getStringByKeys("orchestrator.artifactory.apiKey", "ARTIFACTORY_API_KEY");
String accessToken = configuration.getStringByKeys("orchestrator.artifactory.accessToken", "ARTIFACTORY_ACCESS_TOKEN");
diff --git a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/locator/Locators.java b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/locator/Locators.java
index 94a6c2ed..236ae4e7 100644
--- a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/locator/Locators.java
+++ b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/locator/Locators.java
@@ -19,6 +19,7 @@
*/
package com.sonar.orchestrator.locator;
+import com.sonar.orchestrator.config.Configuration;
import com.sonar.orchestrator.config.FileSystem;
import java.io.File;
import java.io.InputStream;
@@ -30,7 +31,11 @@ public class Locators {
private final ResourceLocator resourceLocator;
private final URLLocator urlLocator;
- public Locators(FileSystem fileSystem, Artifactory artifactory) {
+ public Locators(Configuration configuration) {
+ this(configuration.fileSystem(), ArtifactoryFactory.createArtifactory(configuration));
+ }
+
+ Locators(FileSystem fileSystem, Artifactory artifactory) {
fileLocator = new FileLocator();
mavenLocator = new MavenLocator(fileSystem, artifactory);
resourceLocator = new ResourceLocator();
diff --git a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/locator/MavenLocation.java b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/locator/MavenLocation.java
index ef93bebe..544f1204 100644
--- a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/locator/MavenLocation.java
+++ b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/locator/MavenLocation.java
@@ -19,8 +19,8 @@
*/
package com.sonar.orchestrator.locator;
-import org.apache.commons.lang.ObjectUtils;
-import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang3.ObjectUtils;
+import org.apache.commons.lang3.StringUtils;
import static com.sonar.orchestrator.util.OrchestratorUtils.checkArgument;
import static com.sonar.orchestrator.util.OrchestratorUtils.isEmpty;
@@ -50,6 +50,25 @@ public MavenLocation(Builder builder) {
}
}
+ public static MavenLocation create(String groupId, String artifactId, String version) {
+ return builder().setGroupId(groupId).setArtifactId(artifactId).setVersion(version).build();
+ }
+
+ public static MavenLocation create(String groupId, String artifactId, String version, String classifier) {
+ return builder().setGroupId(groupId).setArtifactId(artifactId).setVersion(version).setClassifier(classifier).build();
+ }
+
+ /**
+ * @since 2.10.1. Shortcut for {@link #create(String, String, String)}
+ */
+ public static MavenLocation of(String groupId, String artifactId, String version) {
+ return create(groupId, artifactId, version);
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
public String getGroupId() {
return groupId;
}
@@ -104,26 +123,6 @@ public String toString() {
}
}
- public static MavenLocation create(String groupId, String artifactId, String version) {
- return builder().setGroupId(groupId).setArtifactId(artifactId).setVersion(version).build();
- }
-
- public static MavenLocation create(String groupId, String artifactId, String version, String classifier) {
- return builder().setGroupId(groupId).setArtifactId(artifactId).setVersion(version).setClassifier(classifier).build();
- }
-
-
- /**
- * @since 2.10.1. Shortcut for {@link #create(String, String, String)}
- */
- public static MavenLocation of(String groupId, String artifactId, String version) {
- return create(groupId, artifactId, version);
- }
-
- public static Builder builder() {
- return new Builder();
- }
-
public static class Builder> {
private String groupId;
private String artifactId;
diff --git a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/locator/MavenLocator.java b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/locator/MavenLocator.java
index 39482c82..724afa50 100644
--- a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/locator/MavenLocator.java
+++ b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/locator/MavenLocator.java
@@ -23,13 +23,15 @@
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
import java.util.Collection;
import java.util.Optional;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.io.FileUtils;
-import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang3.Strings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -44,6 +46,14 @@ public MavenLocator(FileSystem fileSystem, Artifactory artifactory) {
this.artifactory = artifactory;
}
+ private static String pathInMavenLocalRepository(MavenLocation location) {
+ return Strings.CS.replace(location.getGroupId(), ".", "/") + "/" + location.getArtifactId() + "/" + location.getVersion() + "/" + location.getFilename();
+ }
+
+ static String cacheKeyOf(MavenLocation location) {
+ return DigestUtils.md5Hex(location.toString());
+ }
+
@Override
public File locate(MavenLocation location) {
// resolve the version alias if needed (requires to be online)
@@ -55,9 +65,9 @@ public File locate(MavenLocation location) {
File locateResolvedVersion(MavenLocation resolvedLocation) {
// check local cache
String cacheKey = cacheKeyOf(resolvedLocation);
- File cachedDir = new File(fileSystem.getCacheDir(), cacheKey);
- if (cachedDir.exists()) {
- Collection files = FileUtils.listFiles(cachedDir, null, false);
+ Path cachedDir = fileSystem.getCacheDir().resolve(cacheKey);
+ if (Files.exists(cachedDir)) {
+ Collection files = FileUtils.listFiles(cachedDir.toFile(), null, false);
if (files.size() == 1) {
File file = files.iterator().next();
LOG.info("Found {} at {}", resolvedLocation, file);
@@ -77,9 +87,9 @@ File locateResolvedVersion(MavenLocation resolvedLocation) {
if (resolvedLocation.getVersion().endsWith("-SNAPSHOT")) {
return null;
}
- File cachedFile = new File(cachedDir, resolvedLocation.getFilename());
- boolean found = artifactory.downloadToFile(resolvedLocation, cachedFile);
- return found ? cachedFile : null;
+ Path cachedFile = cachedDir.resolve(resolvedLocation.getFilename());
+ boolean found = artifactory.downloadToFile(resolvedLocation, cachedFile.toFile());
+ return found ? cachedFile.toFile() : null;
}
private MavenLocation resolveLocation(MavenLocation location) {
@@ -105,10 +115,10 @@ public Optional resolveVersion(MavenLocation location) {
@CheckForNull
private File locateInLocalRepository(MavenLocation location) {
- if (fileSystem.mavenLocalRepository() != null && fileSystem.mavenLocalRepository().exists()) {
- File file = new File(fileSystem.mavenLocalRepository(), pathInMavenLocalRepository(location));
- if (file.exists()) {
- return file;
+ if (fileSystem.mavenLocalRepository() != null && Files.exists(fileSystem.mavenLocalRepository())) {
+ Path file = fileSystem.mavenLocalRepository().resolve(pathInMavenLocalRepository(location));
+ if (Files.exists(file)) {
+ return file.toFile();
}
}
return null;
@@ -158,12 +168,4 @@ public InputStream openInputStream(MavenLocation location) {
throw new IllegalStateException("Fail to open " + target, e);
}
}
-
- private static String pathInMavenLocalRepository(MavenLocation location) {
- return StringUtils.replace(location.getGroupId(), ".", "/") + "/" + location.getArtifactId() + "/" + location.getVersion() + "/" + location.getFilename();
- }
-
- static String cacheKeyOf(MavenLocation location) {
- return DigestUtils.md5Hex(location.toString());
- }
}
diff --git a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/locator/ResourceLocation.java b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/locator/ResourceLocation.java
index 44c1cfcb..feeea8e1 100644
--- a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/locator/ResourceLocation.java
+++ b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/locator/ResourceLocation.java
@@ -20,7 +20,7 @@
package com.sonar.orchestrator.locator;
import java.net.URL;
-import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang3.StringUtils;
import static com.sonar.orchestrator.util.OrchestratorUtils.checkArgument;
import static java.util.Objects.requireNonNull;
diff --git a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/locator/URLLocation.java b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/locator/URLLocation.java
index 48ce83af..16d51949 100644
--- a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/locator/URLLocation.java
+++ b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/locator/URLLocation.java
@@ -22,7 +22,7 @@
import java.net.URISyntaxException;
import java.net.URL;
import javax.annotation.Nullable;
-import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang3.StringUtils;
import static java.util.Objects.requireNonNull;
diff --git a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/locator/URLLocator.java b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/locator/URLLocator.java
index 1eae5490..51fe9f6d 100644
--- a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/locator/URLLocator.java
+++ b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/locator/URLLocator.java
@@ -29,7 +29,7 @@
import javax.annotation.Nullable;
import okhttp3.HttpUrl;
import org.apache.commons.io.FileUtils;
-import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/server/ServerCommandLineFactory.java b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/server/ServerCommandLineFactory.java
index 1e81ca55..c082d979 100644
--- a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/server/ServerCommandLineFactory.java
+++ b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/server/ServerCommandLineFactory.java
@@ -22,6 +22,8 @@
import com.sonar.orchestrator.config.FileSystem;
import com.sonar.orchestrator.container.Server;
import java.io.File;
+import java.nio.file.Files;
+import java.nio.file.Path;
import java.util.Collection;
import org.apache.commons.exec.CommandLine;
import org.apache.commons.io.FileUtils;
@@ -56,11 +58,11 @@ public CommandLine create(Server server) {
private CommandLine createJavaCommandLine() {
CommandLine command;
- File javaHome = fs.javaHome();
- if (javaHome == null || !javaHome.exists()) {
+ Path javaHome = fs.javaHome();
+ if (javaHome == null || !Files.exists(javaHome)) {
command = new CommandLine("java");
} else {
- command = new CommandLine(FileUtils.getFile(javaHome, "bin", "java"));
+ command = new CommandLine(javaHome.resolve("bin/java").toFile());
}
return command;
}
diff --git a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/server/ServerInstaller.java b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/server/ServerInstaller.java
index 0d5ac9f5..042bb3f0 100644
--- a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/server/ServerInstaller.java
+++ b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/server/ServerInstaller.java
@@ -44,7 +44,7 @@
import okhttp3.HttpUrl;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.filefilter.FileFilterUtils;
-import org.apache.commons.lang.SystemUtils;
+import org.apache.commons.lang3.SystemUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -115,7 +115,7 @@ private void preparePlugins(SonarDistribution distrib, File homeDir) {
}
private File unzip(Packaging packaging) {
- File toDir = new File(configuration.fileSystem().workspace(), valueOf(sharedDirId.addAndGet(1)));
+ File toDir = new File(configuration.fileSystem().workspace().toFile(), valueOf(sharedDirId.addAndGet(1)));
try {
FileUtils.deleteDirectory(toDir);
} catch (IOException e) {
diff --git a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/util/Command.java b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/util/Command.java
index 565aeb58..53157520 100644
--- a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/util/Command.java
+++ b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/util/Command.java
@@ -27,7 +27,7 @@
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
-import org.apache.commons.lang.SystemUtils;
+import org.apache.commons.lang3.SystemUtils;
import static com.sonar.orchestrator.util.OrchestratorUtils.checkArgument;
import static com.sonar.orchestrator.util.OrchestratorUtils.isEmpty;
diff --git a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/util/MavenVersionResolver.java b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/util/MavenVersionResolver.java
index bb346234..2e58c935 100644
--- a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/util/MavenVersionResolver.java
+++ b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/util/MavenVersionResolver.java
@@ -30,7 +30,7 @@
import java.util.stream.Collectors;
import javax.annotation.Nullable;
import okhttp3.HttpUrl;
-import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import static com.sonar.orchestrator.util.OrchestratorUtils.isEmpty;
diff --git a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/util/SharedDir.java b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/util/SharedDir.java
new file mode 100644
index 00000000..d78dea6e
--- /dev/null
+++ b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/util/SharedDir.java
@@ -0,0 +1,66 @@
+/*
+ * Orchestrator
+ * Copyright (C) 2011-2025 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 com.sonar.orchestrator.util;
+
+import com.sonar.orchestrator.config.Configuration;
+import com.sonar.orchestrator.locator.FileLocation;
+import java.io.File;
+
+import static com.sonar.orchestrator.util.OrchestratorUtils.checkState;
+import static java.lang.String.format;
+import static java.util.Objects.requireNonNull;
+
+public class SharedDir {
+ private static final String ENV_SHARED_DIR = "SONAR_IT_SOURCES";
+ private static final String PROP_SHARED_DIR = "orchestrator.it_sources";
+
+ private final Configuration configuration;
+
+ public SharedDir(Configuration configuration) {
+ this.configuration = configuration;
+ }
+
+ /**
+ * File located in the shared directory defined by the system property orchestrator.it_sources or environment variable SONAR_IT_SOURCES.
+ * Example : getFileLocationOfShared("javascript/performancing/pom.xml")
+ */
+ public FileLocation getFileLocationOfShared(String relativePath) {
+ // try to read it_sources
+ // in the System.getProperties
+ // in the prop file (from orchestrator.properties file)
+ // in the environment variable
+ String rootPath;
+ rootPath = System.getProperty(PROP_SHARED_DIR);
+ if (rootPath == null) {
+ rootPath = configuration.getString(PROP_SHARED_DIR);
+ }
+ if (rootPath == null) {
+ rootPath = System.getenv(ENV_SHARED_DIR);
+ }
+ requireNonNull(rootPath, format("Property '%s' or environment variable '%s' is missing", PROP_SHARED_DIR, ENV_SHARED_DIR));
+
+ File rootDir = new File(rootPath);
+ checkState(rootDir.isDirectory() && rootDir.exists(),
+ "Please check the definition of it_sources (%s or %s) because the directory does not exist: %s", PROP_SHARED_DIR, ENV_SHARED_DIR, rootDir);
+
+ return FileLocation.of(new File(rootDir, relativePath));
+ }
+
+}
diff --git a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/util/ZipUtils.java b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/util/ZipUtils.java
index 33323bbc..17df3cbf 100644
--- a/sonar-orchestrator/src/main/java/com/sonar/orchestrator/util/ZipUtils.java
+++ b/sonar-orchestrator/src/main/java/com/sonar/orchestrator/util/ZipUtils.java
@@ -29,7 +29,7 @@
import java.util.zip.ZipFile;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang.SystemUtils;
+import org.apache.commons.lang3.SystemUtils;
public final class ZipUtils {
private ZipUtils() {
diff --git a/sonar-orchestrator/src/test/java/com/sonar/orchestrator/build/AbstractBuildExecutorTest.java b/sonar-orchestrator/src/test/java/com/sonar/orchestrator/build/AbstractBuildExecutorTest.java
index 1d2f16e4..145ea14b 100644
--- a/sonar-orchestrator/src/test/java/com/sonar/orchestrator/build/AbstractBuildExecutorTest.java
+++ b/sonar-orchestrator/src/test/java/com/sonar/orchestrator/build/AbstractBuildExecutorTest.java
@@ -21,6 +21,7 @@
import com.google.common.collect.ImmutableMap;
import com.sonar.orchestrator.config.Configuration;
+import com.sonar.orchestrator.locator.Locators;
import com.sonar.orchestrator.test.MockHttpServerInterceptor;
import java.util.HashMap;
import java.util.Map;
@@ -41,7 +42,9 @@ public void shouldNotAppendCoverageArgumentToOptsByDefault() {
Configuration config = Configuration.create(new HashMap());
- AbstractBuildExecutor.appendCoverageArgumentToOpts(env, config, "SONAR_OPTS");
+ AbstractBuildExecutor.appendCoverageArgumentToOpts(env, config, null, "SONAR_OPTS");
+
+ assertThat(env).isEmpty();
}
@Test
@@ -53,8 +56,9 @@ public void shouldAppendCoverageArgumentToOpts() {
.addProperties(singletonMap("orchestrator.computeCoverage", "true"))
.addEnvVariables()
.build();
+ Locators locators = new Locators(config);
- AbstractBuildExecutor.appendCoverageArgumentToOpts(env, config, "SONAR_OPTS");
+ AbstractBuildExecutor.appendCoverageArgumentToOpts(env, config, locators, "SONAR_OPTS");
assertThat(env.get("SONAR_OPTS")).startsWith("foo -javaagent:");
}
@@ -67,8 +71,9 @@ public void shouldCreateEnvironmentVariableIfNeeded() {
.addProperties(singletonMap("orchestrator.computeCoverage", "true"))
.addEnvVariables()
.build();
+ Locators locators = new Locators(config);
- AbstractBuildExecutor.appendCoverageArgumentToOpts(env, config, "SONAR_OPTS");
+ AbstractBuildExecutor.appendCoverageArgumentToOpts(env, config, locators, "SONAR_OPTS");
assertThat(env.get("SONAR_OPTS")).startsWith("-javaagent:");
}
diff --git a/sonar-orchestrator/src/test/java/com/sonar/orchestrator/build/AntBuildExecutorTest.java b/sonar-orchestrator/src/test/java/com/sonar/orchestrator/build/AntBuildExecutorTest.java
index 1c59be37..9c794666 100644
--- a/sonar-orchestrator/src/test/java/com/sonar/orchestrator/build/AntBuildExecutorTest.java
+++ b/sonar-orchestrator/src/test/java/com/sonar/orchestrator/build/AntBuildExecutorTest.java
@@ -21,6 +21,7 @@
import com.sonar.orchestrator.config.Configuration;
import com.sonar.orchestrator.locator.FileLocation;
+import com.sonar.orchestrator.locator.Locators;
import com.sonar.orchestrator.util.Command;
import com.sonar.orchestrator.util.CommandExecutor;
import com.sonar.orchestrator.util.StreamConsumer;
@@ -51,7 +52,8 @@ public void execute_command() {
CommandExecutor executor = mock(CommandExecutor.class);
when(executor.execute(any(Command.class), any(StreamConsumer.class), anyLong())).thenReturn(2);
- new AntBuildExecutor().execute(build, Configuration.create(), props, executor);
+ Configuration config = Configuration.create();
+ new AntBuildExecutor().execute(build, config, new Locators(config), props, executor);
verify(executor).execute(argThat(c -> c.toCommandLine().contains("ant") &&
c.toCommandLine().contains("-f") &&
diff --git a/sonar-orchestrator/src/test/java/com/sonar/orchestrator/build/BuildRunnerTest.java b/sonar-orchestrator/src/test/java/com/sonar/orchestrator/build/BuildRunnerTest.java
index 435176a9..56f68634 100644
--- a/sonar-orchestrator/src/test/java/com/sonar/orchestrator/build/BuildRunnerTest.java
+++ b/sonar-orchestrator/src/test/java/com/sonar/orchestrator/build/BuildRunnerTest.java
@@ -35,6 +35,7 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyMap;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -53,12 +54,12 @@ public void inject_server_properties() {
Build build = mock(Build.class);
when(build.getProperties()).thenReturn(ImmutableMap.of("sonar.projectKey", "SAMPLE", "language", "java"));
- BuildRunner runner = new BuildRunner(config);
+ BuildRunner runner = new BuildRunner(config, null);
runner.runQuietly(server, build);
ArgumentCaptor