Skip to content

Commit fca7885

Browse files
authored
Merge branch 'main' into private_print_vlb
2 parents b1a19ac + e9d4e75 commit fca7885

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+652
-109
lines changed

.editorconfig

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ dotnet_diagnostic.CA2254.severity = none
1717

1818
dotnet_diagnostic.RS0041.severity = warning
1919

20+
dotnet_diagnostic.IDE0005.severity = none
2021
dotnet_diagnostic.IDE0007.severity = warning
2122
dotnet_diagnostic.IDE0008.severity = none
2223
dotnet_diagnostic.IDE0011.severity = warning
@@ -55,3 +56,7 @@ dotnet_diagnostic.IDE0301.severity = warning
5556
dotnet_diagnostic.IDE0305.severity = none
5657
dotnet_diagnostic.IDE0330.severity = warning
5758
dotnet_diagnostic.IDE1006.severity = warning
59+
60+
dotnet_diagnostic.RSEXPERIMENTAL005.severity = none
61+
62+
dotnet_diagnostic.SYSLIB1045.severity = warning

Directory.Build.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<Project>
22
<PropertyGroup>
3-
<TargetFrameworks>net9.0</TargetFrameworks>
3+
<TargetFrameworks>net10.0</TargetFrameworks>
44
<LangVersion>12</LangVersion>
55
<ImplicitUsings>enable</ImplicitUsings>
66
<Nullable>enable</Nullable>

Directory.Packages.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
<PackageVersion Include="Microsoft.AspNetCore.SpaServices.Extensions" Version="8.0.8" />
1616
<PackageVersion Include="Microsoft.CodeAnalysis.Common" Version="4.14.0" />
1717
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.14.0" />
18-
<PackageVersion Include="Microsoft.CodeAnalysis.PublicApiAnalyzers" Version="3.3.4" />
18+
<PackageVersion Include="Microsoft.CodeAnalysis.PublicApiAnalyzers" Version="4.14.0" />
1919
<PackageVersion Include="Microsoft.CSharp" Version="4.7.0" />
2020
<PackageVersion Include="Microsoft.Extensions.Logging" Version="8.0.0" />
2121
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />

Dockerfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
FROM mcr.microsoft.com/dotnet/aspnet:9.0.5-bookworm-slim-amd64 AS base
1+
FROM mcr.microsoft.com/dotnet/aspnet:10.0.0-preview.5 AS base
22
WORKDIR /app
33
ENV ASPNETCORE_URLS=http://+:80
44
EXPOSE 80
55

6-
FROM mcr.microsoft.com/dotnet/sdk:9.0.300-bookworm-slim-amd64 AS build
6+
FROM mcr.microsoft.com/dotnet/sdk:10.0.100-preview.5 AS build
77

88
RUN set -uex \
99
&& apt-get update \

Src/CSharpier.Cli.Tests/CliTests.cs

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
using System.Diagnostics;
2+
using System.Runtime.InteropServices;
3+
using System.Security.AccessControl;
24
using System.Text;
35
using CliWrap;
46
using CliWrap.Buffered;
@@ -89,6 +91,72 @@ public async Task Format_Should_Format_Subdirectory(string subdirectory)
8991
(await ReadAllTextAsync("Subdirectory/BasicFile.cs")).Should().Be(formattedContent);
9092
}
9193

94+
[Test]
95+
public async Task Format_Should_Handle_UnauthorizedAccessException_In_Subdirectory()
96+
{
97+
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
98+
{
99+
// on linux you can't read a subdirectory if you don't have access to the parent directory
100+
return;
101+
}
102+
103+
var formattedContent = "public class ClassName { }\n";
104+
var unformattedContent = "public class ClassName {\n\n}";
105+
106+
await WriteFileAsync(
107+
"UnauthorizedSubdirectory/Subdirectory/BasicFile.cs",
108+
unformattedContent
109+
);
110+
111+
var directory = new DirectoryInfo(
112+
Path.Combine(testFileDirectory, "UnauthorizedSubdirectory")
113+
);
114+
115+
void ChangeDirectoryPermissions(bool allowAccess)
116+
{
117+
var accessControl = directory.GetAccessControl();
118+
if (allowAccess)
119+
{
120+
accessControl.RemoveAccessRule(
121+
new FileSystemAccessRule(
122+
"Everyone",
123+
FileSystemRights.FullControl,
124+
AccessControlType.Deny
125+
)
126+
);
127+
}
128+
else
129+
{
130+
accessControl.AddAccessRule(
131+
new FileSystemAccessRule(
132+
"Everyone",
133+
FileSystemRights.FullControl,
134+
AccessControlType.Deny
135+
)
136+
);
137+
}
138+
directory.SetAccessControl(accessControl);
139+
}
140+
141+
try
142+
{
143+
ChangeDirectoryPermissions(allowAccess: false);
144+
145+
var formatResult = await new CsharpierProcess()
146+
.WithArguments("format UnauthorizedSubdirectory/Subdirectory")
147+
.ExecuteAsync();
148+
149+
formatResult.ErrorOutput.Should().BeEmpty();
150+
(await ReadAllTextAsync("UnauthorizedSubdirectory/Subdirectory/BasicFile.cs"))
151+
.Should()
152+
.Be(formattedContent);
153+
}
154+
finally
155+
{
156+
ChangeDirectoryPermissions(allowAccess: true);
157+
}
158+
}
159+
92160
[Test]
93161
public async Task Format_Should_Respect_Ignore_File_With_Subdirectory_When_DirectorOrFile_Is_Dot()
94162
{
@@ -283,6 +351,39 @@ public async Task Format_Should_Format_Piped_File_With_Config()
283351
result.ExitCode.Should().Be(0);
284352
}
285353

