diff --git a/sonar-apple-plugin/src/main/java/fr/insideapp/sonarqube/apple/XcodeResultExtensionProvider.java b/sonar-apple-plugin/src/main/java/fr/insideapp/sonarqube/apple/XcodeResultExtensionProvider.java index a0a10714..f3659ab5 100644 --- a/sonar-apple-plugin/src/main/java/fr/insideapp/sonarqube/apple/XcodeResultExtensionProvider.java +++ b/sonar-apple-plugin/src/main/java/fr/insideapp/sonarqube/apple/XcodeResultExtensionProvider.java @@ -18,6 +18,7 @@ package fr.insideapp.sonarqube.apple; import fr.insideapp.sonarqube.apple.commons.ExtensionProvider; +import fr.insideapp.sonarqube.apple.xcode.legacy.XcodeResultLegacyRunner; import fr.insideapp.sonarqube.apple.xcode.runner.XcodeResultReadObjectRunner; import fr.insideapp.sonarqube.apple.xcode.parser.XcodeActionRecordParser; import fr.insideapp.sonarqube.apple.xcode.runner.XcodeResultReadRunner; @@ -50,7 +51,8 @@ public List extensions() { RESULT_BUNDLE_PROPERTY, XcodeResultReadRunner.class, XcodeActionRecordParser.class, - XcodeResultReadObjectRunner.class + XcodeResultReadObjectRunner.class, + XcodeResultLegacyRunner.class ); } diff --git a/sonar-apple-plugin/src/main/java/fr/insideapp/sonarqube/apple/xcode/legacy/XcodeResultLegacyRunnable.java b/sonar-apple-plugin/src/main/java/fr/insideapp/sonarqube/apple/xcode/legacy/XcodeResultLegacyRunnable.java new file mode 100644 index 00000000..a4470703 --- /dev/null +++ b/sonar-apple-plugin/src/main/java/fr/insideapp/sonarqube/apple/xcode/legacy/XcodeResultLegacyRunnable.java @@ -0,0 +1,31 @@ +/* + * SonarQube Apple Plugin - Enables analysis of Swift and Objective-C projects into SonarQube. + * Copyright © 2022 inside|app (contact@insideapp.fr) + * + * 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, see . + */ +package fr.insideapp.sonarqube.apple.xcode.legacy; + +import fr.insideapp.sonarqube.apple.commons.cli.SingleCommandLineToolRunner; +import org.sonar.api.scanner.ScannerSide; + +@ScannerSide +public abstract class XcodeResultLegacyRunnable extends SingleCommandLineToolRunner { + protected XcodeResultLegacyRunnable(String command) { + super(command); + } + + public abstract boolean check(); + +} \ No newline at end of file diff --git a/sonar-apple-plugin/src/main/java/fr/insideapp/sonarqube/apple/xcode/legacy/XcodeResultLegacyRunner.java b/sonar-apple-plugin/src/main/java/fr/insideapp/sonarqube/apple/xcode/legacy/XcodeResultLegacyRunner.java new file mode 100644 index 00000000..6d89f272 --- /dev/null +++ b/sonar-apple-plugin/src/main/java/fr/insideapp/sonarqube/apple/xcode/legacy/XcodeResultLegacyRunner.java @@ -0,0 +1,57 @@ +/* + * SonarQube Apple Plugin - Enables analysis of Swift and Objective-C projects into SonarQube. + * Copyright © 2022 inside|app (contact@insideapp.fr) + * + * 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, see . + */ +package fr.insideapp.sonarqube.apple.xcode.legacy; + +import org.sonar.api.scanner.ScannerSide; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +@ScannerSide +public final class XcodeResultLegacyRunner extends XcodeResultLegacyRunnable { + + private static final Integer MIN_VERSION = 23_021; + + private static final Pattern PATTERN = Pattern.compile("xcresulttool version (?\\d+),.*"); + + public XcodeResultLegacyRunner() { + super("xcrun"); + } + + protected String[] arguments() { + return new String[]{ + "xcresulttool", "version" + }; + } + + public boolean check() { + String result = run(arguments()).trim(); + Matcher versionMatcher = PATTERN.matcher(result); + if (versionMatcher.find()) { + try { + int version = Integer.parseInt(versionMatcher.group("version")); + return version >= MIN_VERSION; + } catch (NumberFormatException e) { + return false; + } + } else { + return false; + } + } + +} \ No newline at end of file diff --git a/sonar-apple-plugin/src/main/java/fr/insideapp/sonarqube/apple/xcode/runner/XcodeResultReadObjectRunner.java b/sonar-apple-plugin/src/main/java/fr/insideapp/sonarqube/apple/xcode/runner/XcodeResultReadObjectRunner.java index ec074dc6..316d3ad3 100644 --- a/sonar-apple-plugin/src/main/java/fr/insideapp/sonarqube/apple/xcode/runner/XcodeResultReadObjectRunner.java +++ b/sonar-apple-plugin/src/main/java/fr/insideapp/sonarqube/apple/xcode/runner/XcodeResultReadObjectRunner.java @@ -18,24 +18,39 @@ package fr.insideapp.sonarqube.apple.xcode.runner; import fr.insideapp.sonarqube.apple.commons.result.models.Reference; +import fr.insideapp.sonarqube.apple.xcode.legacy.XcodeResultLegacyRunnable; import org.sonar.api.scanner.ScannerSide; import java.io.File; +import java.util.ArrayList; +import java.util.List; @ScannerSide public final class XcodeResultReadObjectRunner extends XcodeResultReadObjectRunnable { - public XcodeResultReadObjectRunner() { + private final XcodeResultLegacyRunnable legacyRunner; + + public XcodeResultReadObjectRunner( + final XcodeResultLegacyRunnable legacyRunner + ) { super("xcrun"); + this.legacyRunner = legacyRunner; } protected String[] arguments(File resultBundle, Reference reference) { - return new String[]{ - "xcresulttool", "get", - "--format", "json", - "--path", resultBundle.getAbsolutePath(), - "--id", reference.id - }; + List arguments = new ArrayList<>(); + arguments.add("xcresulttool"); + arguments.add("get"); + arguments.add("--format"); + arguments.add("json"); + arguments.add("--path"); + arguments.add(resultBundle.getAbsolutePath()); + arguments.add("--id"); + arguments.add(reference.id); + if (legacyRunner.check()) { + arguments.add("--legacy"); + } + return arguments.toArray(String[]::new); } public String run(File resultBundle, Reference reference) { diff --git a/sonar-apple-plugin/src/main/java/fr/insideapp/sonarqube/apple/xcode/runner/XcodeResultReadRunner.java b/sonar-apple-plugin/src/main/java/fr/insideapp/sonarqube/apple/xcode/runner/XcodeResultReadRunner.java index 78edb607..233a9800 100644 --- a/sonar-apple-plugin/src/main/java/fr/insideapp/sonarqube/apple/xcode/runner/XcodeResultReadRunner.java +++ b/sonar-apple-plugin/src/main/java/fr/insideapp/sonarqube/apple/xcode/runner/XcodeResultReadRunner.java @@ -17,23 +17,36 @@ */ package fr.insideapp.sonarqube.apple.xcode.runner; +import fr.insideapp.sonarqube.apple.xcode.legacy.XcodeResultLegacyRunnable; import org.sonar.api.scanner.ScannerSide; import java.io.File; +import java.util.ArrayList; +import java.util.List; @ScannerSide public final class XcodeResultReadRunner extends XcodeResultReadRunnable { - public XcodeResultReadRunner() { + private final XcodeResultLegacyRunnable legacyRunner; + + public XcodeResultReadRunner( + final XcodeResultLegacyRunnable legacyRunner + ) { super("xcrun"); + this.legacyRunner = legacyRunner; } - protected String[] arguments(File resultBundle) { - return new String[]{ - "xcresulttool", "get", - "--format", "json", - "--path", resultBundle.getAbsolutePath() - }; + List arguments = new ArrayList<>(); + arguments.add("xcresulttool"); + arguments.add("get"); + arguments.add("--format"); + arguments.add("json"); + arguments.add("--path"); + arguments.add(resultBundle.getAbsolutePath()); + if (legacyRunner.check()) { + arguments.add("--legacy"); + } + return arguments.toArray(String[]::new); } public String run(File resultBundle) { diff --git a/sonar-apple-plugin/src/test/java/fr/insideapp/sonarqube/apple/ApplePluginTest.java b/sonar-apple-plugin/src/test/java/fr/insideapp/sonarqube/apple/ApplePluginTest.java index c15bc045..de3061b0 100644 --- a/sonar-apple-plugin/src/test/java/fr/insideapp/sonarqube/apple/ApplePluginTest.java +++ b/sonar-apple-plugin/src/test/java/fr/insideapp/sonarqube/apple/ApplePluginTest.java @@ -40,6 +40,6 @@ public void define() { plugin.define(context); List extensions = context.getExtensions(); - assertThat(extensions).hasSize(79); + assertThat(extensions).hasSize(80); } } diff --git a/sonar-apple-plugin/src/test/java/fr/insideapp/sonarqube/apple/XcodeResultExtensionProviderTest.java b/sonar-apple-plugin/src/test/java/fr/insideapp/sonarqube/apple/XcodeResultExtensionProviderTest.java index e7a5947f..7cafbc84 100644 --- a/sonar-apple-plugin/src/test/java/fr/insideapp/sonarqube/apple/XcodeResultExtensionProviderTest.java +++ b/sonar-apple-plugin/src/test/java/fr/insideapp/sonarqube/apple/XcodeResultExtensionProviderTest.java @@ -44,7 +44,7 @@ public void prepare() { @Test public void extensions() { - assertThat(provider.extensions()).hasSize(4); + assertThat(provider.extensions()).hasSize(5); } @Test diff --git a/sonar-apple-plugin/src/test/java/fr/insideapp/sonarqube/apple/xcode/legacy/XcodeResultLegacyRunnerTest.java b/sonar-apple-plugin/src/test/java/fr/insideapp/sonarqube/apple/xcode/legacy/XcodeResultLegacyRunnerTest.java new file mode 100644 index 00000000..dc9ba5b3 --- /dev/null +++ b/sonar-apple-plugin/src/test/java/fr/insideapp/sonarqube/apple/xcode/legacy/XcodeResultLegacyRunnerTest.java @@ -0,0 +1,43 @@ +/* + * SonarQube Apple Plugin - Enables analysis of Swift and Objective-C projects into SonarQube. + * Copyright © 2022 inside|app (contact@insideapp.fr) + * + * 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, see . + */ +package fr.insideapp.sonarqube.apple.xcode.legacy; + +import org.junit.Before; +import org.junit.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +public final class XcodeResultLegacyRunnerTest { + + private XcodeResultLegacyRunner runner; + + @Before + public void prepare() { + runner = new XcodeResultLegacyRunner(); + } + + @Test + public void arguments() { + String[] options = runner.arguments(); + assertThat(options).isEqualTo(new String[]{ + "xcresulttool", + "version", + }); + } + +} diff --git a/sonar-apple-plugin/src/test/java/fr/insideapp/sonarqube/apple/xcode/runner/XcodeResultReadObjectRunnerTest.java b/sonar-apple-plugin/src/test/java/fr/insideapp/sonarqube/apple/xcode/runner/XcodeResultReadObjectRunnerTest.java index 1cda816f..51eb4fa3 100644 --- a/sonar-apple-plugin/src/test/java/fr/insideapp/sonarqube/apple/xcode/runner/XcodeResultReadObjectRunnerTest.java +++ b/sonar-apple-plugin/src/test/java/fr/insideapp/sonarqube/apple/xcode/runner/XcodeResultReadObjectRunnerTest.java @@ -18,27 +18,36 @@ package fr.insideapp.sonarqube.apple.xcode.runner; import fr.insideapp.sonarqube.apple.commons.result.models.Reference; +import fr.insideapp.sonarqube.apple.xcode.legacy.XcodeResultLegacyRunnable; import org.junit.Before; import org.junit.Test; import java.io.File; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; public final class XcodeResultReadObjectRunnerTest { private static final String BASE_DIR = "/xcode"; + private XcodeResultLegacyRunnable legacy; private XcodeResultReadObjectRunner runner; @Before public void prepare() { - runner = new XcodeResultReadObjectRunner(); + legacy = mock(XcodeResultLegacyRunnable.class); + runner = new XcodeResultReadObjectRunner(legacy); } @Test - public void arguments() { + public void arguments_no_legacy() { + // When + when(legacy.check()).thenReturn(false); + // Then String[] options = runner.arguments(new File(BASE_DIR), new Reference("test")); + // Assert assertThat(options).isEqualTo(new String[]{ "xcresulttool", "get", @@ -48,4 +57,21 @@ public void arguments() { }); } + @Test + public void arguments_legacy() { + // When + when(legacy.check()).thenReturn(true); + // Then + String[] options = runner.arguments(new File(BASE_DIR), new Reference("test")); + // Assert + assertThat(options).isEqualTo(new String[]{ + "xcresulttool", + "get", + "--format", "json", + "--path", "/xcode", + "--id", "test", + "--legacy" + }); + } + } diff --git a/sonar-apple-plugin/src/test/java/fr/insideapp/sonarqube/apple/xcode/runner/XcodeResultReadRunnerTest.java b/sonar-apple-plugin/src/test/java/fr/insideapp/sonarqube/apple/xcode/runner/XcodeResultReadRunnerTest.java index 70226002..f8e2c4dd 100644 --- a/sonar-apple-plugin/src/test/java/fr/insideapp/sonarqube/apple/xcode/runner/XcodeResultReadRunnerTest.java +++ b/sonar-apple-plugin/src/test/java/fr/insideapp/sonarqube/apple/xcode/runner/XcodeResultReadRunnerTest.java @@ -17,32 +17,57 @@ */ package fr.insideapp.sonarqube.apple.xcode.runner; +import fr.insideapp.sonarqube.apple.xcode.legacy.XcodeResultLegacyRunnable; import org.junit.Before; import org.junit.Test; import java.io.File; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; public final class XcodeResultReadRunnerTest { private static final String BASE_DIR = "/xcode"; + private XcodeResultLegacyRunnable legacy; private XcodeResultReadRunner runner; @Before public void prepare() { - runner = new XcodeResultReadRunner(); + legacy = mock(XcodeResultLegacyRunnable.class); + runner = new XcodeResultReadRunner(legacy); } @Test - public void arguments() { + public void arguments_no_legacy() { + // When + when(legacy.check()).thenReturn(false); + // Then String[] options = runner.arguments(new File(BASE_DIR)); + // Assert assertThat(options).isEqualTo(new String[]{ "xcresulttool", "get", "--format", "json", - "--path", "/xcode" + "--path", "/xcode", + }); + } + + @Test + public void arguments_legacy() { + // When + when(legacy.check()).thenReturn(true); + // Then + String[] options = runner.arguments(new File(BASE_DIR)); + // Assert + assertThat(options).isEqualTo(new String[]{ + "xcresulttool", + "get", + "--format", "json", + "--path", "/xcode", + "--legacy" }); }