Skip to content

Commit 76271d3

Browse files
committed
Update SourceExpander.Console
1 parent 2fd967c commit 76271d3

21 files changed

+725
-118
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [Unreleased]
9+
### Changed
10+
- Update SourceExpander.Console
11+
812
## [7.0.0] - 2024-01-30
913
### Added
1014
- SourceExpander.Generator: Add `unsafe block` warning

Source/Sandbox/SampleLibrary/SampleLibrary.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
</PropertyGroup>
2424

2525
<ItemGroup>
26-
<PackageReference Include="ac-library-csharp" Version="3.9.1" />
26+
<PackageReference Include="ac-library-csharp" Version="[3.9.1]" />
2727
<ProjectReference Include="..\..\SourceExpander.Embedder\SourceExpander.Embedder.csproj">
2828
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
2929
<OutputItemType>Analyzer</OutputItemType>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[**/ConsoleApp.cs]
2+
dotnet_diagnostic.CS1591.severity = none
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
using System.Collections.Generic;
2+
3+
namespace SourceExpander
4+
{
5+
/// <summary>
6+
/// Result of the 'dependency' subcommand
7+
/// </summary>
8+
/// <param name="FileName"></param>
9+
/// <param name="Dependencies"></param>
10+
/// <param name="TypeNames"></param>
11+
public record DependencyResult(string FileName, IEnumerable<string> Dependencies, IEnumerable<string> TypeNames);
12+
}

Source/SourceExpander.Console/Program.cs

+4-1
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,7 @@
1616

1717
return null;
1818
};
19-
ConsoleApp.Run<SourceExpanderCommand>(args);
19+
20+
var app = ConsoleApp.Create();
21+
app.Add<SourceExpanderCommand>();
22+
app.Run(args);

Source/SourceExpander.Console/SourceExpander.Console.csproj

+11-7
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22

33
<PropertyGroup>
44
<OutputType>Exe</OutputType>
5-
<TargetFrameworks>net8.0;net6.0</TargetFrameworks>
5+
<TargetFrameworks>net8.0</TargetFrameworks>
66
<Nullable>enable</Nullable>
77
<LangVersion>latest</LangVersion>
8+
<NoWarn>$(NoWarn);1702;IDE0056;IDE0057</NoWarn>
89

910
<RootNamespace>SourceExpander</RootNamespace>
1011

@@ -20,6 +21,7 @@
2021
<ItemGroup>
2122
<InternalsVisibleTo Include="SourceExpander.Console.Test, PublicKey=002400000480000094000000060200000024000052534131000400000100010019f27fe0b62f6a374e67a12dbd713e0b521d251abc73fcb1e3929cc74a99905daae786e8854b1ccd7401ecb850627c58ecf491bebe9a2fef9effbc63e74e1c00e036282d754dd6c8ffd12e8fd07897bf31b551f68d594c2bdd5be8009adc6eb625e10629d36d731246a8a9c353b62c49902024cf1c7fc0f59952325eec2df5a6" />
2223
<Using Include="SourceExpander" />
24+
<Using Include="ConsoleAppFramework" />
2325

2426
<Compile Include="../SourceExpander.Share/**/EmbeddedData.cs" LinkBase="Share" />
2527
<Compile Include="../SourceExpander.Share/**/SourceFileInfo.cs" LinkBase="Share" />
@@ -32,11 +34,13 @@
3234

3335
<ItemGroup>
3436
<PackageReference Include="Base32768" Version="2.0.2" />
35-
<PackageReference Include="ConsoleAppFramework" Version="4.2.4" />
36-
<PackageReference Include="Microsoft.Build.Locator" Version="1.6.10" />
37-
<PackageReference Include="Microsoft.Build" Version="17.8.3" ExcludeAssets="runtime" />
38-
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.3.1" />
39-
<PackageReference Include="Microsoft.CodeAnalysis.Workspaces.MSBuild" Version="4.3.1" />
40-
<PackageReference Include="System.Text.Json" Version="8.0.5" />
37+
<PackageReference Include="ConsoleAppFramework" Version="5.3.3">
38+
<PrivateAssets>all</PrivateAssets>
39+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
40+
</PackageReference>
41+
<PackageReference Include="Microsoft.Build.Locator" Version="1.7.8" />
42+
<PackageReference Include="Microsoft.Build" Version="17.11.4" ExcludeAssets="runtime" />
43+
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.12.0" />
44+
<PackageReference Include="Microsoft.CodeAnalysis.Workspaces.MSBuild" Version="4.12.0" />
4145
</ItemGroup>
4246
</Project>

