Skip to content

Commit 2e60c37

Browse files
Farighkunaltyagi
authored andcommitted
nsiqcppstyle_exe: Add -q/--quiet option (#14)
Simplify verbosity of output Added a new ConsoleOuputer class, instantiated as a global variable. It is in charge of persisting the verbosity level. It also exposes 2 loggers which will only print a given text provided its defined verbosity level is equal or more than the one set by the user. The following levels are defined: - Verbose (only displayed if the verbose option as been enabled) - Info (skipped if the "--ci" option is passed) - Ci (currently always displayed) - Error (always displayed) The two logger members are: - Out: This one logs on the console stdout stream - Err: This one logs on the console stderr stream
1 parent 2e5ed94 commit 2e60c37

8 files changed

+165
-82
lines changed

nsiqcppstyle_checker.py

+10-14
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828

2929
import os
3030
import traceback
31+
from nsiqcppstyle_outputer import _consoleOutputer as console
3132
from nsiqcppstyle_rulehelper import * #@UnusedWildImport
3233
# Reserved words
3334

@@ -307,8 +308,7 @@ def t_CPPCOMMENT(t):
307308
return t
308309

309310
def t_error(t):
310-
if nsiqcppstyle_state._nsiqcppstyle_state.verbose :
311-
print "Illegal character '%s'" % t.value[0], t.lexer.lineno;
311+
console.Out.Verbose("Illegal character '%s'" % t.value[0], t.lexer.lineno);
312312
t.lexer.skip(1)
313313

314314

@@ -1103,17 +1103,15 @@ def ContructContextInfo(lexer):
11031103
t.contextStack = contextStack
11041104
prevLine = t.lineno
11051105
except Exception, e:
1106-
if nsiqcppstyle_state._nsiqcppstyle_state.verbose :
1107-
print >> sys.stderr, "Context Construnction Error : ", t, t.contextStack, e
1108-
traceback.print_exc(file=sys.stderr)
1106+
console.Err.Verbose("Context Construction Error : ", t, t.contextStack, e)
1107+
console.Err.Verbose(traceback.format_exc())
11091108

11101109
def RunRules(ruleManager, lexer):
11111110
try :
11121111
ruleManager.RunFileStartRule(lexer, os.path.basename(lexer.filename), os.path.dirname(lexer.filename))
11131112
except Exception, e:
1114-
if nsiqcppstyle_state._nsiqcppstyle_state.verbose :
1115-
print >> sys.stderr, "Rule Error : ", e
1116-
traceback.print_exc(file=sys.stderr)
1113+
console.Err.Verbose("Rule Error : ", e)
1114+
console.Err.Verbose(traceback.format_exc())
11171115
currentLine = 0
11181116
t = None
11191117
while(True) :
@@ -1139,13 +1137,11 @@ def RunRules(ruleManager, lexer):
11391137
ruleManager.RunTypeScopeRule(lexer, t.contextStack)
11401138
ruleManager.RunRule(lexer, t.contextStack)
11411139
except Exception, e:
1142-
if nsiqcppstyle_state._nsiqcppstyle_state.verbose :
1143-
print >> sys.stderr, "Rule Error : ", t, t.contextStack, e
1144-
traceback.print_exc(file=sys.stderr)
1140+
console.Err.Verbose("Rule Error : ", t, t.contextStack, e)
1141+
console.Err.Verbose(traceback.format_exc())
11451142
try :
11461143
ruleManager.RunFileEndRule(lexer, os.path.basename(lexer.filename), os.path.dirname(lexer.filename))
11471144
except Exception, e:
1148-
if nsiqcppstyle_state._nsiqcppstyle_state.verbose :
1149-
print >> sys.stderr, "Rule Error : ", e
1150-
traceback.print_exc(file=sys.stderr)
1145+
console.Err.Verbose("Rule Error : ", e)
1146+
console.Err.Verbose(traceback.format_exc())
11511147

nsiqcppstyle_exe.py

+31-36
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import sys # @UnusedImport
3434
import copy
3535
import nsiqcppstyle_checker
36+
from nsiqcppstyle_outputer import _consoleOutputer as console
3637
import nsiqcppstyle_state
3738
import nsiqcppstyle_rulemanager
3839
import nsiqcppstyle_reporter
@@ -49,7 +50,7 @@
4950

5051

5152
def ShowMessageAndExit(msg, usageOutput=True):
52-
print >> sys.stderr, msg
53+
console.Err.Error(msg)
5354
if usageOutput:
5455
Usage()
5556
sys.exit(-1)
@@ -74,7 +75,7 @@ def Usage():
7475
-o path Set the output path. It's only applied when the output is csv or xml.
7576
-f path Set the filefilter path. If not provided, it uses the default filterpath
7677
(target/filefilter.txt)
77-
If you provide the file path(not folder path) for the target,
78+
If you provide the file path (not a folder path) for the target,
7879
-f option should be provided.
7980
--var=key: value,key: value
8081
provide the variables to customize the rule behavior.
@@ -86,7 +87,8 @@ def Usage():
8687
that each tool recognizes.
8788
csv and xml outputs the result on the file "nsiqcppstyle_result.csv"
8889
"nsiqcppstyle_result.xml" respectively, if you don't provide -o option.
89-
--ci Continuous Integration mode. If this mode is on, this tool only report summary.
90+
--ci Continuous Integration mode. If this mode is on, this tool only reports summary.
91+
--quiet / -q Quiet mode. If this mode is on, this tool only reports errors.
9092
9193
* nsiqcppstyle reports coding standard violations on C/C++ source code.
9294
* In default, it doesn't apply any rules on the source. If you want to apply rule,
@@ -133,9 +135,9 @@ def main(argv=None):
133135
argv = sys.argv
134136
try:
135137
try:
136-
opts, args = getopt.getopt(argv[1: ], "o: s: m: hvrf: ", ["help", "csv",
138+
opts, args = getopt.getopt(argv[1: ], "o: s: m: hqvrf: ", ["help", "csv",
137139
"output=", "list_rules", "verbose=", "show-url", "no-update",
138-
"ci", "var=", "noBase"])
140+
"ci", "quiet", "var=", "noBase"])
139141
except getopt.error, msg:
140142
raise ShowMessageAndExit(msg)
141143
return 0
@@ -144,7 +146,6 @@ def main(argv=None):
144146
_nsiqcppstyle_state.output_format = "vs7"
145147
filterScope = "default"
146148
filterPath = ""
147-
ciMode = False
148149
noBase = False
149150
varMap = {}
150151
extLangMap = {
@@ -171,7 +172,7 @@ def main(argv=None):
171172
elif o == "-f":
172173
filterPath = a.strip().replace("\"", "")
173174
elif o == "-v":
174-
EnableVerbose()
175+
console.SetLevel(console.Level.Verbose)
175176
elif o == "-s":
176177
filterScope = a
177178
elif o == "--show-url":
@@ -184,19 +185,21 @@ def main(argv=None):
184185
elif o == "--var":
185186
varMap = GetCustomKeyValueMap(a, "--var="+a)
186187
elif o == "--ci":
187-
ciMode = True
188+
console.SetLevel(console.Level.Ci);
189+
elif o in ("-q", "--quiet"):
190+
console.SetLevel(console.Level.Error);
188191
elif o == "--noBase":
189192
noBase = True
190193

191-
print title
194+
console.Out.Ci(title)
192195
runtimePath = GetRuntimePath()
193196
sys.path.append(runtimePath)
194197
if updateNsiqCppStyle:
198+
console.Out.Ci(console.Separator)
195199
try:
196-
print "======================================================================================"
197200
updateagent.agent.Update(version)
198201
except Exception, e:
199-
print e
202+
console.Out.Error(e)
200203

201204
targetPaths = GetRealTargetPaths(args)
202205
multipleTarget = True
@@ -219,8 +222,8 @@ def main(argv=None):
219222
nsiqcppstyle_reporter.StartTarget(targetPath)
220223
extLangMapCopy = copy.deepcopy(extLangMap)
221224
targetName = os.path.basename(targetPath)
222-
print "======================================================================================"
223-
print "= Analyzing %s " % targetName
225+
console.Out.Ci(console.Separator)
226+
console.Out.Ci("= Analyzing %s " % targetName)
224227

225228
if filterPath != "":
226229
filefilterPath= filterPath
@@ -237,7 +240,8 @@ def main(argv=None):
237240
filterManager = FilterManager(filefilterPath, extLangMapCopy, varMap, filterScope)
238241

239242
if filterScope != filterManager.GetActiveFilter().filterName:
240-
print "\n%s filter scope is not available. Instead, use %s\n" % (filterScope, filterManager.GetActiveFilter().filterName)
243+
console.Out.Error("\n%s filter scope is not available. Instead, use %s\n"
244+
% (filterScope, filterManager.GetActiveFilter().filterName))
241245

242246
filter = filterManager.GetActiveFilter()
243247
# Load Rule
@@ -246,21 +250,20 @@ def main(argv=None):
246250
ShowMessageAndExit("Error!. Rules must be set in %s" % filefilterPath, False)
247251
continue
248252

249-
ruleManager.LoadRules(filter.nsiqCppStyleRules, not ciMode)
253+
ruleManager.LoadRules(filter.nsiqCppStyleRules)
250254
_nsiqcppstyle_state.checkers = filter.nsiqCppStyleRules
251255
_nsiqcppstyle_state.varMap = filter.varMap
252256
nsiqcppstyle_reporter.ReportRules(ruleManager.availRuleNames, filter.nsiqCppStyleRules)
253-
if not ciMode:
254-
print filter.to_string()
255-
print "======================================================================================"
256-
257-
if VerboseMode(): print "* run nsiqcppstyle analysis on %s" % targetName
257+
258+
console.Out.Info(filter.to_string())
259+
console.Out.Ci(console.Separator)
260+
console.Out.Verbose("* run nsiqcppstyle analysis on %s" % targetName)
258261

259262
# if the target is file, analyze it without condition
260263
if os.path.isfile(targetPath):
261264
fileExtension = targetPath[targetPath.rfind('.') + 1: ]
262265
if fileExtension in cExtendstionSet:
263-
ProcessFile(ruleManager, targetPath, analyzedFiles, ciMode)
266+
ProcessFile(ruleManager, targetPath, analyzedFiles)
264267

265268
# if the target is directory, analyze it with filefilter and basefilelist
266269
else:
@@ -279,25 +282,25 @@ def main(argv=None):
279282
basePart = eachFile[len(targetPath): ]
280283
if fileExtension in cExtendstionSet and basefilelist.IsNewOrChanged(eachFile) and filter.CheckFileInclusion(basePart):
281284
nsiqcppstyle_reporter.StartFile(os.path.dirname(basePart), fname)
282-
ProcessFile(ruleManager, eachFile, analyzedFiles, ciMode)
285+
ProcessFile(ruleManager, eachFile, analyzedFiles)
283286
nsiqcppstyle_reporter.EndFile()
284287
ruleManager.RunProjectRules(targetPath)
285288
nsiqcppstyle_reporter.EndTarget()
286289

287-
nsiqcppstyle_reporter.ReportSummaryToScreen(analyzedFiles, _nsiqcppstyle_state, filter, ciMode)
290+
nsiqcppstyle_reporter.ReportSummaryToScreen(analyzedFiles, _nsiqcppstyle_state, filter)
288291
nsiqcppstyle_reporter.CloseReport(_nsiqcppstyle_state.output_format)
289292
return _nsiqcppstyle_state.error_count
290293

291294
except Usage, err:
292-
print >> sys.stderr, err.msg
293-
print >> sys.stderr, "for help use --help"
295+
console.Err.Error(err.msg)
296+
console.Err.Error("for help use --help")
294297
sys.exit(-1)
295298

296299

297300
#################################################################################################3
298301

299-
def ProcessFile(ruleManager, file, analyzedFiles, ciMode):
300-
if not ciMode: print "Processing: ", file
302+
def ProcessFile(ruleManager, file, analyzedFiles):
303+
console.Out.Info("Processing: ", file)
301304
nsiqcppstyle_checker.ProcessFile(ruleManager, file)
302305
analyzedFiles.append(file)
303306

@@ -328,15 +331,7 @@ def GetRealTargetPaths(args):
328331
ShowMessageAndExit("Error!: Target directory %s is not exists" % eachTarget)
329332
return targetPaths
330333

331-
#################################################################################################3
332-
333-
def EnableVerbose():
334-
_nsiqcppstyle_state.verbose = True
335-
336-
def VerboseMode():
337-
return _nsiqcppstyle_state.verbose
338-
339-
334+
#################################################################################################
340335

341336
##############################################################################
342337
# Filter Manager

nsiqcppstyle_outputer.py

+94
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
# Redistribution and use in source and binary forms, with or without
2+
# modification, are permitted provided that the following conditions are
3+
# met:
4+
#
5+
# * Redistributions of source code must retain the above copyright
6+
# notice, this list of conditions and the following disclaimer.
7+
# * Redistributions in binary form must reproduce the above
8+
# copyright notice, this list of conditions and the following disclaimer
9+
# in the documentation and/or other materials provided with the
10+
# distribution.
11+
# * Neither the name of NHN Inc. nor the names of its
12+
# contributors may be used to endorse or promote products derived from
13+
# this software without specific prior written permission.
14+
#
15+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16+
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17+
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18+
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19+
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20+
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21+
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22+
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23+
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24+
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26+
# ----------------------------------------------------------------------
27+
28+
import logging, sys
29+
30+
class ConsoleOuputer:
31+
class Level:
32+
Verbose = logging.DEBUG
33+
Info = logging.INFO
34+
Ci = logging.WARNING
35+
Error = logging.ERROR
36+
37+
def __init__(self):
38+
# Default level is set to Info
39+
self.__level = self.Level.Info
40+
41+
# Commonly used console separator
42+
self.Separator = "======================================================================================"
43+
44+
# Available output stream loggers
45+
self.Err = self.__NSIQLogger(sys.stderr, "stdErrConsole")
46+
self.Out = self.__NSIQLogger(sys.stdout, "stdOutConsole")
47+
48+
def IsLevelDisplayed(self, level):
49+
return level >= self.__level
50+
51+
def SetLevel(self, level):
52+
self.__level = level
53+
self.Out.SetLoggerLevel(level)
54+
self.Err.SetLoggerLevel(level)
55+
56+
class __NSIQLogger:
57+
def __init__(self, output, name):
58+
self.__logger = logging.getLogger(name)
59+
self.__logger.setLevel(ConsoleOuputer.Level.Info)
60+
61+
# Create console handler and set level to Verbose
62+
consoleHandler = logging.StreamHandler(output)
63+
consoleHandler.setLevel(ConsoleOuputer.Level.Verbose)
64+
65+
# Create formatter
66+
formatter = logging.Formatter('%(message)s')
67+
68+
# Add formatter to consoleHandler
69+
consoleHandler.setFormatter(formatter)
70+
71+
# Add consoleHandler to logger
72+
self.__logger.addHandler(consoleHandler)
73+
74+
def Verbose(self, *msgArgs):
75+
self.__logger.debug(self.__Format(*msgArgs))
76+
77+
def Info(self, *msgArgs):
78+
self.__logger.info(self.__Format(*msgArgs))
79+
80+
def Ci(self, *msgArgs):
81+
self.__logger.warning(self.__Format(*msgArgs))
82+
83+
def Error(self, *msgArgs):
84+
self.__logger.error(self.__Format(*msgArgs))
85+
86+
def SetLoggerLevel(self, level):
87+
self.__logger.setLevel(level)
88+
89+
def __Format(self, *msgArgs):
90+
# Format output the same way a direct call to print would
91+
return ' '.join(str(a) for a in msgArgs)
92+
93+
_consoleOutputer = ConsoleOuputer()
94+

0 commit comments

Comments
 (0)