diff --git a/.github/workflows/python-cleanliness.yml b/.github/workflows/python-cleanliness.yml new file mode 100644 index 0000000000..97070e18e6 --- /dev/null +++ b/.github/workflows/python-cleanliness.yml @@ -0,0 +1,25 @@ +name: test Python cleanliness + +on: [push, pull_request, workflow_dispatch] + +concurrency: + group: ci-${{github.workflow}}-${{ github.ref }} + cancel-in-progress: true + +jobs: + build: + runs-on: ubuntu-22.04 + + steps: + # git checkout the PR + - uses: actions/checkout@v4 + with: + submodules: 'recursive' + + - name: Install dependencies + run: | + python -m pip install -U flake8 + + - name: Check Python with Flake8 + run: | + scripts/run_flake8.py MAVProxy diff --git a/MAVProxy/modules/mavproxy_fieldcheck/__init__.py b/MAVProxy/modules/mavproxy_fieldcheck/__init__.py index 07f8a2d985..a2662178ae 100755 --- a/MAVProxy/modules/mavproxy_fieldcheck/__init__.py +++ b/MAVProxy/modules/mavproxy_fieldcheck/__init__.py @@ -12,6 +12,9 @@ - ensure parameters are correct - add check that battery is within tolerances (chemistry issues...) - autodetect numcells being incorrect + +AP_FLAKE8_CLEAN + ''' import math @@ -31,6 +34,7 @@ from MAVProxy.modules.lib.mp_menu import MPMenuItem from MAVProxy.modules.lib.mp_menu import MPMenuSubMenu + class FieldCheck(object): def __init__(self): self.is_armed = False @@ -370,7 +374,7 @@ def idle_task(self): self.check_map_menu() def FC_MPSetting(self, name, atype, default, description): - xname = "fc_%s_%s" % (self.lc_name, name) + # xname = "fc_%s_%s" % (self.lc_name, name) return MPSetting(name, atype, default, description) def select(self): @@ -443,18 +447,22 @@ def cmd_fieldcheck(self, args): print(usage) return + class FieldCMAC(FieldCheck): lc_name = "cmac" location = mavutil.location(-35.363261, 149.165230, 584, 353) + class FieldSpringValley(FieldCheck): location = mavutil.location(-35.281315, 149.005329, 581, 280) lc_name = "springvalley" + class FieldSpringValleyBottom(FieldCheck): location = mavutil.location(-35.2824450, 149.0053668, 593, 0) lc_name = "springvalleybottom" + class FieldCheckModule(mp_module.MPModule): def __init__(self, mpstate): @@ -489,7 +497,6 @@ def try_select_field(self, loc): self.whinge("Selecting field (%s)" % field.lc_name) self.select_field(field) - def idle_task(self): '''run periodic tasks''' if self.field is not None: @@ -510,6 +517,7 @@ def mavlink_packet(self, m): return self.field.mavlink_packet(m) + def init(mpstate): '''initialise module''' return FieldCheckModule(mpstate) diff --git a/scripts/run_flake8.py b/scripts/run_flake8.py new file mode 100755 index 0000000000..bc0811c4da --- /dev/null +++ b/scripts/run_flake8.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python + +""" +Runs flake8 over Python files which contain a marker indicating +they are clean, ensures that they actually are + + AP_FLAKE8_CLEAN +""" + +import os +import subprocess +import sys + +import argparse + +os.environ['PYTHONUNBUFFERED'] = '1' + + +class Flake8Checker(object): + def __init__(self, basedirs): + self.retcode = 0 + self.files_to_check = [] + self.basedirs = basedirs + + def progress(self, string): + print("****** %s" % (string,)) + + def check(self): + if len(self.files_to_check) == 0: + return + for path in self.files_to_check: + self.progress("Checking (%s)" % path) + ret = subprocess.run(["flake8", "--show-source"] + self.files_to_check, + stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True) + if ret.returncode != 0: + self.progress("Flake8 check failed: (%s)" % (ret.stdout)) + self.retcode = 1 + + def run(self): + for basedir in self.basedirs: + for (dirpath, dirnames, filenames) in os.walk(basedir): + for filename in filenames: + if os.path.splitext(filename)[1] != ".py": + continue + filepath = os.path.join(dirpath, filename) + content = open(filepath).read() + if "AP_FLAKE8_CLEAN" not in content: + continue + self.files_to_check.append(filepath) + self.check() + return self.retcode + + +if __name__ == '__main__': + parser = argparse.ArgumentParser(description='Check all Python files for flake8 cleanliness') + parser.add_argument('DIRPATH', nargs="+", default=[], help='directory to recurse into') + args = parser.parse_args() + + checker = Flake8Checker(args.DIRPATH) + sys.exit(checker.run())