Source/SourceExpander.Console/SourceExpanderCommand.Dependency.cs

+32-22
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,27 @@
44
using System.IO;
55
using System.Linq;
66
using System.Text.Json;
7+
using System.Threading;
78
using System.Threading.Tasks;
89
using Microsoft.CodeAnalysis;
910
using Microsoft.CodeAnalysis.CSharp;
1011

11-
internal partial class SourceExpanderCommand : ConsoleAppBase
12+
partial struct SourceExpanderCommand
1213
{
13-
[Command("dependency", "Show dependency json")]
14+
/// <summary>
15+
/// Show dependency json.
16+
/// </summary>
17+
/// <param name="target">Target project(.csproj/.cs).</param>
18+
/// <param name="fullFilePath">-p,File name as full path.</param>
19+
/// <param name="cancellationToken"></param>
20+
/// <returns></returns>
21+
/// <exception cref="ArgumentException"></exception>
22+
/// <exception cref="InvalidOperationException"></exception>
23+
[Command("dependency")]
1424
public async Task Dependency(
15-
[Option(0, "target project(.csproj/.cs)")] string target,
16-
[Option("p", "file name as full path")] bool fullFilePath = false)
25+
[Argument] string target,
26+
bool fullFilePath = false,
27+
CancellationToken cancellationToken = default)
1728
{
1829
var targetInfo = new FileInfo(target);
1930
if (!targetInfo.Exists)
@@ -27,7 +38,7 @@ public async Task Dependency(
2738
if (fullFilePath)
2839
props.Add("SourceExpander_Embedder_EmbeddingFileNameType", "FullPath");
2940

30-
var (compilation, csProject) = await GetCompilation(project, props);
41+
var (compilation, csProject) = await GetCompilation(project, props, cancellationToken: cancellationToken);
3142
if (compilation is not CSharpCompilation csCompilation)
3243
throw new InvalidOperationException("Failed to get compilation");
3344
if (csProject.ParseOptions is not CSharpParseOptions parseOptions)
@@ -41,40 +52,39 @@ public async Task Dependency(
4152
out var version) && version < new Version(5, 0, 0, 0))
4253
{
4354
if (version is null)
44-
await Console.Error.WriteLineAsync("needs SourceExpander.Embedder 5.0.0 or newer");
55+
await Error.WriteLineAsync("needs SourceExpander.Embedder 5.0.0 or newer");
4556
else
46-
await Console.Error.WriteLineAsync($"needs SourceExpander.Embedder 5.0.0 or newer, Current: {version}");
57+
await Error.WriteLineAsync($"needs SourceExpander.Embedder 5.0.0 or newer, Current: {version}");
4758

4859
Environment.Exit(1);
4960
return;
5061
}
5162
}
52-
var metadatas = metadataResolver.GetEmbeddedSourceFiles(true, Context.CancellationToken)
63+
var metadatas = metadataResolver
64+
.GetEmbeddedSourceFiles(true, cancellationToken)
5365
.ToArray();
5466

