Skip to content

Commit e752f9f

Browse files
authored
Adding option for --ignore-path (#1659)
closes #1585
1 parent 9e9ad83 commit e752f9f

File tree

9 files changed

+111
-30
lines changed

9 files changed

+111
-30
lines changed

Src/CSharpier.Cli.Tests/CliTests.cs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,38 @@ public async Task Format_Should_Respect_Ignore_File_With_Subdirectory_When_Direc
105105
.Be(unformattedContent, $"The file at {filePath} should have been ignored");
106106
}
107107

108+
[Test]
109+
public async Task Format_Should_Respect_Ignore_Path()
110+
{
111+
var unformattedContent = "public class Unformatted { }";
112+
var filePath = "IgnoredFile.cs";
113+
await WriteFileAsync(filePath, unformattedContent);
114+
await WriteFileAsync(".config/.csharpierignore", filePath);
115+
116+
await new CsharpierProcess()
117+
.WithArguments("format . --ignore-path ./config/.csharpierignore")
118+
.ExecuteAsync();
119+
var fileContents = await ReadAllTextAsync(filePath);
120+
121+
fileContents
122+
.Should()
123+
.Be(unformattedContent, $"The file at {filePath} should have been ignored");
124+
}
125+
126+
[Test]
127+
public async Task Check_Should_Respect_Ignore_Path()
128+
{
129+
var unformattedContent = "public class Unformatted { }";
130+
var filePath = "IgnoredFile.cs";
131+
await WriteFileAsync(filePath, unformattedContent);
132+
await WriteFileAsync(".config/.csharpierignore", filePath);
133+
134+
var result = await new CsharpierProcess()
135+
.WithArguments("check . --ignore-path .config/.csharpierignore")
136+
.ExecuteAsync();
137+
result.ExitCode.Should().Be(0);
138+
}
139+
108140
[TestCase(".git")]
109141
[TestCase("subdirectory/.git")]
110142
[TestCase("node_modules")]

Src/CSharpier.Cli/CommandLineFormatter.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ CancellationToken cancellationToken
4848
var optionsProvider = await OptionsProvider.Create(
4949
directoryPath,
5050
commandLineOptions.ConfigPath,
51+
commandLineOptions.IgnorePath,
5152
fileSystem,
5253
logger,
5354
cancellationToken
@@ -178,6 +179,7 @@ CancellationToken cancellationToken
178179
var optionsProvider = await OptionsProvider.Create(
179180
directoryName,
180181
commandLineOptions.ConfigPath,
182+
commandLineOptions.IgnorePath,
181183
fileSystem,
182184
logger,
183185
cancellationToken

Src/CSharpier.Cli/CommandLineOptions.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,5 @@ internal class CommandLineOptions
1919
public string? StandardInFileContents { get; init; }
2020
public string? ConfigPath { get; init; }
2121
public string[] OriginalDirectoryOrFilePaths { get; init; } = [];
22+
public string? IgnorePath { get; init; }
2223
}

Src/CSharpier.Cli/FormattingCommands.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ public static Command CreateFormatCommand()
3535
formatCommand.AddOption(writeStdoutOption);
3636
formatCommand.AddOption(CompilationErrorsAsWarningsOption);
3737
formatCommand.AddOption(ConfigPathOption);
38+
formatCommand.AddOption(IgnorePathOption);
3839
formatCommand.AddOption(LogFormatOption);
3940
formatCommand.AddOption(LogLevelOption);
4041

@@ -51,6 +52,7 @@ public static Command CreateFormatCommand()
5152
CompilationErrorsAsWarningsOption
5253
);
5354
var configPath = context.ParseResult.GetValueForOption(ConfigPathOption);
55+
var ignorePath = context.ParseResult.GetValueForOption(IgnorePathOption);
5456
var logLevel = context.ParseResult.GetValueForOption(LogLevelOption);
5557
var logFormat = context.ParseResult.GetValueForOption(LogFormatOption);
5658
var token = context.GetCancellationToken();
@@ -66,6 +68,7 @@ public static Command CreateFormatCommand()
6668
includeGenerated,
6769
compilationErrorsAsWarnings,
6870
configPath,
71+
ignorePath,
6972
logLevel,
7073
logFormat,
7174
token
@@ -84,6 +87,7 @@ public static Command CreateCheckCommand()
8487
var directoryOrFileArgument = AddDirectoryOrFileArgument(checkCommand);
8588

