Skip to content

Commit

Permalink
Packaging a CLI tool instead
Browse files Browse the repository at this point in the history
  • Loading branch information
LPeter1997 committed Sep 21, 2024
1 parent e63b3dd commit 63d7e80
Show file tree
Hide file tree
Showing 12 changed files with 253 additions and 106 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/publish.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ on:
description: Deploy components of the REPL (Compiler, Chr, Repl)
deploy-coverage-tool:
type: boolean
description: Deploy the coverage tool (Coverage, Coverage.MSBuild)
description: Deploy the coverage tool (Coverage, Coverage.Toolset)
deploy-langserver:
type: boolean
description: Deploy the language server (Compiler, Chr, LanguageServer, Lsp)
Expand Down Expand Up @@ -66,7 +66,7 @@ jobs:
$sdkProjects = "Compiler", "Chr", "Compiler.Toolset", "Sdk", "ProjectTemplates"
$replProjects = "Compiler", "Chr", "Repl"
$coverageToolProjects = "Coverage", "Coverage.MSBuild"
$coverageToolProjects = "Coverage", "Coverage.Toolset"
$langserverProjects = "Compiler", "Chr", "LanguageServer", "Lsp", "JsonRpc"
$debugadapterProjects = "DebugAdapter", "Dap", "JsonRpc"
Expand Down
11 changes: 11 additions & 0 deletions src/Draco.Coverage.Cli/Draco.Coverage.Cli.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\Draco.Coverage\Draco.Coverage.csproj" />
</ItemGroup>

</Project>
77 changes: 77 additions & 0 deletions src/Draco.Coverage.Cli/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
using System;
using System.IO;
using System.Linq;

namespace Draco.Coverage.Cli;

internal static class Program
{
private static int Main(string[] args)
{
args = ProcessArgs(args);

if (args.Length != 2)
{
Log("Usage: Draco.Coverage.Cli <inputPaths> <outputPaths>");
Log($"Provided argument(s): {string.Join(", ", args)}");
return 1;
}

var inputPaths = args[0];
var outputPaths = args[1];

if (string.IsNullOrEmpty(inputPaths) && string.IsNullOrEmpty(outputPaths))
{
// Ok, no inputs our outputs
return 0;
}

var inputPathArray = ProcessPath(inputPaths);
var outputPathArray = ProcessPath(outputPaths);

if (inputPathArray.Length != outputPathArray.Length)
{
Log("Input and output paths must have the same number of elements");
return 1;
}

foreach (var (inputPath, outputPath) in inputPathArray.Zip(outputPathArray))
{
if (!Path.Exists(inputPath))
{
Log($"Input path '{inputPath}' does not exist");
return 1;
}
if (!Path.Exists(outputPath))
{
Log($"Output path '{outputPath}' does not exist");
return 1;
}

InstrumentedAssembly.Weave(inputPath, outputPath);
}

return 0;
}

private static void Log(string message) => Console.Error.WriteLine(message);

// MSBuild passes in the path to all binaries copied, concatenated with a semocilon
// We need to split them and filter for .dll files
private static string[] ProcessPath(string path) => path
.Split(';')
.Where(p => !string.IsNullOrWhiteSpace(p))
.Where(p => Path.GetExtension(p) == ".dll")
.Select(Path.GetFullPath)
.ToArray();

private static string[] ProcessArgs(string[] args)
{
if (args.Length != 1) return args;
if (!args[0].StartsWith('@')) return args;

// RSP file
var file = args[0][1..];
return File.ReadAllLines(file);
}
}
45 changes: 0 additions & 45 deletions src/Draco.Coverage.MSBuild/CoverageWeaveTask.cs

This file was deleted.

51 changes: 0 additions & 51 deletions src/Draco.Coverage.MSBuild/Draco.Coverage.MSBuild.csproj

This file was deleted.

87 changes: 87 additions & 0 deletions src/Draco.Coverage.Tasks/CoverageWeaveTask.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
using System;
using System.IO;
using System.Linq;
using System.Text;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;

namespace Draco.Coverage.Tasks;

