#1337 automatic pylint
Merged 4 years ago by praiskup. Opened 4 years ago by praiskup.
Unknown source linters  into  master

file modified
+9
@@ -8,6 +8,15 @@

  extension-pkg-whitelist=SQLAlchemy

  ignored-modules = SQLAlchemy

  

+ init-hook=

+     import os

+     import sys

+     from pylint.config import find_pylintrc

+     pylintrc = find_pylintrc()

+     backend_dir = os.path.dirname(pylintrc)

+     sys.path.insert(0, os.path.join(backend_dir, '..', 'common'))

+     sys.path.insert(0, os.path.join(backend_dir, '..', 'python'))

+ 

  [MESSAGES CONTROL]

  

  # Disable the message(s) with the given id(s).

file modified
+5
@@ -30,4 +30,9 @@

      esac

  done

  

+ test -f ../build_aux/linter && {

+     echo >&2 "running linter"

+     ../build_aux/linter

+ }

+ 

Is anyone against adding (something like) this to all of our packages?

  python3 -m pytest -s tests $COVPARAMS "${KEEP_ARGS[@]}"

@@ -0,0 +1,12 @@

+ #! /bin/bash

+ 

+ # csdiff mis-parses the line if we don't produce absoulute filenames, hence

+ # the leading /.

+ 

+ pylint -rn \

+        --score=no \

+        --msg-template='/{path}:{line}:{column}: {msg_id}[pylint]: {msg}' \

+        "$@" \

+     | grep -F -v '*******'

+ 

+ exit "${PIPESTATUS[0]}"

@@ -0,0 +1,94 @@

+ #! /bin/bash

+ 

+ set -x

+ set -e

+ 

+ # only PRs now

+ case $REPO in

+     *forks*) ;;

+     *) exit 0 ;;

+ esac

+ 

+ cleanup_actions=()

+ cleanup()

+ {

+     for action in "${cleanup_actions[@]}"; do

+         $action

+     done

+ }

+ trap cleanup EXIT

+ 

+ filter="

+ import sys, json

+ d = json.loads(sys.stdin.read())

+ for member in d['members']:

+     sys.stdout.write(' ' + member + ' ')

+ print()

+ "

+ 

+ echo "Checking whether we want to run against $REPO/$BRANCH"

+ 

+ # only copr-team for now

+ members=$(curl https://pagure.io/api/0/group/copr \

+     | python3 -c "$filter")

+ 

+ # https://pagure.io/pagure/issue/4807

+ copr_sig_member=false

+ for member in $members; do

+     case $REPO in