8689
checkCommand.AddOption(ConfigPathOption);
90+
checkCommand.AddOption(IgnorePathOption);
8791
checkCommand.AddOption(LogFormatOption);
8892
checkCommand.AddOption(LogLevelOption);
8993
checkCommand.AddOption(IncludeGeneratedOption);
@@ -99,6 +103,7 @@ public static Command CreateCheckCommand()
99103
CompilationErrorsAsWarningsOption
100104
);
101105
var configPath = context.ParseResult.GetValueForOption(ConfigPathOption);
106+
var ignorePath = context.ParseResult.GetValueForOption(IgnorePathOption);
102107
var logLevel = context.ParseResult.GetValueForOption(LogLevelOption);
103108
var logFormat = context.ParseResult.GetValueForOption(LogFormatOption);
104109
var token = context.GetCancellationToken();
@@ -114,6 +119,7 @@ public static Command CreateCheckCommand()
114119
includeGenerated,
115120
compilationErrorsAsWarnings,
116121
configPath,
122+
ignorePath,
117123
logLevel,
118124
logFormat,
119125
token
@@ -134,6 +140,7 @@ private static async Task<int> FormatOrCheck(
134140
bool includeGenerated,
135141
bool compilationErrorsAsWarnings,
136142
string? configPath,
143+
string? ignorePath,
137144
LogLevel logLevel,
138145
LogFormat logFormat,
139146
CancellationToken cancellationToken
@@ -179,6 +186,7 @@ CancellationToken cancellationToken
179186
WriteStdout = writeStdout || standardInFileContents != null,
180187
IncludeGenerated = includeGenerated,
181188
ConfigPath = configPath,
189+
IgnorePath = ignorePath,
182190
CompilationErrorsAsWarnings = compilationErrorsAsWarnings,
183191
LogFormat = logFormat,
184192
};
@@ -218,6 +226,11 @@ private static Argument<string[]> AddDirectoryOrFileArgument(Command command)
218226
"Path to the CSharpier configuration file"
219227
);
220228