5567
var infos = metadatas.SelectMany(t => t.Data.Sources)
56-
.Select(t => new
57-
{
58-
t.FileName,
59-
t.Dependencies,
60-
t.TypeNames,
61-
});
68+
.Select(t => new DependencyResult(
69+
FileName: t.FileName,
70+
Dependencies: t.Dependencies,
71+
TypeNames: t.TypeNames
72+
));
6273
if (metadatas.FirstOrDefault(t => t.Name == compilation.AssemblyName) is not { Data.Sources.Length: > 0 })
6374
{
6475
infos = infos.Concat(
6576
new EmbeddedLoader(csCompilation,
6677
parseOptions,
6778
new ExpandConfig(),
68-
Context.CancellationToken)
79+
cancellationToken)
6980
.Dependencies()
70-
.Select(t => new
71-
{
72-
FileName = t.FilePath,
73-
Dependencies = (IEnumerable<string>)t.Dependencies,
74-
TypeNames = Enumerable.Empty<string>(),
75-
}));
81+
.Select(t => new DependencyResult(
82+
FileName: t.FilePath,
83+
Dependencies: t.Dependencies,
84+
TypeNames: Enumerable.Empty<string>()
85+
)));
7686
}
7787
var result = JsonSerializer.Serialize(infos, DefaultSerializerOptions);
78-
Console.WriteLine(result);
88+
Output.WriteLine(result);
7989
}
8090
}
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,49 @@
11
using System;
2-
using System.Collections.Generic;
3-
using System.Collections.Immutable;
42
using System.IO;
53
using System.Linq;
64
using System.Text.Json;
5+
using System.Threading;
76
using System.Threading.Tasks;
87
using Microsoft.CodeAnalysis;
98
using Microsoft.CodeAnalysis.CSharp;
10-
using Microsoft.CodeAnalysis.MSBuild;
119

12-
internal partial class SourceExpanderCommand : ConsoleAppBase
10+
partial struct SourceExpanderCommand
1311
{
14-
[RootCommand]
12+
/// <summary>
13+
/// Expand embedded source.
14+
/// </summary>
15+
/// <param name="expand">Expanding file.</param>
16+
/// <param name="output">-o,Output file</param>
17+
/// <param name="project">-p,csproj file</param>
18+
/// <param name="staticEmbedding">-s,Static embedding text</param>
19+
/// <param name="cancellationToken"></param>
20+
/// <returns></returns>
21+
/// <exception cref="InvalidOperationException"></exception>
22+
[Command("")]
1523
public async Task Expand(
16-
[Option(0, "expanding file")] string expand,
17-
[Option("o", "output file")] string? output = null,
18-
[Option("p", "csproj file")] string? project = null,
19-
[Option("s", "static embedding text")] string? staticEmbedding = null)
24+
[Argument] string expand,
25+
string? output = null,
26+
string? project = null,
27+
string? staticEmbedding = null,
28+
CancellationToken cancellationToken = default)
2029
{
2130
project ??= PathUtil.GetProjectPath(expand);
2231
project = Path.GetFullPath(project);
2332

24-
var (compilation, csProject) = await GetCompilation(project);
33+
var (compilation, csProject) = await GetCompilation(project, cancellationToken: cancellationToken);
2534
if (compilation is not CSharpCompilation csCompilation)
2635
throw new InvalidOperationException("Failed to get compilation");
2736
if (csProject.ParseOptions is not CSharpParseOptions parseOptions)
2837
throw new InvalidOperationException("Failed to get parseOptions");
2938

3039
var config = new ExpandConfig(
31-
matchFilePatterns: new[] { new FileInfo(expand).FullName },
40+
matchFilePatterns: [new FileInfo(expand).FullName],
3241
staticEmbeddingText: staticEmbedding);
3342

3443
var (_, code) = new EmbeddedLoader(csCompilation,
3544
parseOptions,
3645
config,
37-
Context.CancellationToken)
46+
cancellationToken)
3847
.ExpandedCodes()
3948
.SingleOrDefault();
4049

@@ -44,28 +53,37 @@ public async Task Expand(
4453

4554
if (output is null)
4655
{
47-
Console.Write(code);
56+
Output.Write(code);
4857
}
4958
else
5059
{
5160
output = Path.GetFullPath(output);
5261

53-
Console.WriteLine($"expanding file: {project}");
54-
Console.WriteLine($"project: {expand}");
55-
Console.WriteLine($"output: {output}");
62+
Output.WriteLine($"expanding file: {project}");
63+
Output.WriteLine($"project: {expand}");
64+
Output.WriteLine($"output: {output}");
5665

57-
await File.WriteAllTextAsync(output, code);
66+
await File.WriteAllTextAsync(output, code, cancellationToken: cancellationToken);
5867
}
5968
}
6069

