Skip to content

Commit

Permalink
Generate response files inline (#134)
Browse files Browse the repository at this point in the history
closes #133
  • Loading branch information
jaredpar committed May 28, 2024
1 parent cb27b6d commit 0af1a60
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 16 deletions.
31 changes: 31 additions & 0 deletions src/Basic.CompilerLog.UnitTests/ProgramTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using Basic.CompilerLog.Util.Serialize;
using MessagePack;
using Microsoft.Build.Logging.StructuredLogger;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using System;
using System.Collections.Generic;
Expand Down Expand Up @@ -389,6 +390,36 @@ public void ResponseBadOption()
Assert.Contains("complog rsp [OPTIONS]", output);
}

[Fact]
public void ResponseInline()
{
var dir = Root.NewDirectory();
RunDotNet($"new console --name example --output .", dir);
var (exitCode, output) = RunCompLogEx($"rsp -i", dir);
Assert.Equal(Constants.ExitSuccess, exitCode);
Assert.Contains("Generating response files inline", output);
Assert.True(File.Exists(Path.Combine(dir, "build.rsp")));
}

[Fact]
public void ResponseInlineMultiTarget()
{
var dir = Root.CopyDirectory(Path.GetDirectoryName(Fixture.ClassLibMultiProjectPath)!);
RunDotNet($"new console --name example --output .", dir);
var (exitCode, output) = RunCompLogEx($"rsp -i", dir);
Assert.Equal(Constants.ExitSuccess, exitCode);
Assert.Contains("Generating response files inline", output);
Assert.True(File.Exists(Path.Combine(dir, "build-net6.0.rsp")));
Assert.True(File.Exists(Path.Combine(dir, "build-net7.0.rsp")));
}

[Fact]
public void ResponseInlineWithOutput()
{
var (exitCode, _) = RunCompLogEx($"rsp -i -o {RootDirectory}");
Assert.Equal(Constants.ExitFailure, exitCode);
}

[Fact]
public void ResponseLinuxComplog()
{
Expand Down
14 changes: 14 additions & 0 deletions src/Basic.CompilerLog.UnitTests/TempDir.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,20 @@ public string NewDirectory(string? name = null)
return path;
}

public string CopyDirectory(string dir)
{
var newDir = NewDirectory();

var info = new DirectoryInfo(dir);
foreach (var item in info.GetFiles())
{
var tempPath = Path.Combine(newDir, item.Name);
item.CopyTo(tempPath, overwrite: true);
}

return newDir;
}

public void EmptyDirectory()
{
var d = new DirectoryInfo(DirectoryPath);
Expand Down
60 changes: 44 additions & 16 deletions src/Basic.CompilerLog/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -338,10 +338,12 @@ void PrintUsage()
int RunResponseFile(IEnumerable<string> args)
{
var singleLine = false;
var inline = false;
var baseOutputPath = "";
var options = new FilterOptionSet()
{
{ "s|singleline", "keep response file as single line", s => singleLine = s != null },
{ "i|inline", "put response files next to the project file", i => inline = i != null },
{ "o|out=", "path to output rsp files", o => baseOutputPath = o },
};

Expand All @@ -354,20 +356,47 @@ int RunResponseFile(IEnumerable<string> args)
return ExitSuccess;
}

if (inline && !string.IsNullOrEmpty(baseOutputPath))
{
WriteLine("Cannot specify both --inline and --out");
return ExitFailure;
}

using var reader = GetCompilerCallReader(extra, BasicAnalyzerHost.DefaultKind);
baseOutputPath = GetBaseOutputPath(baseOutputPath, "rsp");
WriteLine($"Generating response files in {baseOutputPath}");
Directory.CreateDirectory(baseOutputPath);
if (inline)
{
WriteLine($"Generating response files inline");
}
else
{
baseOutputPath = GetBaseOutputPath(baseOutputPath, "rsp");
WriteLine($"Generating response files in {baseOutputPath}");
Directory.CreateDirectory(baseOutputPath);
}

var compilerCalls = reader.ReadAllCompilerCalls();
for (int i = 0; i < compilerCalls.Count; i++)
{
var compilerCall = compilerCalls[i];
var rspDirPath = GetOutputPath(baseOutputPath, compilerCalls, i);
var rspDirPath = inline
? compilerCall.ProjectDirectory
: GetOutputPath(baseOutputPath, compilerCalls, i);
Directory.CreateDirectory(rspDirPath);
var rspFilePath = Path.Combine(rspDirPath, "build.rsp");
var rspFilePath = Path.Combine(rspDirPath, GetRspFileName());
using var writer = new StreamWriter(rspFilePath, append: false, Encoding.UTF8);
ExportUtil.ExportRsp(compilerCall, writer, singleLine);

string GetRspFileName()
{
if (inline)
{
return IsSingleTarget(compilerCalls, i)
? "build.rsp"
: $"build-{compilerCall.TargetFramework}.rsp";
}

return "build.rsp";
}
}

return ExitSuccess;
Expand Down Expand Up @@ -761,21 +790,20 @@ string GetOutputPath(string baseOutputPath, List<CompilerCall> compilerCalls, in
return Path.Combine(baseOutputPath, projectName);
}

string GetProjectUniqueName(List<CompilerCall> compilerCalls, int index)
bool IsSingleTarget(List<CompilerCall> compilerCalls, int index)
{
var compilerCall = compilerCalls[index];
var name = Path.GetFileNameWithoutExtension(compilerCall.ProjectFileName);
return compilerCalls.Count(x => x.ProjectFilePath == compilerCall.ProjectFilePath) == 1;
}

// If the project is built multiple times then need to make it unique
if (compilerCalls.Count(x => x.ProjectFilePath == compilerCall.ProjectFilePath) > 1)
{
if (!string.IsNullOrEmpty(compilerCall.TargetFramework))
{
name += "-" + compilerCall.TargetFramework;
}
}

return name;
string GetProjectUniqueName(List<CompilerCall> compilerCalls, int index)
{
var compilerCall = compilerCalls[index];
var name = Path.GetFileNameWithoutExtension(compilerCall.ProjectFileName);
return IsSingleTarget(compilerCalls, index)
? name
: $"{name}-{compilerCall.TargetFramework}";
}

static string GetResolvedPath(string baseDirectory, string path)
Expand Down

0 comments on commit 0af1a60

Please sign in to comment.