Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ability to read --{in,ex}clude value from stdin #790

Merged
merged 1 commit into from Nov 9, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
32 changes: 19 additions & 13 deletions README.md
Expand Up @@ -85,19 +85,25 @@ Options:

Add `format` after `dotnet` and before the command arguments that you want to run:

| Examples | Description |
| ---------------------------------------------------------------- |---------------------------------------------------------------------------------------------- |
| dotnet **format** | Formats the project or solution in the current directory. |
| dotnet **format** <workspace> | Formats a specific project or solution. |
| dotnet **format** <workspace> -f | Formats a particular folder and subfolders. |
| dotnet **format** <workspace> --fix-style warn | Fixes only codestyle analyzer warnings. |
| dotnet **format** <workspace> --fix-whitespace --fix-style | Formats and fixes codestyle analyzer errors. |
| dotnet **format** <workspace> --fix-analyzers | Fixes only 3rd party analyzer errors. |
| dotnet **format** <workspace> -wsa | Formats, fixes codestyle errors, and fixes 3rd party analyzer errors. |
| dotnet **format** -v diag | Formats with very verbose logging. |
| dotnet **format** --include Programs.cs Utility\Logging.cs | Formats the files Program.cs and Utility\Logging.cs |
| dotnet **format** --check | Formats but does not save. Returns a non-zero exit code if any files would have been changed. |
| dotnet **format** --report <report-path> | Formats and saves a json report file to the given directory. |
| Examples | Description |
| ---------------------------------------------------------------- |--------------------------------------------------------------------------------------------------- |
| `dotnet format` | Formats the project or solution in the current directory. |
| `dotnet format <workspace>` | Formats a specific project or solution. |
| `dotnet format <workspace> -f` | Formats a particular folder and subfolders. |
| `dotnet format <workspace> --fix-style warn` | Fixes only codestyle analyzer warnings. |
| `dotnet format <workspace> --fix-whitespace --fix-style` | Formats and fixes codestyle analyzer errors. |
| `dotnet format <workspace> --fix-analyzers` | Fixes only 3rd party analyzer errors. |
| `dotnet format <workspace> -wsa | Formats, fixes codestyle errors, and fixes 3rd party analyzer errors. |
| `dotnet format -v diag` | Formats with very verbose logging. |
| `dotnet format --include Programs.cs Utility\Logging.cs` | Formats the files Program.cs and Utility\Logging.cs |
| `dotnet format --check` | Formats but does not save. Returns a non-zero exit code if any files would have been changed. |
| `dotnet format --report <report-path>` | Formats and saves a json report file to the given directory. |
| `dotnet format --include test/Utilities/*.cs --folder` | Formats the files expanded from native shell globbing (e.g. bash). Space-separated list of |
| | files are fed to formatter in this case. Also applies to `--exclude` option. |
| `dotnet format --include 'test/Utilities/*.cs' --folder` | With single quotes, formats the files expanded from built-in glob expansion. A single file |
| | pattern is fed to formatter, which gets expanded internally. Also applies to `--exclude` option. |
| `ls tests/Utilities/*.cs \| dotnet format --include - --folder` | Formats the list of files redirected from pipeline via standard input. Formatter will iterate over |
| | `Console.In` to read the list of files. Also applies to `--exclude` option. |

### How To Uninstall

Expand Down
52 changes: 52 additions & 0 deletions src/Program.cs
Expand Up @@ -7,6 +7,7 @@
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Tools.Logging;
Expand All @@ -24,6 +25,8 @@ internal class Program
internal const int UnableToLocateMSBuildExitCode = 3;
internal const int UnableToLocateDotNetCliExitCode = 4;

private static readonly string[] s_standardInputKeywords = { "/dev/stdin", "-" };

private static ParseResult? s_parseResult;

private static async Task<int> Main(string[] args)
Expand Down Expand Up @@ -148,6 +151,8 @@ private static async Task<int> Main(string[] args)
fixType |= FixCategory.Whitespace;
}

HandleStandardInput(logger, ref include, ref exclude);

var fileMatcher = SourceFileMatcher.CreateMatcher(include, exclude);

var formatOptions = new FormatOptions(
Expand Down Expand Up @@ -189,6 +194,53 @@ private static async Task<int> Main(string[] args)
}
}

private static void HandleStandardInput(ILogger logger, ref string[] include, ref string[] exclude)
{
var isStandardMarkerUsed = false;
if (include.Length == 1 && s_standardInputKeywords.Contains(include[0]))
{
if (TryReadFromStandardInput(ref include))
{
isStandardMarkerUsed = true;
}
}

if (exclude.Length == 1 && s_standardInputKeywords.Contains(exclude[0]))
{
if (isStandardMarkerUsed)
{
logger.LogCritical(Resources.Standard_input_used_multiple_times);
Environment.Exit(CheckFailedExitCode);
}

TryReadFromStandardInput(ref exclude);
}

static bool TryReadFromStandardInput(ref string[] subject)
{
if (!Console.IsInputRedirected)
{
return false; // pass
}

// reset the subject array
Array.Clear(subject, 0, subject.Length);
Array.Resize(ref subject, 0);

Console.InputEncoding = Encoding.UTF8;
using var reader = new StreamReader(Console.OpenStandardInput(8192));
Console.SetIn(reader);

for (var i = 0; Console.In.Peek() != -1; ++i)
{
Array.Resize(ref subject, subject.Length + 1);
subject[i] = Console.In.ReadLine();
}

return true;
}
}

internal static int GetExitCode(WorkspaceFormatResult formatResult, bool check)
{
if (!check)
Expand Down
3 changes: 3 additions & 0 deletions src/Resources.resx
Expand Up @@ -222,6 +222,9 @@
<data name="Include_generated_code_files_in_formatting_operations" xml:space="preserve">
<value>Include generated code files in formatting operations.</value>
</data>
<data name="Standard_input_used_multiple_times" xml:space="preserve">
<value>Standard input markers ('/dev/stdin', '-') can only be used either with `--include` or `--exclude`, but not both.</value>
</data>
<data name="Unable_to_locate_dotnet_CLI_Ensure_that_it_is_on_the_PATH" xml:space="preserve">
<value>Unable to locate dotnet CLI. Ensure that it is on the PATH.</value>
</data>
Expand Down
5 changes: 5 additions & 0 deletions src/xlf/Resources.cs.xlf
Expand Up @@ -207,6 +207,11 @@
<target state="translated">Řešení {0} nemá žádné projekty.</target>
<note />
</trans-unit>
<trans-unit id="Standard_input_used_multiple_times">
<source>Standard input markers ('/dev/stdin', '-') can only be used either with `--include` or `--exclude`, but not both.</source>
<target state="new">Standard input markers ('/dev/stdin', '-') can only be used either with `--include` or `--exclude`, but not both.</target>
<note />
</trans-unit>
<trans-unit id="The_dotnet_CLI_version_is_0">
<source>The dotnet CLI version is '{0}'.</source>
<target state="translated">Verze .NET CLI je {0}.</target>
Expand Down
5 changes: 5 additions & 0 deletions src/xlf/Resources.de.xlf
Expand Up @@ -207,6 +207,11 @@
<target state="translated">Die Projektmappe "{0}" enthält keine Projekte.</target>
<note />
</trans-unit>
<trans-unit id="Standard_input_used_multiple_times">
<source>Standard input markers ('/dev/stdin', '-') can only be used either with `--include` or `--exclude`, but not both.</source>
<target state="new">Standard input markers ('/dev/stdin', '-') can only be used either with `--include` or `--exclude`, but not both.</target>
<note />
</trans-unit>
<trans-unit id="The_dotnet_CLI_version_is_0">
<source>The dotnet CLI version is '{0}'.</source>
<target state="translated">Die dotnet-CLI-Version ist "{0}".</target>
Expand Down
5 changes: 5 additions & 0 deletions src/xlf/Resources.es.xlf
Expand Up @@ -207,6 +207,11 @@
<target state="translated">La solución {0} no tiene ningún proyecto.</target>
<note />
</trans-unit>
<trans-unit id="Standard_input_used_multiple_times">
<source>Standard input markers ('/dev/stdin', '-') can only be used either with `--include` or `--exclude`, but not both.</source>
<target state="new">Standard input markers ('/dev/stdin', '-') can only be used either with `--include` or `--exclude`, but not both.</target>
<note />
</trans-unit>
<trans-unit id="The_dotnet_CLI_version_is_0">
<source>The dotnet CLI version is '{0}'.</source>
<target state="translated">La versión de la CLI de dotnet es "{0}".</target>
Expand Down
5 changes: 5 additions & 0 deletions src/xlf/Resources.fr.xlf
Expand Up @@ -207,6 +207,11 @@
<target state="translated">La solution {0} n'a aucun projet</target>
<note />
</trans-unit>
<trans-unit id="Standard_input_used_multiple_times">
<source>Standard input markers ('/dev/stdin', '-') can only be used either with `--include` or `--exclude`, but not both.</source>
<target state="new">Standard input markers ('/dev/stdin', '-') can only be used either with `--include` or `--exclude`, but not both.</target>
<note />
</trans-unit>
<trans-unit id="The_dotnet_CLI_version_is_0">
<source>The dotnet CLI version is '{0}'.</source>
<target state="translated">La version de l'interface CLI dotnet est '{0}'.</target>
Expand Down
5 changes: 5 additions & 0 deletions src/xlf/Resources.it.xlf
Expand Up @@ -207,6 +207,11 @@
<target state="translated">La soluzione {0} non contiene progetti</target>
<note />
</trans-unit>
<trans-unit id="Standard_input_used_multiple_times">
<source>Standard input markers ('/dev/stdin', '-') can only be used either with `--include` or `--exclude`, but not both.</source>
<target state="new">Standard input markers ('/dev/stdin', '-') can only be used either with `--include` or `--exclude`, but not both.</target>
<note />
</trans-unit>
<trans-unit id="The_dotnet_CLI_version_is_0">
<source>The dotnet CLI version is '{0}'.</source>
<target state="translated">La versione dell'interfaccia della riga di comando di dotnet è '{0}'.</target>
Expand Down
5 changes: 5 additions & 0 deletions src/xlf/Resources.ja.xlf
Expand Up @@ -207,6 +207,11 @@
<target state="translated">ソリューション {0} にプロジェクトがありません</target>
<note />
</trans-unit>
<trans-unit id="Standard_input_used_multiple_times">
<source>Standard input markers ('/dev/stdin', '-') can only be used either with `--include` or `--exclude`, but not both.</source>
<target state="new">Standard input markers ('/dev/stdin', '-') can only be used either with `--include` or `--exclude`, but not both.</target>
<note />
</trans-unit>
<trans-unit id="The_dotnet_CLI_version_is_0">
<source>The dotnet CLI version is '{0}'.</source>
<target state="translated">dotnet CLI バージョンは '{0}' です。</target>
Expand Down
5 changes: 5 additions & 0 deletions src/xlf/Resources.ko.xlf
Expand Up @@ -207,6 +207,11 @@
<target state="translated">{0} 솔루션에 프로젝트가 없습니다.</target>
<note />
</trans-unit>
<trans-unit id="Standard_input_used_multiple_times">
<source>Standard input markers ('/dev/stdin', '-') can only be used either with `--include` or `--exclude`, but not both.</source>
<target state="new">Standard input markers ('/dev/stdin', '-') can only be used either with `--include` or `--exclude`, but not both.</target>
<note />
</trans-unit>
<trans-unit id="The_dotnet_CLI_version_is_0">
<source>The dotnet CLI version is '{0}'.</source>
<target state="translated">dotnet CLI 버전은 '{0}'입니다.</target>
Expand Down
5 changes: 5 additions & 0 deletions src/xlf/Resources.pl.xlf
Expand Up @@ -207,6 +207,11 @@
<target state="translated">Rozwiązanie {0} nie zawiera projektów</target>
<note />
</trans-unit>
<trans-unit id="Standard_input_used_multiple_times">
<source>Standard input markers ('/dev/stdin', '-') can only be used either with `--include` or `--exclude`, but not both.</source>
<target state="new">Standard input markers ('/dev/stdin', '-') can only be used either with `--include` or `--exclude`, but not both.</target>
<note />
</trans-unit>
<trans-unit id="The_dotnet_CLI_version_is_0">
<source>The dotnet CLI version is '{0}'.</source>
<target state="translated">Wersja interfejsu wiersza polecenia dotnet to „{0}”.</target>
Expand Down
5 changes: 5 additions & 0 deletions src/xlf/Resources.pt-BR.xlf
Expand Up @@ -207,6 +207,11 @@
<target state="translated">A solução {0} não tem nenhum projeto</target>
<note />
</trans-unit>
<trans-unit id="Standard_input_used_multiple_times">
<source>Standard input markers ('/dev/stdin', '-') can only be used either with `--include` or `--exclude`, but not both.</source>
<target state="new">Standard input markers ('/dev/stdin', '-') can only be used either with `--include` or `--exclude`, but not both.</target>
<note />
</trans-unit>
<trans-unit id="The_dotnet_CLI_version_is_0">
<source>The dotnet CLI version is '{0}'.</source>
<target state="translated">A versão do CLI do dotnet é '{0}'.</target>
Expand Down
5 changes: 5 additions & 0 deletions src/xlf/Resources.ru.xlf
Expand Up @@ -207,6 +207,11 @@
<target state="translated">Решение {0} не содержит проектов.</target>
<note />
</trans-unit>
<trans-unit id="Standard_input_used_multiple_times">
<source>Standard input markers ('/dev/stdin', '-') can only be used either with `--include` or `--exclude`, but not both.</source>
<target state="new">Standard input markers ('/dev/stdin', '-') can only be used either with `--include` or `--exclude`, but not both.</target>
<note />
</trans-unit>
<trans-unit id="The_dotnet_CLI_version_is_0">
<source>The dotnet CLI version is '{0}'.</source>
<target state="translated">Версия CLI dotnet: "{0}".</target>
Expand Down
5 changes: 5 additions & 0 deletions src/xlf/Resources.tr.xlf
Expand Up @@ -207,6 +207,11 @@
<target state="translated">{0} çözümünde proje yok</target>
<note />
</trans-unit>
<trans-unit id="Standard_input_used_multiple_times">
<source>Standard input markers ('/dev/stdin', '-') can only be used either with `--include` or `--exclude`, but not both.</source>
<target state="new">Standard input markers ('/dev/stdin', '-') can only be used either with `--include` or `--exclude`, but not both.</target>
<note />
</trans-unit>
<trans-unit id="The_dotnet_CLI_version_is_0">
<source>The dotnet CLI version is '{0}'.</source>
<target state="translated">dotnet CLI sürümü: '{0}'.</target>
Expand Down
5 changes: 5 additions & 0 deletions src/xlf/Resources.zh-Hans.xlf
Expand Up @@ -207,6 +207,11 @@
<target state="translated">解决方案 {0} 不包含任何项目</target>
<note />
</trans-unit>
<trans-unit id="Standard_input_used_multiple_times">
<source>Standard input markers ('/dev/stdin', '-') can only be used either with `--include` or `--exclude`, but not both.</source>
<target state="new">Standard input markers ('/dev/stdin', '-') can only be used either with `--include` or `--exclude`, but not both.</target>
<note />
</trans-unit>
<trans-unit id="The_dotnet_CLI_version_is_0">
<source>The dotnet CLI version is '{0}'.</source>
<target state="translated">dotnet CLI 版本为“{0}”。</target>
Expand Down
5 changes: 5 additions & 0 deletions src/xlf/Resources.zh-Hant.xlf
Expand Up @@ -207,6 +207,11 @@
<target state="translated">解決方案 {0} 沒有任何專案</target>
<note />
</trans-unit>
<trans-unit id="Standard_input_used_multiple_times">
<source>Standard input markers ('/dev/stdin', '-') can only be used either with `--include` or `--exclude`, but not both.</source>
<target state="new">Standard input markers ('/dev/stdin', '-') can only be used either with `--include` or `--exclude`, but not both.</target>
<note />
</trans-unit>
<trans-unit id="The_dotnet_CLI_version_is_0">
<source>The dotnet CLI version is '{0}'.</source>
<target state="translated">dotnet CLI 版本為 '{0}'。</target>
Expand Down