Skip to content

Commit 7446318

Browse files
authored
Miscellaneous fixes (#174)
* Fix for #134 * Improves the build output reporting for Packrules command and provides location of log file to console output. Consolidates rules verification into a single class, improves json simple tags output, updates help.
1 parent 552fc76 commit 7446318

25 files changed

+898
-646
lines changed

AppInspector.CLI/Program.cs

Lines changed: 27 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,8 @@
44
using CommandLine;
55
using Microsoft.ApplicationInspector.Commands;
66
using NLog;
7-
using NLog.Config;
8-
using NLog.Targets;
97
using System;
10-
using System.IO;
8+
119

1210

1311
namespace Microsoft.ApplicationInspector.CLI
@@ -52,7 +50,7 @@ static int Main(string[] args)
5250
{
5351
if (Logger != null)
5452
{
55-
WriteOnce.Error(ErrMsg.FormatString(ErrMsg.ID.RUNTIME_ERROR_NAMED, e.Message));
53+
WriteOnce.Error(ErrMsg.FormatString(ErrMsg.ID.RUNTIME_ERROR_NAMED, e.Message, Utils.LogFilePath));
5654
Logger.Error($"Runtime error: {e.StackTrace}");
5755
}
5856
else
@@ -62,7 +60,7 @@ static int Main(string[] args)
6260
{
6361
if (Logger != null)
6462
{
65-
WriteOnce.Error(ErrMsg.FormatString(ErrMsg.ID.RUNTIME_ERROR_UNNAMED));
63+
WriteOnce.Error(ErrMsg.FormatString(ErrMsg.ID.RUNTIME_ERROR_UNNAMED, Utils.LogFilePath));
6664
Logger.Error($"Runtime error: {e.Message} {e.StackTrace}");
6765
}
6866
else
@@ -75,83 +73,59 @@ static int Main(string[] args)
7573

7674
private static int RunAnalyzeCommand(AnalyzeCommandOptions opts)
7775
{
78-
SetupLogging(opts);
76+
Logger = Utils.SetupLogging(opts);
77+
WriteOnce.Log = Logger;
78+
opts.Log = Logger;
79+
7980
return new AnalyzeCommand(opts).Run();
8081
}
8182

8283
private static int RunTagDiffCommand(TagDiffCommandOptions opts)
8384
{
84-
SetupLogging(opts);
85+
Logger = Utils.SetupLogging(opts);
86+
WriteOnce.Log = Logger;
87+
opts.Log = Logger;
88+
8589
return new TagDiffCommand(opts).Run();
8690
}
8791

8892
private static int RunTagTestCommand(TagTestCommandOptions opts)
8993
{
90-
SetupLogging(opts);
94+
Logger = Utils.SetupLogging(opts);
95+
WriteOnce.Log = Logger;
96+
opts.Log = Logger;
97+
9198
return new TagTestCommand(opts).Run();
9299
}
93100

94101
private static int RunExportTagsCommand(ExportTagsCommandOptions opts)
95102
{
96-
SetupLogging(opts);
103+
Logger = Utils.SetupLogging(opts);
104+
WriteOnce.Log = Logger;
105+
opts.Log = Logger;
106+
97107
return new ExportTagsCommand(opts).Run();
98108
}
99109

100110
private static int RunVerifyRulesCommand(VerifyRulesCommandOptions opts)
101111
{
102-
SetupLogging(opts);
112+
Logger = Utils.SetupLogging(opts);
113+
WriteOnce.Log = Logger;
114+
opts.Log = Logger;
115+
103116
return new VerifyRulesCommand(opts).Run();
104117
}
105118

106119

107120
private static int RunPackRulesCommand(PackRulesCommandOptions opts)
108121
{
109-
SetupLogging(opts);
122+
Logger = Utils.SetupLogging(opts);
123+
WriteOnce.Log = Logger;
124+
opts.Log = Logger;
125+
110126
return new PackRulesCommand(opts).Run();
111127
}
112128

113-
static void SetupLogging(AllCommandOptions opts)
114-
{
115-
var config = new NLog.Config.LoggingConfiguration();
116-
117-
if (String.IsNullOrEmpty(opts.LogFilePath))
118-
{
119-
opts.LogFilePath = Utils.GetPath(Utils.AppPath.defaultLog);
120-
//if using default app log path clean up previous for convenience in reading
121-
if (File.Exists(opts.LogFilePath))
122-
File.Delete(opts.LogFilePath);
123-
}
124-
125-
LogLevel log_level = LogLevel.Error;//default
126-
try
127-
{
128-
log_level = LogLevel.FromString(opts.LogFileLevel);
129-
}
130-
catch (Exception)
131-
{
132-
throw new OpException(String.Format(ErrMsg.FormatString(ErrMsg.ID.CMD_INVALID_ARG_VALUE, "-v")));
133-
}
134-
135-
using (var fileTarget = new FileTarget()
136-
{
137-
Name = "LogFile",
138-
FileName = opts.LogFilePath,
139-
Layout = @"${date:universalTime=true:format=s} ${threadid} ${level:uppercase=true} - ${message}",
140-
ForceMutexConcurrentWrites = true
141-
142-
})
143-
{
144-
config.AddTarget(fileTarget);
145-
config.LoggingRules.Add(new LoggingRule("*", log_level, fileTarget));
146-
}
147-
148-
LogManager.Configuration = config;
149-
opts.Log = LogManager.GetCurrentClassLogger();
150-
Logger = opts.Log;
151-
Logger.Info("[" + DateTime.Now.ToLocalTime() + "] //////////////////////////////////////////////////////////");
152-
WriteOnce.Log = Logger;//allows log to be written to as well as console or output file
153-
154-
}
155129

156130
}
157131
}

AppInspector/AppInspector.Commands.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,9 @@
8787
<None Include="..\icon-128.png" Pack="true" PackagePath="" />
8888
</ItemGroup>
8989

90+
9091
<Target Name="PreBuild" BeforeTargets="BeforeCompile">
9192
<MakeDir Directories="Resources" />
9293
<Exec Command="dotnet ../RulesPacker/ApplicationInspector.CLI.dll packrules -r rules/default -o Resources/defaultRules.json" />
9394
</Target>
94-
9595
</Project>

AppInspector/Commands/AllCommandOptions.cs

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@ public class AllCommandOptions
2323
[Verb("analyze", HelpText = "Inspect source directory/file/compressed file (.tgz|zip) against defined characteristics")]
2424
public class AnalyzeCommandOptions : AllCommandOptions
2525
{
26-
[Option('s', "source-path", Required = true, HelpText = "Path to source code to inspect (required)")]
26+
[Option('s', "source-path", Required = true, HelpText = "Source file or directory to inspect")]
2727
public string SourcePath { get; set; }
2828

29-
[Option('o', "output-file-path", Required = false, HelpText = "Path to output file")]
29+
[Option('o', "output-file-path", Required = false, HelpText = "Output file path")]
3030
public string OutputFilePath { get; set; }
3131

3232
[Option('f', "output-file-format", Required = false, HelpText = "Output format [html|json|text]", Default = "html")]
@@ -35,7 +35,7 @@ public class AnalyzeCommandOptions : AllCommandOptions
3535
[Option('e', "text-format", Required = false, HelpText = "Match text format specifiers", Default = "Tag:%T,Rule:%N,Ruleid:%R,Confidence:%X,File:%F,Sourcetype:%t,Line:%L,Sample:%m")]
3636
public string TextOutputFormat { get; set; }
3737

38-
[Option('r', "custom-rules-path", Required = false, HelpText = "Custom rules path")]
38+
[Option('r', "custom-rules-path", Required = false, HelpText = "Custom rules file or directory path")]
3939
public string CustomRulesPath { get; set; }
4040

4141
[Option('t', "tag-output-only", Required = false, HelpText = "Output only identified tags", Default = false)]
@@ -47,7 +47,7 @@ public class AnalyzeCommandOptions : AllCommandOptions
4747
[Option('d', "allow-dup-tags", Required = false, HelpText = "Output contains unique and non-unique tag matches", Default = false)]
4848
public bool AllowDupTags { get; set; }
4949

50-
[Option('b', "supress-browser-open", Required = false, HelpText = "HTML formatted output is automatically opened to default browser", Default = false)]
50+
[Option('b', "suppress-browser-open", Required = false, HelpText = "Suppress automatic open to HTML output using default browser", Default = false)]
5151
public bool AutoBrowserOpen { get; set; }
5252

5353
[Option('c', "confidence-filters", Required = false, HelpText = "Output only matches with specified confidence <value>,<value> [high|medium|low]", Default = "high,medium")]
@@ -65,59 +65,60 @@ public class AnalyzeCommandOptions : AllCommandOptions
6565
[Verb("tagdiff", HelpText = "Compares unique tag values between two source paths")]
6666
public class TagDiffCommandOptions : AllCommandOptions
6767
{
68-
[Option("src1", Required = true, HelpText = "Source 1 to compare (required)")]
68+
[Option("src1", Required = true, HelpText = "Source 1 to compare")]
6969
public string SourcePath1 { get; set; }
7070

71-
[Option("src2", Required = true, HelpText = "Source 2 to compare (required")]
71+
[Option("src2", Required = true, HelpText = "Source 2 to compare")]
7272
public string SourcePath2 { get; set; }
7373

7474
[Option('t', "test-type", Required = false, HelpText = "Type of test to run [equality|inequality]", Default = "equality")]
7575
public string TestType { get; set; }
7676

77-
[Option('r', "custom-rules-path", Required = false, HelpText = "Custom rules path")]
77+
[Option('r', "custom-rules-path", Required = false, HelpText = "Custom rules file or directory path")]
7878
public string CustomRulesPath { get; set; }
7979

8080
[Option('i', "ignore-default-rules", Required = false, HelpText = "Exclude default rules bundled with application", Default = false)]
8181
public bool IgnoreDefaultRules { get; set; }
8282

83-
[Option('o', "output-file-path", Required = false, HelpText = "Path to output file")]
83+
[Option('o', "output-file-path", Required = false, HelpText = "Output file path")]
8484
public string OutputFilePath { get; set; }
8585

8686
[Option('x', "console-verbosity", Required = false, HelpText = "Console verbosity [high|medium|low|none]", Default = "medium")]
8787
public string ConsoleVerbosityLevel { get; set; }
8888

8989
}
9090

91-
[Verb("tagtest", HelpText = "Test presence of smaller set or custom tags in source (compare or verify modes)")]
91+
92+
[Verb("tagtest", HelpText = "Test (T/F) for presence of custom rule set in source")]
9293
public class TagTestCommandOptions : AllCommandOptions
9394
{
94-
[Option('s', "source-path", Required = true, HelpText = "Source to test (required)")]
95+
[Option('s', "source-path", Required = true, HelpText = "Source file or directory to inspect")]
9596
public string SourcePath { get; set; }
9697

9798
[Option('t', "test-type", Required = false, HelpText = "Test to perform [rulespresent|rulesnotpresent] ", Default = "rulespresent")]
9899
public string TestType { get; set; }
99100

100-
[Option('r', "custom-rules-path", Required = false, HelpText = "Custom rules path")]
101+
[Option('r', "custom-rules-path", Required = false, HelpText = "Custom rules file or directory path")]
101102
public string CustomRulesPath { get; set; }
102103

103-
[Option('o', "output-file-path", Required = false, HelpText = "Path to output file")]
104+
[Option('o', "output-file-path", Required = false, HelpText = "Output file path")]
104105
public string OutputFilePath { get; set; }
105106

106107
[Option('x', "console-verbosity", Required = false, HelpText = "Console verbosity [high|medium|low|none]", Default = "medium")]
107108
public string ConsoleVerbosityLevel { get; set; }
108109

109110
}
110111

111-
[Verb("exporttags", HelpText = "Export default unique rule tags to view what features may be detected")]
112+
[Verb("exporttags", HelpText = "Export unique rule tags to view what code features may be detected")]
112113
public class ExportTagsCommandOptions : AllCommandOptions
113114
{
114-
[Option('r', "custom-rules-path", Required = false, HelpText = "Custom rules path")]
115+
[Option('r', "custom-rules-path", Required = false, HelpText = "Custom rules file or directory path")]
115116
public string CustomRulesPath { get; set; }
116117

117118
[Option('i', "ignore-default-rules", Required = false, HelpText = "Exclude default rules bundled with application", Default = false)]
118119
public bool IgnoreDefaultRules { get; set; }
119120

120-
[Option('o', "output-file-path", Required = false, HelpText = "Path to output file")]
121+
[Option('o', "output-file-path", Required = false, HelpText = "Output file path")]
121122
public string OutputFilePath { get; set; }
122123

123124
[Option('x', "console-verbosity", Required = false, HelpText = "Console verbosity [high|medium|low|none]", Default = "medium")]
@@ -128,10 +129,10 @@ public class ExportTagsCommandOptions : AllCommandOptions
128129
[Verb("verifyrules", HelpText = "Verify custom rules syntax is valid")]
129130
public class VerifyRulesCommandOptions : AllCommandOptions
130131
{
131-
[Option('r', "custom-rules-path", Required = false, HelpText = "Custom rules path")]
132+
[Option('r', "custom-rules-path", Required = false, HelpText = "Custom rules file or directory path")]
132133
public string CustomRulesPath { get; set; }
133134

134-
[Option('o', "output-file-path", Required = false, HelpText = "Path to output file")]
135+
[Option('o', "output-file-path", Required = false, HelpText = "Output file path")]
135136
public string OutputFilePath { get; set; }
136137

137138
[Option('x', "console-verbosity", Required = false, HelpText = "Console verbosity [high|medium|low|none]", Default = "medium")]
@@ -140,16 +141,16 @@ public class VerifyRulesCommandOptions : AllCommandOptions
140141

141142
}
142143

143-
[Verb("packrules", HelpText = "Combine multiple rules into one file for ease in distribution")]
144+
[Verb("packrules", HelpText = "Combine multiple rule files into one file for ease in distribution")]
144145
public class PackRulesCommandOptions : AllCommandOptions
145146
{
146-
[Option('d', "pack-default-rules", Required = false, HelpText = "Repack default rules")]
147+
[Option('d', "pack-default-rules", Required = false, HelpText = "Repack default rules. Automatic on Application Inspector build")]
147148
public bool RepackDefaultRules { get; set; }
148149

149-
[Option('r', "custom-rules-path", Required = false, HelpText = "Custom rules path")]
150+
[Option('r', "custom-rules-path", Required = false, HelpText = "Custom rules file or directory path")]
150151
public string CustomRulesPath { get; set; }
151152

152-
[Option('o', "output-file-path", Required = false, HelpText = "Path to output file")]
153+
[Option('o', "output-file-path", Required = false, HelpText = "Output file path")]
153154
public string OutputFilePath { get; set; }
154155

155156
[Option('i', "not-indented", Required = false, HelpText = "Remove indentation from json output", Default = false)]

AppInspector/Commands/AnalyzeCommand.cs

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -150,38 +150,32 @@ void ConfigRules()
150150
{
151151
WriteOnce.SafeLog("AnalyzeCommand::ConfigRules", LogLevel.Trace);
152152

153-
RuleSet rulesSet = new RuleSet(_arg_logger);
153+
RuleSet rulesSet = null;
154154
List<string> rulePaths = new List<string>();
155155

156156
if (!_arg_ignoreDefaultRules)
157157
{
158-
Assembly assembly = Assembly.GetExecutingAssembly();
159-
string[] resourceName = assembly.GetManifestResourceNames();
160-
string filePath = "Microsoft.ApplicationInspector.Commands.defaultRules.json";
161-
Stream resource = assembly.GetManifestResourceStream(filePath);
162-
using (StreamReader file = new StreamReader(resource))
163-
{
164-
rulesSet.AddString(file.ReadToEnd(), filePath, null);
165-
}
158+
rulePaths.Add(Utils.GetPath(Utils.AppPath.defaultRulesPackedFile));
159+
rulesSet = Utils.GetDefaultRuleSet(_arg_logger);
166160
}
167161

168162
if (!string.IsNullOrEmpty(_arg_customRulesPath))
163+
{
164+
if (rulesSet == null)
165+
rulesSet = new RuleSet(_arg_logger);
166+
169167
rulePaths.Add(_arg_customRulesPath);
170168

171-
foreach (string rulePath in rulePaths)
172-
{
173-
if (Directory.Exists(rulePath))
174-
rulesSet.AddDirectory(rulePath);
175-
else if (File.Exists(rulePath))
176-
rulesSet.AddFile(rulePath);
169+
if (Directory.Exists(_arg_customRulesPath))
170+
rulesSet.AddDirectory(_arg_customRulesPath);
171+
else if (File.Exists(_arg_customRulesPath))
172+
rulesSet.AddFile(_arg_customRulesPath);
177173
else
178-
{
179-
throw new OpException(ErrMsg.FormatString(ErrMsg.ID.CMD_INVALID_RULE_PATH, rulePath));
180-
}
174+
throw new OpException(ErrMsg.FormatString(ErrMsg.ID.CMD_INVALID_RULE_PATH, _arg_customRulesPath));
181175
}
182176

183177
//error check based on ruleset not path enumeration
184-
if (rulesSet.Count() == 0)
178+
if (rulesSet == null || rulesSet.Count() == 0)
185179
{
186180
throw new OpException(ErrMsg.GetString(ErrMsg.ID.CMD_NORULES_SPECIFIED));
187181
}
@@ -265,7 +259,7 @@ void ConfigSourcetoScan()
265259

266260

267261
/// <summary>
268-
/// Option for DLL use as alternate to Run which only outputs a file to return results as string
262+
/// Option for DLL use as alternate to Run() which only outputs a file to return results as string
269263
/// CommandOption defaults will not have been set when used as DLL via CLI processing so some checks added
270264
/// </summary>
271265
/// <returns>output results</returns>
@@ -315,6 +309,7 @@ public override int Run()
315309
}
316310
catch (Exception e)
317311
{
312+
WriteOnce.SafeLog(e.Message, LogLevel.Error);
318313
throw new OpException(ErrMsg.FormatString(ErrMsg.ID.ANALYZE_FILE_TYPE_OPEN, filename));
319314
}
320315

0 commit comments

Comments
 (0)