Support argfiles in kotlin compiler

Using '-Xargfile=path/to/argfile' will substitute
that argument with the content of argfile.

See KT-24472
This commit is contained in:
Dmitry Savvinov
2018-05-17 21:36:59 +03:00
parent ede2e227c2
commit 43467516ef
18 changed files with 210 additions and 29 deletions
@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.cli;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.io.FileUtilKt;
import com.intellij.openapi.util.text.StringUtil;
import kotlin.Pair;
import kotlin.collections.CollectionsKt;
@@ -30,6 +31,7 @@ import org.jetbrains.kotlin.cli.js.K2JSCompiler;
import org.jetbrains.kotlin.cli.js.dce.K2JSDce;
import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler;
import org.jetbrains.kotlin.cli.metadata.K2MetadataCompiler;
import org.jetbrains.kotlin.codegen.TestUtilsKt;
import org.jetbrains.kotlin.config.KotlinCompilerVersion;
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmMetadataVersion;
import org.jetbrains.kotlin.test.CompilerTestUtil;
@@ -42,8 +44,10 @@ import org.jetbrains.kotlin.utils.StringsKt;
import org.junit.Assert;
import java.io.File;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public abstract class AbstractCliTest extends TestCaseWithTmpdir {
private static final String TESTDATA_DIR = "$TESTDATA_DIR$";
@@ -180,28 +184,61 @@ public abstract class AbstractCliTest extends TestCaseWithTmpdir {
}
@NotNull
private static List<String> readArgs(@NotNull String argsFilePath, @NotNull String tempDir) {
List<String> lines = FilesKt.readLines(new File(argsFilePath), Charsets.UTF_8);
private static List<String> readArgs(@NotNull String testArgsFilePath, @NotNull String tempDir) {
File testArgsFile = new File(testArgsFilePath);
List<String> lines = FilesKt.readLines(testArgsFile, Charsets.UTF_8);
return CollectionsKt.mapNotNull(lines, arg -> readArg(arg, testArgsFile.getParent(), tempDir));
}
return CollectionsKt.mapNotNull(lines, arg -> {
if (arg.isEmpty()) {
return null;
}
private static String readArg(String arg, @NotNull String testDataDir, @NotNull String tempDir) {
if (arg.isEmpty()) {
return null;
}
// Do not replace ':' after '\' (used in compiler plugin tests)
String argsWithColonsReplaced = arg
.replace("\\:", "$COLON$")
.replace(":", File.pathSeparator)
.replace("$COLON$", ":");
String argWithColonsReplaced = arg
.replace("\\:", "$COLON$")
.replace(":", File.pathSeparator)
.replace("$COLON$", ":");
return argsWithColonsReplaced
.replace("$TEMP_DIR$", tempDir)
.replace(TESTDATA_DIR, new File(argsFilePath).getParent())
.replace(
"$FOREIGN_ANNOTATIONS_DIR$",
new File(AbstractForeignAnnotationsTestKt.getFOREIGN_ANNOTATIONS_SOURCES_PATH()).getPath()
);
});
String argWithTestPathsReplaced = replaceTestPaths(argWithColonsReplaced, testDataDir, tempDir);
if (isArgfileArgument(arg)) {
return mockArgfile(argWithTestPathsReplaced, testDataDir, tempDir);
} else {
return argWithTestPathsReplaced;
}
}
private static boolean isArgfileArgument(@NotNull String arg) {
return arg.startsWith("-Xargfile=");
}
// Create new temp. argfile with all test paths replaced and return argfile-argument pointing to that file
private static String mockArgfile(@NotNull String argfileArgument, @NotNull String testDataDir, @NotNull String tempDir) {
int firstIndexOfArgfilePath = "-Xargfile=".length();
String argfilePath = argfileArgument.substring(firstIndexOfArgfilePath);
File argfile = new File(argfilePath);
if (argfile.exists()) {
File mockArgfile = FilesKt.createTempFile(argfile.getAbsolutePath(), "", new File(tempDir));
String oldArgfileContent = FilesKt.readText(argfile, Charsets.UTF_8);
String newArgfileContent = replaceTestPaths(oldArgfileContent, testDataDir, tempDir);
FilesKt.writeText(mockArgfile, newArgfileContent, Charsets.UTF_8);
return "-Xargfile=" + mockArgfile.getAbsolutePath();
} else {
return argfileArgument;
}
}
private static String replaceTestPaths(@NotNull String str, @NotNull String testDataDir, @NotNull String tempDir) {
return str
.replace("$TEMP_DIR$", tempDir)
.replace(TESTDATA_DIR, testDataDir)
.replace(
"$FOREIGN_ANNOTATIONS_DIR$",
new File(AbstractForeignAnnotationsTestKt.getFOREIGN_ANNOTATIONS_SOURCES_PATH()).getPath()
);
}
protected void doJvmTest(@NotNull String fileName) {