Skip to content

Commit fdff7f8

Browse files
committed
Add proper CLI interface & add log output format option
The log output format will by default autodetect if it is currently running inside a Github Action / Workflow and adjust its output format to be readable as an annotation (see https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-commands-for-github-actions#setting-an-error-message ). This patch also introduces the -v (verbose) flag to get debugging logs etc. And the correct assembly version is now set to 0.1.3.0.
1 parent 8bc8b3a commit fdff7f8

File tree

4 files changed

+84
-38
lines changed

4 files changed

+84
-38
lines changed

NeoDoc.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@
4747
<Reference Include="System.Management" />
4848
<Reference Include="System.Transactions" />
4949
<Reference Include="System.Xml" />
50+
<Reference Include="CommandLine">
51+
<HintPath>packages\CommandLineParser.2.8.0\lib\net45\CommandLine.dll</HintPath>
52+
</Reference>
5053
</ItemGroup>
5154
<ItemGroup>
5255
<Compile Include="Program.cs" />

Program.cs

Lines changed: 78 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using NeoDoc.Langs;
33
using NeoDoc.Params;
44
using Newtonsoft.Json;
5+
using CommandLine;
56
using System;
67
using System.Collections.Generic;
78
using System.IO;
@@ -16,13 +17,13 @@ namespace NeoDoc
1617
{
1718
internal static class NeoDoc
1819
{
19-
public const bool DEBUGGING = false;
20-
public static int Progress = 0;
20+
public static bool DEBUGGING;
21+
public static int Progress;
2122
public static string NEWDIR = "";
23+
public static string ErrorLogFormat = "auto";
2224

2325
public enum ERROR_CODES: int
2426
{
25-
INVALID_COMMAND_LINE = 1,
2627
BAD_ARGUMENTS = 2,
2728
NOT_EXISTS = 3,
2829
MISSING_ESSENTIAL_PARAMS = 4,
@@ -43,38 +44,44 @@ public static void Empty(this DirectoryInfo directory)
4344
subDirectory.Delete(true);
4445
}
4546

46-
public static int Main()
47-
{
48-
string[] args = Environment.GetCommandLineArgs();
47+
public class Options
48+
{
49+
[Option('f', "format", Default = "auto", Required = false, HelpText = "Choose a log message format (auto, standard, github).")]
50+
public string LogFormat { get; set; }
4951

50-
if (args.Length == 1)
51-
{
52-
Console.Error.WriteLine("Invalid command line (missing folder path)!");
52+
[Option('v', "verbose", Default = false, Required = false, HelpText = "Should the output be more verbose and contain debugging logs?")]
53+
public bool Verbose { get; set; }
5354

54-
return (int)ERROR_CODES.INVALID_COMMAND_LINE;
55-
}
55+
[Value(0, Required = true, HelpText = "The source folder to check and read files from.")]
56+
public string Folder { get; set; }
5657

57-
string folder = args[1];
58-
59-
if (string.IsNullOrEmpty(folder))
60-
{
61-
Console.Error.WriteLine("Provided folder path is null or empty!");
58+
[Value(1, HelpText = "Set this to a path and you will generate json output (usually used by external applications such as NeoVis).")]
59+
public string OutputFolder { get; set; }
60+
}
6261

63-
return (int)ERROR_CODES.BAD_ARGUMENTS;
64-
}
62+
public static int Main(string[] args)
63+
{
64+
return Parser.Default.ParseArguments<Options>(args)
65+
.MapResult(
66+
Run,
67+
error => (int) ERROR_CODES.BAD_ARGUMENTS
68+
);
69+
}
6570

66-
if (!Directory.Exists(folder))
67-
{
68-
Console.Error.WriteLine("Provided folder '" + folder + "' does not exists!");
71+
public static int Run(Options options) {
72+
NEWDIR = options.OutputFolder;
73+
ErrorLogFormat = options.LogFormat;
74+
DEBUGGING = options.Verbose;
6975

70-
return (int)ERROR_CODES.NOT_EXISTS;
71-
}
76+
if (!Directory.Exists(options.Folder))
77+
{
78+
Console.Error.WriteLine("Provided folder '" + options.Folder + "' does not exists!");
7279

73-
if (args.Length > 2)
74-
NEWDIR = args[2];
80+
return (int) ERROR_CODES.NOT_EXISTS;
81+
}
7582

76-
// Build the file tree
77-
string[] files = Directory.GetFiles(folder, "*.*", SearchOption.AllDirectories);
83+
// Build the file tree
84+
string[] files = Directory.GetFiles(options.Folder, "*.*", SearchOption.AllDirectories);
7885

7986
// Prepare the files
8087
List<FileParser> fileParsers = new List<FileParser>();
@@ -87,7 +94,7 @@ public static int Main()
8794
{
8895
string file = files[n];
8996

90-
string relPath = file.Remove(0, folder.Length);
97+
string relPath = file.Remove(0, options.Folder.Length);
9198
relPath = relPath.TrimStart('\\');
9299
relPath = relPath.Replace('\\', '/');
93100

@@ -144,11 +151,8 @@ public static int Main()
144151
return Environment.ExitCode;
145152
}
146153

147-
#pragma warning disable IDE0060 // Nicht verwendete Parameter entfernen
148154
internal static void WriteDebugInfo(string debugInfo)
149-
#pragma warning restore IDE0060 // Nicht verwendete Parameter entfernen
150155
{
151-
#pragma warning disable CS0162 // Unerreichbarer Code wurde entdeckt.
152156
if (!DEBUGGING)
153157
return;
154158

@@ -159,10 +163,9 @@ internal static void WriteDebugInfo(string debugInfo)
159163
Console.Out.WriteLine(debugInfo);
160164

161165
Console.ForegroundColor = oldColor;
162-
#pragma warning restore CS0162 // Unerreichbarer Code wurde entdeckt.
163166
}
164167

165-
internal static void WriteErrors(string title, List<string> errors, string relPath, int? foundLine, int? exitCode)
168+
internal static void WriteErrors(string message, List<string> errors, string relPath, int? foundLine, int? exitCode)
166169
{
167170
if (exitCode != null)
168171
Environment.ExitCode = (int)exitCode;
@@ -173,17 +176,56 @@ internal static void WriteErrors(string title, List<string> errors, string relPa
173176

174177
TextWriter textWriter = Console.Error;
175178

179+
textWriter.WriteLine(formatLogMessage(message, errors, relPath, foundLine, exitCode));
180+
181+
Console.ForegroundColor = oldColor;
182+
}
183+
184+
private static string formatLogMessage(string message, List<string> errors, string relPath, int? foundLine, int? exitCode) {
185+
switch (ErrorLogFormat) {
186+
case "auto":
187+
if (System.Environment.GetEnvironmentVariable("GITHUB_ACTIONS") != null && System.Environment.GetEnvironmentVariable("GITHUB_WORKFLOW") != null) {
188+
return formatGithub(message, errors, relPath, foundLine, exitCode);
189+
}
190+
return formatStandard(message, errors, relPath, foundLine, exitCode);
191+
case "standard":
192+
return formatStandard(message, errors, relPath, foundLine, exitCode);
193+
case "github":
194+
return formatGithub(message, errors, relPath, foundLine, exitCode);
195+
default:
196+
Console.Error.WriteLine("Could not understand the given format param, falling back to mode: standard");
197+
return formatStandard(message, errors, relPath, foundLine, exitCode);
198+
}
199+
}
200+
201+
private static string formatStandard(string message, List<string> errors, string relPath, int? foundLine, int? exitCode) {
176202
StringBuilder errorBuilder = new StringBuilder();
177203

178-
errorBuilder.AppendLine("Error " + (exitCode != null ? ((int)exitCode).ToString() : "???") + ": " + (relPath ?? "?") + ": [Warning] line " + (foundLine != null ? ((int)foundLine).ToString() : "?") + ": " + title);
204+
errorBuilder.AppendLine("Error " + (exitCode != null ? ((int)exitCode).ToString() : "???") + ": " + (relPath ?? "?") + ": [Warning] line " + (foundLine != null ? ((int)foundLine).ToString() : "?") + ": " + message);
179205

180206
if (errors != null)
181207
foreach (string error in errors)
182208
errorBuilder.AppendLine(error);
209+
210+
return errorBuilder.ToString();
211+
}
183212

184-
textWriter.WriteLine(errorBuilder.ToString());
213+
private static string formatGithub(string message, List<string> errors, string relPath, int? foundLine, int? exitCode) {
214+
string output = "::error ";
215+
216+
output += "file=" + (relPath ?? "?") + ",";
217+
output += "line=" + (foundLine != null ? ((int)foundLine).ToString() : "?");
218+
output += "::";
219+
output += "Code (" + (exitCode != null ? ((int)exitCode).ToString() : "???") + ") ";
220+
output += message + "\\n";
185221

186-
Console.ForegroundColor = oldColor;
222+
if (errors != null)
223+
output += "Errors: \\n";
224+
foreach (string error in errors)
225+
output += error + "\\n";
226+
227+
// Also output human readable format for the log files
228+
return output + "\n" + formatStandard(message, errors, relPath, foundLine, exitCode);
187229
}
188230

189231
private static WrapperParam[] ProcessFileParsers(List<FileParser> fileParsers, out SortedDictionary<string, SortedDictionary<string, List<DataStructure>>> globalsDict)

Properties/AssemblyInfo.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,15 @@
99
[assembly: AssemblyConfiguration("")]
1010
[assembly: AssemblyCompany("")]
1111
[assembly: AssemblyProduct("")]
12-
[assembly: AssemblyCopyright("${AuthorCopyright}")]
12+
[assembly: AssemblyCopyright("GNU General Public License v3.0 - see LICENSE file")]
1313
[assembly: AssemblyTrademark("")]
1414
[assembly: AssemblyCulture("")]
1515

1616
// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
1717
// The form "{Major}.{Minor}.*" will automatically update the build and revision,
1818
// and "{Major}.{Minor}.{Build}.*" will update just the revision.
1919

20-
[assembly: AssemblyVersion("1.0.*")]
20+
[assembly: AssemblyVersion("0.1.3.0")]
2121

2222
// The following attributes are used to specify the signing key for the assembly,
2323
// if desired. See the Mono documentation for more information about signing.

packages.config

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<packages>
3+
<package id="CommandLineParser" version="2.8.0" targetFramework="net472" />
34
<package id="Newtonsoft.Json" version="12.0.3" targetFramework="net472" />
45
</packages>

0 commit comments

Comments
 (0)