354+
[Test]
355+
public async Task Format_Should_Format_Piped_File_With_Config_And_Path()
356+
{
357+
await WriteFileAsync("Stdin/.csharpierrc", "printWidth: 10");
358+
359+
var formattedContent1 = "var x =\n _________________longName;\n";
360+
var unformattedContent1 = "var x = _________________longName;\n";
361+
362+
var result = await new CsharpierProcess()
363+
.WithArguments("format --stdin-path ./Stdin/Test.cs")
364+
.WithPipedInput(unformattedContent1)
365+
.ExecuteAsync();
366+
367+
result.Output.Should().Be(formattedContent1);
368+
result.ExitCode.Should().Be(0);
369+
}
370+
371+
[Test]
372+
public async Task Format_Should_Not_Format_Piped_File_With_Gitignore_And_Path()
373+
{
374+
await WriteFileAsync("Stdin/.gitignore", "*");
375+
376+
var unformattedContent1 = "var x = _________________longName;\n";
377+
378+
var result = await new CsharpierProcess()
379+
.WithArguments("format --stdin-path ./Stdin/Test.cs")
380+
.WithPipedInput(unformattedContent1)
381+
.ExecuteAsync();
382+
383+
result.Output.Should().Be(unformattedContent1);
384+
result.ExitCode.Should().Be(0);
385+
}
386+
286387
[Test]
287388
public async Task Format_Should_Format_Piped_File_With_EditorConfig()
288389
{

Src/CSharpier.Cli.Tests/ServerTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ namespace CSharpier.Cli.Tests;
1212
[TestFixture]
1313
public class ServerTests
1414
{
15-
private static readonly HttpClient httpClient = new HttpClient();
15+
private static readonly HttpClient httpClient = new();
1616

1717
// TODO server add other tests
1818
// starting on port

Src/CSharpier.Cli/CSharpier.Cli.csproj

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<OutputType>Exe</OutputType>
55
<PackageId>CSharpier</PackageId>
66
<AssemblyName>CSharpier</AssemblyName>
7-
<TargetFrameworks>net8.0;net9.0</TargetFrameworks>
7+
<TargetFrameworks>net8.0;net9.0;net10.0</TargetFrameworks>
88
<PackAsTool>true</PackAsTool>
99
<ToolCommandName>csharpier</ToolCommandName>
1010
<AssemblyOriginatorKeyFile>../../Nuget/csharpier.snk</AssemblyOriginatorKeyFile>
@@ -15,16 +15,20 @@
1515
<ItemGroup>
1616
<PackageReference Include="GitignoreParserNet" />
1717
<PackageReference Include="ini-parser-netstandard" />
18-
<PackageReference Include="Microsoft.Extensions.Logging" />
1918
<PackageReference Include="NReco.Logging.File" />
2019
<PackageReference Include="StrongNamer" />
2120
<PackageReference Include="System.CommandLine" />
2221
<PackageReference Include="System.IO.Abstractions" />
2322
<PackageReference Include="System.IO.Abstractions.TestingHelpers" />
2423
<PackageReference Include="System.IO.Hashing" />
25-
<PackageReference Include="System.Text.Encoding.CodePages" />
2624
<PackageReference Include="YamlDotNet" />
2725
<FrameworkReference Include="Microsoft.AspNetCore.App" />
26+
</ItemGroup>
27+
<ItemGroup Condition="'$(TargetFramework)' != 'net10.0'">
28+
<PackageReference Include="Microsoft.Extensions.Logging" />
29+
<PackageReference Include="System.Text.Encoding.CodePages" />
30+
</ItemGroup>
31+
<ItemGroup Condition="'$(TargetFramework)' != 'net9.0' AND '$(TargetFramework)' != 'net8.0'">
2832
<PackageReference Include="Microsoft.CodeAnalysis.PublicApiAnalyzers">
2933
<PrivateAssets>all</PrivateAssets>
3034
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>

Src/CSharpier.Cli/CommandLineFormatter.cs

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,33 @@ CancellationToken cancellationToken
2828

2929
if (commandLineOptions.StandardInFileContents != null)
3030
{
31-
var directoryOrFilePath = commandLineOptions.DirectoryOrFilePaths[0];
32-
var directoryPath = fileSystem.Directory.Exists(directoryOrFilePath)
33-
? directoryOrFilePath
34-
: fileSystem.Path.GetDirectoryName(directoryOrFilePath);
35-
var filePath =
36-
directoryOrFilePath != directoryPath
37-
? directoryOrFilePath
38-
: Path.Combine(directoryPath, "StdIn.cs");
39-
40-
ArgumentNullException.ThrowIfNull(directoryPath);
31+
var pathSupplied = false;
32+
var directoryPath = commandLineOptions.DirectoryOrFilePaths[0];
33+
string? filePath;
34+
35+
// when piping multiple files we get a path to a file here
36+
// when sending stdin-filepath we get a path to a file here
37+
// so because this path is not a directory one of those is true
38+
if (!fileSystem.Directory.Exists(directoryPath))
39+
{
40+
filePath = directoryPath;
41+
directoryPath = fileSystem.Path.GetDirectoryName(directoryPath);
42+
ArgumentNullException.ThrowIfNull(directoryPath);
43+
pathSupplied = true;
44+
}
45+
// otherwise someone is running this as a single command and not sending a path
46+
else
47+
{
48+
filePath = Path.Combine(directoryPath, Guid.NewGuid().ToString());
49+
if (commandLineOptions.StandardInFileContents.TrimStart().StartsWith('<'))
50+
{
51+
filePath += ".xml";
52+
}
53+
else
54+
{
55+
filePath += ".cs";
56+
}
57+
}
4158

4259
var fileToFormatInfo = FileToFormatInfo.Create(
4360
filePath,
@@ -58,7 +75,12 @@ CancellationToken cancellationToken
5875
(
5976
commandLineOptions.IncludeGenerated
6077
|| !GeneratedCodeUtilities.IsGeneratedCodeFile(filePath)
61-
) && !await optionsProvider.IsIgnoredAsync(filePath, cancellationToken)
78+
)
79+
// this only considers the ignore files when a path is supplied
80+
&& (
81+
!pathSupplied
82+
|| !await optionsProvider.IsIgnoredAsync(filePath, cancellationToken)
83+
)
6284
)
6385
{
6486
var fileIssueLogger = new FileIssueLogger(
@@ -71,6 +93,7 @@ CancellationToken cancellationToken
7193
filePath,
7294
cancellationToken
7395
);
96+
7497
if (printerOptions is { Formatter: not Formatter.Unknown })
7598
{
7699
printerOptions.IncludeGenerated = commandLineOptions.IncludeGenerated;

Src/CSharpier.Cli/CommandLineOptions.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ namespace CSharpier.Cli;
66
internal class CommandLineOptions
77
{
88
public string[] DirectoryOrFilePaths { get; init; } = [];
9+
public string[] OriginalDirectoryOrFilePaths { get; init; } = [];
910
public bool Check { get; init; }
1011
public bool SkipValidation { get; init; }
1112
public LogFormat LogFormat { get; init; }
12-
public bool Fast { get; init; }
1313
public bool SkipWrite { get; init; }
1414
public bool WriteStdout { get; init; }
1515
public bool NoCache { get; init; }
@@ -18,6 +18,5 @@ internal class CommandLineOptions
1818
public bool IncludeGenerated { get; init; }
1919
public string? StandardInFileContents { get; init; }
2020
public string? ConfigPath { get; init; }
21-
public string[] OriginalDirectoryOrFilePaths { get; init; } = [];
2221
public string? IgnorePath { get; init; }
2322
}

Src/CSharpier.Cli/EditorConfig/EditorConfigFileParser.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,16 @@
77

88
namespace CSharpier.Cli.EditorConfig;
99

10-
internal static class EditorConfigFileParser
10+
internal static partial class EditorConfigFileParser
1111
{
1212
// According to https://spec.editorconfig.org/#file-format
1313
// "Comment: starts with a ; or a #."
14-
private static readonly Regex CommentRegex = new("^[;#].*$");
14+
[GeneratedRegex("^[;#].*$")]
15+
private static partial Regex CommentRegex();
1516

1617
private static readonly IniParserConfiguration Configuration = new()
1718
{
18-
CommentRegex = CommentRegex,
19+
CommentRegex = CommentRegex(),
1920
AllowDuplicateKeys = true,
2021
AllowDuplicateSections = true,
2122
OverrideDuplicateKeys = true,

0 commit comments

Comments
 (0)