public sealed class CoverageWeaveTask : ToolTask
{
public string WeaverPath { get; set; }
public string InputPaths { get; set; }
public string OutputPaths { get; set; }

protected override string ToolName => Path.GetFileName(GetDotNetPath());

private int errorCount = 0;

protected override string GenerateCommandLineCommands() => $"exec \"{this.WeaverPath}\"";

protected override string GenerateResponseFileCommands()
{
var sb = new StringBuilder();
sb.AppendLine(this.InputPaths);
sb.AppendLine(this.OutputPaths);
return sb.ToString();
}

protected override void LogEventsFromTextOutput(string singleLine, MessageImportance messageImportance)
{
this.errorCount++;
base.LogEventsFromTextOutput(singleLine, messageImportance);
}

protected override bool HandleTaskExecutionErrors()
{
if (this.errorCount == 0)
{
var message = "Internal weaver error. Please open an issue with a repro case at https://github.com/Draco-lang/Compiler/issues";
this.Log.LogCriticalMessage(
subcategory: null, code: "DRC0001", helpKeyword: null,
file: null,
lineNumber: 0, columnNumber: 0,
endLineNumber: 0, endColumnNumber: 0,
message: message.ToString());
}

return false;
}

private const string DotNetHostPathEnvironmentName = "DOTNET_HOST_PATH";

// https://github.com/dotnet/roslyn/blob/020db28fa9b744146e6f072dbdc6bf3e62c901c1/src/Compilers/Shared/RuntimeHostInfo.cs#L59
private static string GetDotNetPath()
{
if (Environment.GetEnvironmentVariable(DotNetHostPathEnvironmentName) is string pathToDotNet)
{
return pathToDotNet;
}

var (fileName, sep) = Environment.OSVersion.Platform == PlatformID.Win32NT
? ("dotnet.exe", ';')
: ("dotnet", ':');

var path = Environment.GetEnvironmentVariable("PATH") ?? "";
foreach (var item in path.Split(new[] { sep }, StringSplitOptions.RemoveEmptyEntries))
{
try
{
var filePath = Path.Combine(item, fileName);
if (File.Exists(filePath))
{
return filePath;
}
}
catch
{
// If we can't read a directory for any reason just skip it
}
}

return fileName;
}

protected override string GenerateFullPathToTool() => Path.GetFullPath(GetDotNetPath());
}
13 changes: 13 additions & 0 deletions src/Draco.Coverage.Tasks/Draco.Coverage.Tasks.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<IsPackable>false</IsPackable>
<Nullable>disable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Build.Utilities.Core" Version="17.0.0" PrivateAssets="All" ExcludeAssets="Runtime" />
</ItemGroup>

</Project>
40 changes: 40 additions & 0 deletions src/Draco.Coverage.Toolset/Draco.Coverage.Toolset.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<HasRuntimeOutput>true</HasRuntimeOutput>
<DevelopmentDependency>true</DevelopmentDependency>
<IncludeBuildOutput>false</IncludeBuildOutput>
<NoWarn>$(NoWarn);NU5100</NoWarn>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\Draco.Coverage.Tasks\Draco.Coverage.Tasks.csproj" DestinationSubDirectory="tasks\" PrivateAssets="All" />
<ProjectReference Include="..\Draco.Coverage\Draco.Coverage.csproj" DestinationSubDirectory="lib\" />
<ProjectReference Include="..\Draco.Coverage.Cli\Draco.Coverage.Cli.csproj" PrivateAssets="All" />
</ItemGroup>

<Target Name="GetFilesToPackage" AfterTargets="Build">
<ItemGroup>
<_File Include="$(OutDir)\**\*.*" PackagePath="tools" Exclude="$(OutDir)\tasks\**\*.*;$(OutDir)\lib\**\*.*" />
<_File Include="$(OutDir)\tasks\**\*.*" PackagePath="tasks" />
<_File Include="$(OutDir)\lib\**\*.*" PackagePath="lib\$(TargetFramework)" />
<_File Include="$(OutDir)\lib\**\*.*" PackagePath="tools" />

<_File Include="build\**\*.*" PackagePath="build" />

<None Include="@(_File)" Pack="True" PackagePath="%(_File.PackagePath)" />
</ItemGroup>
</Target>

<!-- Don't actually create binaries for this project. -->
<Target Name="CoreCompile" />
<Target Name="CreateManifestResourceNames" />

<!-- And don't try to copy them to the build output either. -->
<PropertyGroup>
<CopyBuildOutputToOutputDirectory>false</CopyBuildOutputToOutputDirectory>
<GenerateDependencyFile>false</GenerateDependencyFile>
<GenerateRuntimeConfigurationFiles>false</GenerateRuntimeConfigurationFiles>
</PropertyGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<Project>

<UsingTask TaskName="CoverageWeaveTask" AssemblyFile="$(MSBuildThisFileDirectory)..\tasks\netstandard2.0\Draco.Coverage.MSBuild.dll" />
<UsingTask TaskName="CoverageWeaveTask" AssemblyFile="$(MSBuildThisFileDirectory)..\tasks\Draco.Coverage.Tasks.dll" />

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,11 @@
</ItemGroup>

<CoverageWeaveTask
InputPath="@(ReferencesWithWeave->'$(OutDir)%(Filename)%(Extension)')"
OutputPath="@(ReferencesWithWeave->'$(OutDir)%(Filename)%(Extension)')" />
InputPaths="@(ReferencesWithWeave->'$(OutDir)%(Filename)%(Extension)')"
OutputPaths="@(ReferencesWithWeave->'$(OutDir)%(Filename)%(Extension)')"
WeaverPath="$(MSBuildThisFileDirectory)..\tools\Draco.Coverage.Cli.dll"
ToolPath="$(DotNetHostDirectory)"
ToolExe="$(DotNetHostFileName)"/>
</Target>

</Project>
4 changes: 0 additions & 4 deletions src/Draco.Coverage/Draco.Coverage.csproj
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Mono.Cecil" Version="0.11.5" />
Expand Down
Loading

0 comments on commit 63d7e80

Please sign in to comment.