Repository: melexis/warnings-plugin

Issue:
Report command return value by default
If command exists with non 0 value, we just check if there are no warnings and we might mark a field as passed. Confirm the return value of the command and use that as a default return value. Provide flag to disregard that.

Discussion:

Patch:
diff --git a/.travis.yml b/.travis.yml
index ecc0bf8..7df4c41 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -55,6 +55,19 @@ notifications:
     on_failure: always
 
 deploy:
+  # test pypi
+  - provider: pypi
+    distributions: sdist bdist_wheel
+    server: https://test.pypi.org/legacy/
+    user: bavo.van.achte
+    password:
+      secure: cKCBgEUOSUnlPbOxHCrXENlVgdMGnjNC+7nnutp/1xF8VEDF3aj9Br4u5LKrAYs0sm0AvnCyjhPvfKGPwyRDdfGBjoG06G+L+1hcfpgBlItmdSBqB8RxMm2B76si1ZlVI9gC58hlk/agFr2vik/mLXsH23rafB/2UwfB3ItTTx2J14xC5jlaqYR/srMJUi8YO5z6mGGLokfcz0KhYUHegOna38UcARM8rkAC2Je0xrPKZMlCoTI84dqwnFPW4zn3g/B5s3s18gmZu4fE4+J1g0PNMvxhbDP1TIBzPSWXLBv+YPSKrIT6+Q4R/kfDJFzLn3SmDDnNOpD/OC8ssqVJOcQL3HhKQ7EAcxX9W+/Rt7mIpdJdDXohiPrBl9EdRYbhB+KiPeo/dekAV6loUP/8cHuEgjcW/gE8t+HIqWsa5SO9yK7Sz8Ym+0ENdzS1df0iPOj2ebR3kb1iwINdFi7zIG6Utvlf7w1A2Qtx1xfI2+woPU+GOgQrpwdw64Wl1uo4l0kqTpFkytIG7BEVWC+zPPzqddi+3Ulf9AkWSjNDTqYafxZ9oqBJ5q7WPH8zyPQHotcHbnziTAnv7qRa+CTFLeME/KXNT8egToLK75G367lANTFIhMm8eSDS7wAxFWHacq8j68wNb38Yj1Rv1WMHQh14sxOkzQ4hVEV0xYY7Bj8=
+    before_deploy:
+      - "env SETUP_TOOLS_SCM_PRETEND_VERSION='{next_version}.dev{distance}'"
+    on:
+      branch: master
+      python: 3.6
+      tags: false
   # production pypi
   - provider: pypi
     distributions: sdist bdist_wheel
diff --git a/src/mlx/warnings.py b/src/mlx/warnings.py
index 7f23c10..894f799 100644
--- a/src/mlx/warnings.py
+++ b/src/mlx/warnings.py
@@ -213,6 +213,7 @@ class WarningsPlugin:
         self.warn_min = 0
         self.warn_max = 0
         self.count = 0
+        self.printout = False
 
     def activate_checker(self, checker):
         '''
@@ -244,6 +245,8 @@ class WarningsPlugin:
         if len(self.checkerList) == 0:
             print("No checkers activated. Please use activate_checker function")
         else:
+            if self.printout:
+                print(content)
             for name, checker in self.checkerList.items():
                 checker.check(content)
 
@@ -309,6 +312,16 @@ class WarningsPlugin:
 
         return 0
 
+    def toggle_printout(self, printout):
+        ''' Toggle printout of all the parsed content
+
+        Useful for command input where we want to print content as well
+
+        Args:
+            printout: True enables the printout, False provides more silent mode
+        '''
+        self.printout = printout
+
 
 def warnings_wrapper(args):
     parser = argparse.ArgumentParser(prog='mlx-warnings')
@@ -319,6 +332,8 @@ def warnings_wrapper(args):
     parser.add_argument('-v', '--verbose', dest='verbose', action='store_true')
     parser.add_argument('--command', dest='command', action='store_true',
                         help='Treat program arguments as command to execute to obtain data')
+    parser.add_argument('--ignore-retval', dest='ignore', action='store_true',
+                        help='Ignore return value of the executed command')
     parser.add_argument('-m', '--maxwarnings', type=int, required=False, default=0,
                         help='Maximum amount of warnings accepted')
     parser.add_argument('--minwarnings', type=int, required=False, default=0,
@@ -338,7 +353,11 @@ def warnings_wrapper(args):
         cmd = args.logfile
         if args.flags:
             cmd.extend(args.flags)
-        warnings_command(warnings, cmd)
+        warnings.toggle_printout(True)
+        retval = warnings_command(warnings, cmd)
+
+        if (not args.ignore) and (retval != 0):
+            return retval
     else:
         warnings_logfile(warnings, args.logfile)
 
@@ -347,6 +366,24 @@ def warnings_wrapper(args):
 
 
 def warnings_command(warnings, cmd):
+    ''' Execute command to obtain input for parsing for warnings
+
+    Usually log files are output of the commands. To avoid this additional step
+    this function runs a command instead and parses the stderr and stdout of the
+    command for warnings.
+
+    Args:
+        warnings (WarningsPlugin): Object for warnings where errors should be logged
+        cmd: Command list, which should be executed to obtain input for parsing
+        ignore: Flag to ignore return value of the command
+
+    Return:
+        retval: Return value of executed command
+
+    Raises:
+        OSError: When program is not installed.
+    '''
+
     try:
         print("Executing: ", end='')
         print(cmd)
@@ -356,19 +393,16 @@ def warnings_command(warnings, cmd):
         # Check stdout
         if out:
             try:
-                print(out.decode(encoding="utf-8"))
                 warnings.check(out.decode(encoding="utf-8"))
             except AttributeError as e:
                 warnings.check(out)
-                print(out)
         # Check stderr
         if err:
             try:
                 warnings.check(err.decode(encoding="utf-8"))
-                print(err.decode(encoding="utf-8"), file=sys.stderr)
             except AttributeError as e:
                 warnings.check(err)
-                print(err, file=sys.stderr)
+        return proc.returncode
     except OSError as e:
         if e.errno == os.errno.ENOENT:
             print("It seems like program " + str(cmd) + " is not installed.")


Test patch:
diff --git a/tests/test_integration.py b/tests/test_integration.py
index 4500dfb..9bc771a 100644
--- a/tests/test_integration.py
+++ b/tests/test_integration.py
@@ -50,6 +50,14 @@ class TestIntegration(TestCase):
         with self.assertRaises(OSError):
             warnings_wrapper(['--sphinx', '--command', 'blahahahaha', 'tests/sphinx_single_warning.txt'])
 
+    def test_command_revtal_err(self):
+        retval = warnings_wrapper(['--sphinx', '--command', 'false'])
+        self.assertEqual(1, retval)
+
+    def test_command_revtal_err_supress(self):
+        retval = warnings_wrapper(['--sphinx', '--ignore-retval', '--command', 'false'])
+        self.assertEqual(0, retval)
+
     def test_wildcarded_arguments(self):
         # note: no shell expansion simulation (e.g. as in windows)
         retval = warnings_wrapper(['--junit', 'tests/junit*.xml'])