229+
private static readonly Option<string> IgnorePathOption = new(
230+
["--ignore-path"],
231+
"Path to the CSharpier ignore file"
232+
);
233+
221234
private static readonly Option<LogFormat> LogFormatOption = new(
222235
["--log-format"],
223236
() => LogFormat.Console,

Src/CSharpier.Cli/IgnoreFile.cs

Lines changed: 45 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System.Diagnostics;
12
using System.IO.Abstractions;
23
using System.Text.RegularExpressions;
34
using CSharpier.Core;
@@ -49,46 +50,61 @@ public bool IsIgnored(string filePath)
4950
public static async Task<IgnoreFile?> CreateAsync(
5051
string baseDirectoryPath,
5152
IFileSystem fileSystem,
53+
string? ignorePath,
5254
CancellationToken cancellationToken
5355
)
5456
{
57+
async Task<IgnoreWithBasePath> CreateIgnore(string ignoreFilePath, string? overrideBasePath)
58+
{
59+
var ignore = new IgnoreWithBasePath(
60+
overrideBasePath ?? Path.GetDirectoryName(ignoreFilePath)!
61+
);
62+
AddDefaultRules(ignore);
63+
64+
var content = await fileSystem.File.ReadAllTextAsync(ignoreFilePath, cancellationToken);
65+
66+
var (positives, negatives) = GitignoreParserNet.GitignoreParser.Parse(content, true);
67+
68+
ignore.AddPositives(positives.Merged);
69+
ignore.AddNegatives(negatives.Merged);
70+
71+
return ignore;
72+
}
73+
5574
return await SharedFunc<IgnoreFile?>
5675
.GetOrAddAsync(
5776
baseDirectoryPath,
5877
async () =>
5978
{
6079
DebugLogger.Log("Creating ignore file for " + baseDirectoryPath);
61-
var ignoreFilePaths = FindIgnorePaths(baseDirectoryPath, fileSystem);
62-
if (ignoreFilePaths.Count == 0)
80+
if (ignorePath is not null)
6381
{
64-
var ignore = new IgnoreWithBasePath(baseDirectoryPath);
65-
AddDefaultRules(ignore);
66-
return new IgnoreFile([ignore]);
67-
}
82+
if (!fileSystem.File.Exists(ignorePath))
83+
{
84+
throw new Exception("There was no ignore file found at " + ignorePath);
85+
}
6886

69-
var ignores = new List<IgnoreWithBasePath>();
70-
foreach (var ignoreFilePath in ignoreFilePaths)
87+
DebugLogger.Log("Using ignorePath: " + ignorePath);
88+
return new IgnoreFile([await CreateIgnore(ignorePath, baseDirectoryPath)]);
89+
}
90+
else
7191
{
72-
var ignore = new IgnoreWithBasePath(Path.GetDirectoryName(ignoreFilePath)!);
73-
AddDefaultRules(ignore);
74-
75-
var content = await fileSystem.File.ReadAllTextAsync(
76-
ignoreFilePath,
77-
cancellationToken
78-
);
79-
80-
var (positives, negatives) = GitignoreParserNet.GitignoreParser.Parse(
81-
content,
82-
true
83-
);
84-
85-
ignore.AddPositives(positives.Merged);
86-
ignore.AddNegatives(negatives.Merged);
87-
88-
ignores.Add(ignore);
92+
var ignoreFilePaths = FindIgnorePaths(baseDirectoryPath, fileSystem);
93+
if (ignoreFilePaths.Count == 0)
94+
{
95+
var ignore = new IgnoreWithBasePath(baseDirectoryPath);
96+
AddDefaultRules(ignore);
97+
return new IgnoreFile([ignore]);
98+
}
99+
100+
var ignores = new List<IgnoreWithBasePath>();
101+
foreach (var ignoreFilePath in ignoreFilePaths)
102+
{
103+
ignores.Add(await CreateIgnore(ignoreFilePath, null));
104+
}
105+
106+
return new IgnoreFile(ignores);
89107
}
90-
91-
return new IgnoreFile(ignores);
92108
},
93109
cancellationToken
94110
)
@@ -164,6 +180,8 @@ private class IgnoreWithBasePath(string basePath)
164180

165181
public (bool hasMatchingRule, bool isIgnored) IsIgnored(string path)
166182
{
183+
DebugLogger.Log("path: " + path);
184+
DebugLogger.Log("basePath: " + basePath);
167185
if (!path.StartsWith(basePath, StringComparison.Ordinal))
168186
{
169187
return (false, false);

Src/CSharpier.Cli/Options/OptionsProvider.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ ILogger logger
3737
public static async Task<OptionsProvider> Create(
3838
string directoryName,
3939
string? configPath,
40+
string? ignorePath,
4041
IFileSystem fileSystem,
4142
ILogger logger,
4243
CancellationToken cancellationToken
@@ -55,7 +56,12 @@ CancellationToken cancellationToken
5556
? CSharpierConfigParser.Create(csharpierConfigPath, fileSystem, logger)
5657
: null;
5758

58-
var ignoreFile = await IgnoreFile.CreateAsync(directoryName, fileSystem, cancellationToken);
59+
var ignoreFile = await IgnoreFile.CreateAsync(
60+
directoryName,
61+
fileSystem,
62+
ignorePath,
63+
cancellationToken
64+
);
5965

6066
if (ignoreFile is null)
6167
{
@@ -196,7 +202,7 @@ CancellationToken cancellationToken
196202
Path.Combine(searchingDirectory, ".csharpierignore")
197203
),
198204
(searchingDirectory) =>
199-
IgnoreFile.CreateAsync(searchingDirectory, this.fileSystem, cancellationToken)
205+
IgnoreFile.CreateAsync(searchingDirectory, this.fileSystem, null, cancellationToken)
200206
);
201207

202208
if (ignoreFile is null)

Src/CSharpier.Cli/Server/CSharpierServiceImplementation.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ CancellationToken cancellationToken
4545
var optionsProvider = await OptionsProvider.Create(
4646
directoryName,
4747
configPath: null,
48+
ignorePath: null,
4849
this.fileSystem,
4950
logger,
5051
cancellationToken

Src/CSharpier.Tests/OptionsProviderTests.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -821,6 +821,7 @@ string filePath
821821
var provider = await OptionsProvider.Create(
822822
directoryName,
823823
null,
824+
null,
824825
this.fileSystem,
825826
NullLogger.Instance,
826827
CancellationToken.None

docs/CLI.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,16 @@ If a list of paths is not supplied, then stdin is read as a file, formatted and
3333
dotnet csharpier format . --config-path "./config/csharpier.yaml"
3434

3535
# allows passing in a path to an editorconfig
36-
dotnet csharpier . --config-path "./config/.editorconfig"
36+
dotnet csharpier format . --config-path "./config/.editorconfig"
3737
```
3838

39+
- `--ignore-path`
40+
41+
If your ignore file lives in a location that CSharpier would not normally resolve it (such as in a config folder)
42+
you can pass the path for the ignore file to CSharpier.
43+
```bash
44+
dotnet csharpier format . --ignore-path "./config/.csharpierignore"
45+
```
3946

4047
- `--log-format`
4148

0 commit comments

Comments
 (0)