61-
[Command("expand-all", "Show expanded codes json")]
70+
/// <summary>
71+
/// Show expanded codes json.
72+
/// </summary>
73+
/// <param name="project">Target project(.csproj).</param>
74+
/// <param name="staticEmbedding">-s,Static embedding text.</param>
75+
/// <param name="cancellationToken"></param>
76+
/// <returns></returns>
77+
/// <exception cref="InvalidOperationException"></exception>
78+
[Command("expand-all")]
6279
public async Task ExpandAll(
63-
[Option(0, "target project(.csproj)")] string project,
64-
[Option("s", "static embedding text")] string? staticEmbedding = null)
80+
[Argument] string project,
81+
string? staticEmbedding = null,
82+
CancellationToken cancellationToken = default)
6583
{
6684
project = Path.GetFullPath(project);
6785

68-
var (compilation, csProject) = await GetCompilation(project);
86+
var (compilation, csProject) = await GetCompilation(project, cancellationToken: cancellationToken);
6987
if (compilation is not CSharpCompilation csCompilation)
7088
throw new InvalidOperationException("Failed to get compilation");
7189
if (csProject.ParseOptions is not CSharpParseOptions parseOptions)
@@ -76,21 +94,14 @@ public async Task ExpandAll(
7694
var expanded = new EmbeddedLoader(csCompilation,
7795
parseOptions,
7896
config,
79-
Context.CancellationToken)
97+
cancellationToken)
8098
.ExpandedCodes();
8199

82100
var result = JsonSerializer.Serialize(expanded.Select(t => new
83101
{
84102
t.SyntaxTree.FilePath,
85103
t.ExpandedCode,
86104
}), DefaultSerializerOptions);
87-
Console.WriteLine(result);
88-
}
89-
90-
private async Task<(Compilation? Compilation, Project Project)> GetCompilation(string projectPath, IDictionary<string, string>? properties = null)
91-
{
92-
var workspace = MSBuildWorkspace.Create(properties ?? ImmutableDictionary<string, string>.Empty);
93-
var project = await workspace.OpenProjectAsync(projectPath, cancellationToken: Context.CancellationToken);
94-
return (await project.GetCompilationAsync(Context.CancellationToken), project);
105+
Output.WriteLine(result);
95106
}
96107
}

Source/SourceExpander.Console/SourceExpanderCommand.LibraryList.cs

+16-9
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,32 @@
11
using System;
22
using System.IO;
33
using System.Linq;
4+
using System.Threading;
45
using System.Threading.Tasks;
56
using Microsoft.CodeAnalysis;
6-
using Microsoft.CodeAnalysis.CSharp;
77

8-
internal partial class SourceExpanderCommand : ConsoleAppBase
8+
partial struct SourceExpanderCommand
99
{
10-
[Command("library-list", @"Show embedded libraries list from dependency
11-
12-
<assembly name>,<version>")]
10+
/// <summary>
11+
/// List embedded libraries from dependency.
12+
/// </summary>
13+
/// <param name="target">Target project(.csproj/.cs).</param>
14+
/// <param name="cancellationToken"></param>
15+
/// <returns></returns>
16+
/// <exception cref="ArgumentException"></exception>
17+
/// <exception cref="InvalidOperationException"></exception>
18+
[Command("library-list")]
1319
public async Task LibraryList(
14-
[Option(0, "target project(.csproj/.cs)")] string target)
20+
[Argument] string target,
21+
CancellationToken cancellationToken = default)
1522
{
1623
var targetInfo = new FileInfo(target);
1724
if (!targetInfo.Exists)
1825
throw new ArgumentException("File does not exist.", nameof(target));
1926
var project = targetInfo.Extension == ".csproj" ? targetInfo.FullName : PathUtil.GetProjectPath(target);
20-
var (compilation, _) = await GetCompilation(project);
27+
var (compilation, _) = await GetCompilation(project, cancellationToken: cancellationToken);
2128

22-
if (compilation is not CSharpCompilation)
29+
if (compilation == null)
2330
throw new InvalidOperationException("Failed to get compilation");
2431

2532
var metadataResolver = new AssemblyMetadataResolver(compilation);
@@ -31,7 +38,7 @@ public async Task LibraryList(
3138
var dict = metadataResolver.GetAssemblyMetadata(symbol);
3239
if (dict.TryGetValue("SourceExpander.EmbedderVersion", out var version))
3340
{
34-
Console.WriteLine($"{symbol.Name},{version}");
41+
Output.WriteLine($"{symbol.Name},{version}");
3542
}
3643
}
3744
}

0 commit comments

Comments
 (0)