+         *forks/$member/*)

+             copr_sig_member=true

+             break

+             ;;

+     esac

+ done

+ $copr_sig_member || exit 0  # silently skip non-copr people

+ 

+ git remote rm proposed || true

+ git remote add proposed "$REPO"

+ git fetch proposed

+ git checkout "proposed/$BRANCH"

+ 

+ : "${DIFF_AGAINST=origin/master}"

+ 

+ subdirs=(

+     -e ^backend$

+     -e ^frontend$

+     -e ^distgit$

+     -e ^cli$

+     -e ^common$

+     -e ^messaging$

+     -e ^rpmbuild$

+     -e ^keygen$

+     -e ^python$

+ )

+ 

+ changed_packages=$(

+     git diff --name-only "$DIFF_AGAINST" \

+         | cut -d'/' -f1 | sort | uniq \

+         | grep "${subdirs[@]}"

+ ) || :

+ 

+ test -n "$changed_packages" || exit 0

+ 

+ 

+ run_linter()

+ {

+     test -f build_aux/linter || return 0

+     mkdir -p image

+     image=copr-lint-container:latest

+     cat > image/Dockerfile <<EOF

+ From fedora:32

+ RUN dnf install -y csdiff git pylint

+ EOF

+     ( cd image

+       docker build -t "$image" .

+     )

+     container=$(docker run --rm -v "$PWD":/workdir:Z -d "$image" sleep 1800)

+     cleanup_actions+=( "docker kill $container" )

+     for package; do

+       docker exec "$container" bash -c "cd /workdir/$package && ../build_aux/linter --compare-against $DIFF_AGAINST"

+     done

+ }

+ 

+ run_linter $changed_packages

file added
+287
@@ -0,0 +1,287 @@

+ #! /usr/bin/python3

+ 

+ """

+ Using 'csdiff', print newly added coding errors.

+ """

+ 

+ import os

+ import sys

+ from subprocess import Popen, PIPE, check_output, check_call

+ import glob

+ import logging

+ import tempfile

+ import shutil

+ import argparse

+ 

+ 

+ logging.basicConfig(level=logging.INFO)

+ log = logging.getLogger()  # pylint: disable=invalid-name

+ 

+ CSDIFF_PYLINT = os.path.realpath(os.path.join(os.path.dirname(__file__),

+                                               'csdiff-pylint'))

+ 

+ 

+ def file_type(filename):

+     """

+     Taking FILENAME (must exist), return it's type in string format.  Current

+     supported formats are ('python',).

+     """

+     if filename.endswith(".py"):

+         return 'python'

+     with open(filename) as f_d:

+         first_line = f_d.readline()

+         if first_line.startswith('#!') and first_line.find('python') != -1:

+             return 'python'

+     return 'unknown'

+ 

+ 

+ class _Linter:

+     filetype = None

+     path_filters = None

+ 

+     def __init__(self, projectdir, renames=None):

+         self.projectdir = projectdir

+         self.renames = renames

+ 

+     @classmethod

+     def modify_rename(cls, old, new):

+         """ if the paths in linter output need adjustments """

+         return old, new

+ 

+     def _sed_filter(self):

+         if not self.renames:

+             return None

+ 

+         rules = []

+         for pair in self.renames:

+             old, new = self.modify_rename(pair[0], pair[1])

+             rule = "s|^{}|{}|".format(old, new)

+             rules += ['-e', rule]

+ 

+         return ['sed'] + rules

+ 

+     def command(self, filenames):

+         """

+         Given the list of FILENAMES, generate command that will be executed

+         by lint() method, and environment vars set.  Return (CMD, ENV) pair.

+         """

+         raise NotImplementedError

+ 

+     # pylint: disable=no-self-use,unused-argument

+     def is_compatible(self, file):

+         """ file contains 'filename' and 'type' attributes """

+         return True

+ 

+     def lint(self, cwd, files, logfd):

+         """ run the linter """

+         if not files:

+             return

+ 

+         oldcwd = os.getcwd()

+ 

+         try:

+             log.debug("linting in %s", cwd)

+             os.chdir(cwd)

+             files = [f.filename for f in files if self.is_compatible(f)]

+             if not files:

+                 return

+             linter_cmd, linter_env = self.command(files)

+             env = os.environ.copy()

+             env.update(linter_env)

+             sed_cmd = self._sed_filter()

+             if sed_cmd:

+                 linter = Popen(linter_cmd, env=env, stdout=PIPE)

+                 sed = Popen(sed_cmd, stdout=logfd, stdin=linter.stdout)

+                 sed.communicate()

+             else:

+                 linter = Popen(linter_cmd, env=env, stdout=logfd)

+                 linter.communicate()

+ 

+         finally:

+             os.chdir(oldcwd)

+ 

+ 

+ class PylintLinter(_Linter):

+     """

+     Generate pyilnt error output that is compatible with 'csdiff'.

+     """

+     def is_compatible(self, file):

+         return file.type == 'python'

+ 

+     @classmethod

+     def modify_rename(cls, old, new):

+         """

+         Git reports 'a -> b' rename, but we use '/a -> /b' here because

+         otherwise csdiff wouldn't parse the reports.  That's why we have to

+         modify it here, too.

+         """

+         return '/' + old, '/' + new

+ 

+     def command(self, filenames):

+         options = []

+         pylintrc = os.path.realpath(os.path.join(self.projectdir, 'pylintrc'))

+         cmd = [CSDIFF_PYLINT] + options + filenames

+         env = {'PYLINTRC': pylintrc}

+         return cmd, env

+ 

+ 

+ def get_rename_map(options):

+     """

+     Using the os.getcwd() and 'git diff --namestatus', generate list of

+     files to analyze with possible overrides.  The returned format is

+     dict of format 'new_file' -> 'old_file'.

+     """

+     cmd = ['git', 'diff', '--name-status', '-C', options.compare_against,

+            '--numstat', '.']

+     # current file -> old_name

+     return_map = {}

+     output = check_output(cmd).decode('utf-8')

+     for line in output.split('\n'):

+         if not line:

+             continue

+ 

+         parts = line.split('\t')

+         mode = parts[0]

+         if mode == '':

+             continue

+         if mode.startswith('R'):

+             return_map[parts[2]] = parts[1]

+         elif mode.startswith('A'):

+             return_map[parts[1]] = None

+         elif mode == 'M':

+             return_map[parts[1]] = parts[1]

+         else:

+             assert False

+ 

+     return return_map

+ 

+ 

+ class _Worker:  # pylint: disable=too-few-public-methods

+     gitroot = None

+     projectdir = None

+     workdir = None

+     checkout = None

+     linters = [PylintLinter]

+ 

+     def __init__(self, options):

+         self.options = options

+ 

+     def _analyze_projectdir(self):

+         """ find sub-directory in git repo which contains spec file """

+         gitroot = check_output(['git', 'rev-parse', '--show-toplevel'])

+         self.gitroot = gitroot.decode('utf-8').strip()

+ 

+         checkout = check_output(['git', 'rev-parse',

+                                  self.options.compare_against])

+         self.checkout = checkout.decode('utf-8').strip()

+ 

+         path = os.getcwd()

+         while True:

+             log.debug("checking for projectdir: %s", path)

+             if os.path.realpath(path) == '/':

+                 raise Exception("project dir not found")

+             if os.path.isdir(os.path.join(path, '.git')):

+                 self.projectdir = path

+                 return

+             if glob.glob(os.path.join(path, '*.spec')):

+                 self.projectdir = path

+                 return

+             path = os.path.normpath(os.path.join(path, '..'))

+ 

+     def _run_linters(self, old_report_fd, new_report_fd):

+         # pylint: disable=too-many-locals

+         lookup = get_rename_map(self.options)

+         if not lookup:

+             return

+ 

+         old_files = []

+         new_files = []

+         old_dir = os.path.join(self.workdir, 'old_dir')

+         origin_from = self.gitroot

+         check_call(['git', 'clone', '--quiet', origin_from, old_dir])

+         ret_cwd = os.getcwd()

+         try:

+             os.chdir(old_dir)

+             check_call(['git', 'checkout', '-q', self.checkout])

+         finally:

+             os.chdir(ret_cwd)

+ 

+         new_dir = self.gitroot

+ 

+         def add_file(dirname, files, filename):

+             if not filename:

+                 return

+             git_file = os.path.join(dirname, filename)

+             if not os.path.isfile(git_file):

+                 log.debug("skipping non-file %s", git_file)

+                 return

+             file = lambda: None  # noqa: E731

+             file.filename = filename

+             file.type = file_type(git_file)

+             files.append(file)

+ 

+         for filename in lookup:

+             add_file(new_dir, new_files, filename)

+             add_file(old_dir, old_files, lookup[filename])

+ 

+         renames = []

+         for new in lookup:

+             old = lookup[new]

+             if old and old != new:

+                 renames.append((old, new))

+ 

+         for LinterClass in self.linters:

+             linter_new = LinterClass(self.projectdir)

+             linter_old = LinterClass(self.projectdir, renames)

+             linter_new.lint(new_dir, new_files, logfd=new_report_fd)

+             linter_old.lint(old_dir, old_files, logfd=old_report_fd)

+ 

+     def run(self):

+         """

+         Run all the 'self.linters' against old sources and new sources,

+         and provide the diff.

+         """

+         self._analyze_projectdir()

+         self.workdir = tempfile.mkdtemp(prefix='copr-linter-')

+         try:

+             old_report = os.path.join(self.workdir, 'old')

+             new_report = os.path.join(self.workdir, 'new')

+ 

+             with open(old_report, 'w') as old, open(new_report, 'w') as new:

+                 oldcwd = os.getcwd()

+                 try:

+                     log.debug("going to projectdir %s", self.projectdir)

+                     os.chdir(self.projectdir)

+                     self._run_linters(old, new)

+                 finally:

+                     os.chdir(oldcwd)

+ 

+             popen_diff = Popen(['csdiff', old_report, new_report],

+                                stdout=PIPE)

+             diff = popen_diff.communicate()[0].decode('utf-8')

+             sys.stdout.write(diff)

+             sys.exit(bool(diff))

+         finally:

+             log.debug("removing workdir %s", self.workdir)

+             shutil.rmtree(self.workdir)

+ 

+ 

+ def _get_arg_parser():

+     parser = argparse.ArgumentParser()

+     parser.add_argument(

+         "--compare-against",

+         default="origin/master",

+         help=("What git ref to diff the linters' results against.  Note "

+               "that the reference needs to be available in the current "

+               "git directory"))

+     return parser

+ 

+ 

+ def _main():

+     options = _get_arg_parser().parse_args()

+     worker = _Worker(options)

+     worker.run()

+ 

+ 

+ if __name__ == "__main__":

+     _main()

file modified
+10
@@ -8,6 +8,16 @@

  extension-pkg-whitelist=SQLAlchemy

  ignored-modules = SQLAlchemy

  

+ init-hook=

+     import os

+     import sys

+     from pylint.config import find_pylintrc

+     pylintrc = find_pylintrc()

+     backend_dir = os.path.dirname(pylintrc)

+     sys.path.insert(0, os.path.join(backend_dir, '..', 'common'))

+     sys.path.insert(0, os.path.join(backend_dir, '..', 'python'))

+ 

+ 

  [MESSAGES CONTROL]

  

  # Disable the message(s) with the given id(s).

file modified
+7
@@ -1,3 +1,10 @@

  #!/bin/sh

  

+ set -e

+ 

+ test -f ../build_aux/linter && {

+     echo >&2 "running linter"

+     ../build_aux/linter

+ }

+ 

  PYTHONPATH=../python/:./copr_cli:$PYTHONPATH python3 -B -m pytest --cov-report term-missing --cov ./copr_cli/ $@

file added
+1
@@ -0,0 +1,1 @@

+ ../pylintrc 

\ No newline at end of file

file added
+1
@@ -0,0 +1,1 @@

+ ../pylintrc 

\ No newline at end of file

file modified
+5
@@ -3,6 +3,11 @@

  set -x

  set -e

  

+ test -f ../build_aux/linter && {

+     echo >&2 "running linter"

+     ../build_aux/linter

+ }

+ 

  common_path=$(readlink -f ../common)

  export PYTHONPATH="${PYTHONPATH+$PYTHONPATH:}$common_path"

  python3 -m pytest --cov-report term-missing --cov ./dist_git tests "$@"

file modified
+9
@@ -8,6 +8,15 @@

  extension-pkg-whitelist = SQLAlchemy

  ignored-modules = alembic*, sqlalchemy*, SQLAlchemy*

  

+ init-hook=

+     import os

+     import sys

+     from pylint.config import find_pylintrc

+     pylintrc = find_pylintrc()

+     backend_dir = os.path.dirname(pylintrc)

+     sys.path.insert(0, os.path.join(backend_dir, '..', 'common'))

+     sys.path.insert(0, os.path.join(backend_dir, '..', 'python'))

+ 

  [MESSAGES CONTROL]

  

  # Disable the message(s) with the given id(s).

file modified
+5
@@ -15,6 +15,11 @@

  

  ./build_aux/check-alembic-revisions

  

+ test -f ../build_aux/linter && {

+     echo >&2 "running linter"

+     ../build_aux/linter

+ }

+ 

  common_path=$(readlink -f ../common)

  export PYTHONPATH="${PYTHONPATH+$PYTHONPATH:}$common_path"

  export COPR_CONFIG="$(pwd)/coprs_frontend/config/copr_unit_test.conf"

file added
+1
@@ -0,0 +1,1 @@

+ ../pylintrc 

\ No newline at end of file

file modified
+7
@@ -1,3 +1,10 @@

  #!/bin/sh

  

+ set -e

+ 

+ test -f ../build_aux/linter && {

+     echo >&2 "running linter"

+     ../build_aux/linter

+ }

+ 

  PYTHONPATH=./src:$PYTHONPATH python3 -B -m pytest --cov-report term-missing --cov ./src tests

@@ -14,6 +14,8 @@

  # with this program; if not, write to the Free Software Foundation, Inc.,

  # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

  

+ # pylint: skip-file

+ 

  """Unit tests for the message schema."""

  

  import copy
@@ -81,7 +83,6 @@

          for key in self.required_fields:

              body = copy.deepcopy(self.fedmsg_message)

  

-             print(key)

              if key in int_fields:

                  body['msg'][key] = "str"

              else:

file modified
+10
@@ -8,6 +8,16 @@

  extension-pkg-whitelist=SQLAlchemy

  ignored-modules = SQLAlchemy

  

+ init-hook=

+     import os

+     import sys

+     from pylint.config import find_pylintrc

+     pylintrc = find_pylintrc()

+     backend_dir = os.path.dirname(pylintrc)

+     sys.path.insert(0, os.path.join(backend_dir, '..', 'common'))

+     sys.path.insert(0, os.path.join(backend_dir, '..', 'python'))

+ 

+ 

  [MESSAGES CONTROL]

  

  # Disable the message(s) with the given id(s).

file modified
+9 -2
@@ -1,7 +1,14 @@

  #! /bin/sh

  

+ set -e

+ 

+ test -f ../build_aux/linter && {

+     echo >&2 "running linter"

+     ../build_aux/linter

+ }

+ 

  dir=$(dirname "$(readlink -f "$0")")

  export PYTHONPATH=$dir:$dir/../common

+ 

  cd "$dir"

- python3 setup.py bdist_egg

- pytest-3

+ python3 -m pytest -s copr_messaging/tests

file added
+107
@@ -0,0 +1,107 @@

+ # copr global (fallback) pylint configuration

+ 

+ [MASTER]

+ # Pickle collected data for later comparisons.

+ persistent=no

+ 

+ init-hook=

+     import os

+     import sys

+     import subprocess

+     gitrootdir = subprocess.check_output(["git", "rev-parse", "--show-toplevel"]).decode("utf-8").strip()

+     sys.path.insert(0, os.path.join(gitrootdir, 'common'))

+     sys.path.insert(0, os.path.join(gitrootdir, 'python'))

+ 

+ 

+ [VARIABLES]

+ # A regular expression matching names used for dummy variables (i.e. not used).

+ dummy-variables-rgx=_|dummy

+ 

+ 

+ [BASIC]

+ # Regular expression which should only match correct module names

+ module-rgx=([a-zA-Z_][a-zA-Z0-9_]+)$

+ 

+ # Regular expression which should only match correct module level names

+ const-rgx=(([a-zA-Z_][a-zA-Z0-9_]*)|(__.*__))$

+ 

+ # Regular expression which should only match correct class names

+ class-rgx=[a-zA-Z_][a-zA-Z0-9_]+$

+ 

+ # Regular expression which should only match correct function names

+ function-rgx=[a-z_][a-zA-Z0-9_]{,42}$

+ 

+ # Regular expression which should only match correct method names

+ method-rgx=[a-z_][a-zA-Z0-9_]{,42}$

+ 

+ # Regular expression which should only match correct instance attribute names

+ attr-rgx=[a-z_][a-zA-Z0-9_]{,30}$

+ 

+ # Regular expression which should only match correct argument names

+ argument-rgx=[a-z_][a-zA-Z0-9_]{,30}$

+ 

+ # Regular expression which should only match correct variable names

+ variable-rgx=[a-z_][a-zA-Z0-9_]{,30}$

+ 

+ # Regular expression which should only match correct list comprehension /

+ # generator expression variable names

+ inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$

+ 

+ # Regular expression which should only match correct class sttribute names

+ class-attribute-rgx=([A-Za-z_][A-Za-z0-9_]{2,42}|(__.*__))$

+ 

+ # Good variable names which should always be accepted, separated by a comma

+ good-names=i,j,k,ex,Run,_

+ 

+ # Bad variable names which should always be refused, separated by a comma

+ bad-names=foo,bar,baz,toto,tutu,tata

+ 

+ # List of builtins function names that should not be used, separated by a comma

+ bad-functions=apply,input

+ 

+ 

+ [DESIGN]

+ 

+ # Maximum number of arguments for function / method

+ max-args=10

+ 

+ # Maximum number of locals for function / method body

+ max-locals=20

+ 

+ # Maximum number of return / yield for function / method body

+ max-returns=6

+ 

+ # Maximum number of branch for function / method body

+ max-branchs=20

+ 

+ # Maximum number of statements in function / method body

+ max-statements=50

+ 

+ # Maximum number of parents for a class (see R0901).

+ max-parents=7

+ 

+ # Maximum number of attributes for a class (see R0902).

+ max-attributes=7

+ 

+ # Minimum number of public methods for a class (see R0903).

+ min-public-methods=1

+ 

+ # Maximum number of public methods for a class (see R0904).

+ max-public-methods=20

+ 

+ 

+ [FORMAT]

+ # Maximum number of characters on a single line.

+ max-line-length=120

+ 

+ # Maximum number of lines in a module

+ max-module-lines=1000

+ 

+ # String used as indentation unit. This is usually " " (4 spaces) or "\t" (1

+ # tab).

+ indent-string='    '

+ 

+ 

+ [MISCELLANEOUS]

+ # List of note tags to take in consideration, separated by a comma.

+ notes=

file modified
+10
@@ -8,6 +8,16 @@

  extension-pkg-whitelist=SQLAlchemy

  ignored-modules = SQLAlchemy

  

+ init-hook=

+     import os

+     import sys

+     from pylint.config import find_pylintrc

+     pylintrc = find_pylintrc()

+     backend_dir = os.path.dirname(pylintrc)

+     sys.path.insert(0, os.path.join(backend_dir, '..', 'common'))

+     sys.path.insert(0, os.path.join(backend_dir, '..', 'python'))

+ 

+ 

  [MESSAGES CONTROL]

  

  # Disable the message(s) with the given id(s).

file modified
+7
@@ -1,5 +1,12 @@

  #!/bin/bash

  

+ set -e

+ 

+ test -f ../build_aux/linter && {

+     echo >&2 "running linter"

+     ../build_aux/linter

+ }

+ 

  absdir="$(dirname "$(readlink -f "$0")")"

  export PYTHONPATH="$absdir"

  

file added
+1
@@ -0,0 +1,1 @@

+ ../pylintrc 

\ No newline at end of file

file modified
+7
@@ -1,3 +1,10 @@

  #!/bin/sh

  

+ set -e

+ 

+ test -f ../build_aux/linter && {

+     echo >&2 "running linter"

+     ../build_aux/linter

+ }

+ 

  PYTHONPATH=".:$PYTHONPATH" "${PYTHON:-python3}" -m pytest -s tests "$@"

This is WIP, quick & dirty for now, and not material for merge. I'm going to
freeze this idea for week or so because I'm waiting at least for:
https://github.com/kdudka/csmock/issues/25

Metadata Update from @praiskup:
- Pull-request tagged with: wip

4 years ago

rebased onto 70c55b42dd9f565e3880c00663849c20c8a2df8a

4 years ago

rebased onto 70c55b42dd9f565e3880c00663849c20c8a2df8a

4 years ago

Is anyone against adding (something like) this to all of our packages?

Unfortunately, we don't have an easy way to hook this into our existing
CI.

The script needs git with reference to origin/master. This can not be
easily achieved when we build RPMs, and it's a bit problematic even with
the tito build --test SRPM build. We would have to hack our own Builder
class, use it -> and detect somehow that we are running in copr (because
we have to do `git remote add upstream our_upstream_repo, git fetch
upstream, ..., and that's not something we want to do elsewhere).

So until we have no Jenkins (or Travis, or ...) doing this only in
./run_tests.sh is better than nothing (the chance we'll catch the pylint
problems before push is much more likely).

For now I'm adding pylint, but I'd like to add ShellCheck in future which
is super useful.

pretty please pagure-ci rebuild

4 years ago

pretty please pagure-ci rebuild

4 years ago

pretty please pagure-ci rebuild

4 years ago

rebased onto 9a446483f8456e70cc444e137a5d08c384485c7a

4 years ago

1 new commit added

  • build_aux: add jenkins job helper
4 years ago

Metadata Update from @praiskup:
- Pull-request untagged with: wip

4 years ago

I need some feedback here, so I can finish this PR. I dropped the WIP flag.

pretty please pagure-ci rebuild

4 years ago

pretty please pagure-ci rebuild

4 years ago

pretty please pagure-ci rebuild

4 years ago

pretty please pagure-ci rebuild

4 years ago

3 new commits added

  • pylint: run pylint in all run*tests.sh files
  • build_aux: add jenkins job helper
  • all: add syntax linter
4 years ago

rebased onto 2e091d7

4 years ago

Pull-Request has been merged by praiskup

4 years ago

Unfortunately since this PR, the run_tests.sh scripts give me the pylint errors but then exit without running the actual tests.

+ echo 'running linter'
running linter            
+ ../build_aux/linter                                                                                                  
Error: PROSPECTOR_WARNING:
/backend/copr_backend/actions.py:231: W0223[pylint]: Method 'run' is abstract in class 'Action' but is not overridden

Error: PROSPECTOR_WARNING:
/backend/tests/test_worker_manager.py:10: C0411[pylint]: standard import "from unittest.mock import MagicMock, patch" should be placed before "import pytest"
+ cleanup
+ redis-cli -p 7777 shutdown
+ wait                                                     
[jkadlcik@localhost backend]$

Should I file a proper issue?

Yeah, that's what I wanted to achieve initially (the easiest option), but we can remember the failure, run the tests, and then report the failure?

Either that, or an option (variable) that will allow me to not run (and fail on pylint) and executes tests.

Typically you just don't care about some pylint warnings until you have the code working and tests are passing. That's the moment when you start cleaning it, removing excessive blank lines and commented pieces of code, etc.

So thinking about it, IMHO the most sense would make to first run

python3 -m pytest -s tests $COVPARAMS "${KEEP_ARGS[@]}"

and then run

test -f ../build_aux/linter && {
    echo >&2 "running linter"
    ../build_aux/linter
}

Which would be also the easiest way to fix this issue. You can simply swap them. If tests fail, then the linter is not even executed. Which is IMHO what we want anyway because then we can focus on fixing the tests and not having to scroll-up above the linter output to see the error messages. If tests succeed, you don't need to see the success message and you care about the pylint output instead. This seems like a best option to me, WDYT?

Metadata
Flags
Copr build
success (100%)
#1337510
4 years ago
Copr build
success (100%)
#1337509
4 years ago
Copr build
pending (50%)
#1337508
4 years ago
Copr build
success (100%)
#1337507
4 years ago
Copr build
success (100%)
#1337506
4 years ago
jenkins
success (100%)
Build #20 successful (commit: 21f1e9ef)
4 years ago
Copr build
failure
#1337505
4 years ago
Copr build
success (100%)
#1337504
4 years ago
Copr build
success (100%)
#1337503
4 years ago
Copr build
success (100%)
#1337502
4 years ago
Copr build
success (100%)
#1337370
4 years ago
Copr build
success (100%)
#1337369
4 years ago
Copr build
success (100%)
#1337368
4 years ago
Copr build
success (100%)
#1337367
4 years ago
Copr build
success (100%)
#1337366
4 years ago
Copr build
failure
#1337365
4 years ago
jenkins
success (100%)
Build #18 successful (commit: 1fe15745)
4 years ago
Copr build
success (100%)
#1337364
4 years ago
Copr build
success (100%)
#1337363
4 years ago
Copr build
success (100%)
#1337362
4 years ago
jenkins
success (100%)
Build #17 successful (commit: d6a5b3b9)
4 years ago
jenkins
failure
Build #16 failed (commit: d6a5b3b9)
4 years ago
jenkins
success (100%)
Build #15 successful (commit: d6a5b3b9)
4 years ago
jenkins
success (100%)
Build #14 successful (commit: d6a5b3b9)
4 years ago
jenkins
success (100%)
Build #13 successful (commit: d6a5b3b9)
4 years ago
jenkins
success (100%)
Build #13 successful (commit: d6a5b3b9)
4 years ago
jenkins
success (100%)
Build #12 successful (commit: d6a5b3b9)
4 years ago
jenkins
success (100%)
Build #12 successful (commit: d6a5b3b9)
4 years ago
jenkins
success (100%)
Build #12 successful (commit: d6a5b3b9)
4 years ago
jenkins
success (100%)
Build #12 successful (commit: d6a5b3b9)
4 years ago
jenkins
failure
Build #11 failed (commit: d6a5b3b9)
4 years ago
jenkins
failure
Build #10 failed (commit: d6a5b3b9)
4 years ago
jenkins
failure
Build #9 failed (commit: d6a5b3b9)
4 years ago
jenkins
failure
Build #8 failed (commit: d6a5b3b9)
4 years ago
jenkins
failure
Build #8 failed (commit: d6a5b3b9)
4 years ago
jenkins
failure
Build #7 failed (commit: d6a5b3b9)
4 years ago
jenkins
success (100%)
Build #3 successful (commit: d6a5b3b9)
4 years ago
jenkins
success (100%)
Build #30 successful (commit: d6a5b3b9)
4 years ago
jenkins
success (100%)
Build #25 successful (commit: d6a5b3b9)
4 years ago
Copr build
success (100%)
#1336246
4 years ago
jenkins
success (100%)
Build #23 successful (commit: 9a446483)
4 years ago
Copr build
success (100%)
#1336239
4 years ago
jenkins
success (100%)
Build #20 successful (commit: 70c55b42)
4 years ago
jenkins
success (100%)
Build #19 successful (commit: 70c55b42)
4 years ago
jenkins
failure
Build #18 failed (commit: 70c55b42)
4 years ago
jenkins
success (100%)
Build #17 successful (commit: 70c55b42)
4 years ago
jenkins
failure
Build #16 failed (commit: 70c55b42)
4 years ago
jenkins
failure
Build #15 failed (commit: 70c55b42)
4 years ago
jenkins
failure
Build #14 failed (commit: 70c55b42)
4 years ago
jenkins
failure
Build #13 failed (commit: 70c55b42)
4 years ago
jenkins
failure
Build #12 failed (commit: 70c55b42)
4 years ago
jenkins
failure
Build #11 failed (commit: 70c55b42)
4 years ago
jenkins
failure
Build #10 failed (commit: 70c55b42)
4 years ago
jenkins
failure
Build #9 failed (commit: 70c55b42)
4 years ago
jenkins
failure
Build #8 failed (commit: 70c55b42)
4 years ago
jenkins
failure
Build #7 failed (commit: 70c55b42)
4 years ago
jenkins
failure
Build #6 failed (commit: 70c55b42)
4 years ago
jenkins
failure
Build #5 failed (commit: 70c55b42)
4 years ago
Copr build
success (100%)
#1334431
4 years ago
Copr build
success (100%)
#1334430
4 years ago
Copr build
success (100%)
#1333574
4 years ago