From 541acb45b87264b8af1dad5e92b3c389aa3c34fc Mon Sep 17 00:00:00 2001 From: odaki Date: Mon, 23 Mar 2020 19:52:41 +0900 Subject: [PATCH] Change Travis scripts to use python instead of bash --- .travis.yml | 26 ++---- Grbl_Esp32/config.h | 4 +- build-all.py | 9 +- build-machine.py | 7 +- builder.py | 1 + configure-features.py | 209 ++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 231 insertions(+), 25 deletions(-) create mode 100755 configure-features.py diff --git a/.travis.yml b/.travis.yml index 877f192a..1dd3cc6c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,5 @@ sudo: false -language: bash +language: python os: - linux @@ -12,25 +12,13 @@ install: - pip install --user -U pip - pip install --user -U platformio -before_script: - - cd $TRAVIS_BUILD_DIR - - chmod +x *.sh *.py script: - - cd $TRAVIS_BUILD_DIR - - sed -n '118,136p;137q' $TRAVIS_BUILD_DIR/Grbl_Esp32/config.h - - sed -i "s/\/\/#define ENABLE_BLUETOOTH/#define ENABLE_BLUETOOTH/g" $TRAVIS_BUILD_DIR/Grbl_Esp32/config.h - - sed -i "s/#define ENABLE_BLUETOOTH/\/\/#define ENABLE_BLUETOOTH/g" $TRAVIS_BUILD_DIR/Grbl_Esp32/config.h - - sed -i "s/\/\/#define ENABLE_WIFI/#define ENABLE_WIFI/g" $TRAVIS_BUILD_DIR/Grbl_Esp32/config.h - - sed -n '118,136p;137q' $TRAVIS_BUILD_DIR/Grbl_Esp32/config.h - - PLATFORMIO_BUILD_FLAGS=-DMACHINE_FILENAME=test_drive.h platformio run - - sed -i "s/\/\/#define ENABLE_BLUETOOTH/#define ENABLE_BLUETOOTH/g" $TRAVIS_BUILD_DIR/Grbl_Esp32/config.h - - sed -i "s/#define ENABLE_WIFI/\/\/#define ENABLE_WIFI/g" $TRAVIS_BUILD_DIR/Grbl_Esp32/config.h - - sed -n '118,136p;137q' $TRAVIS_BUILD_DIR/Grbl_Esp32/config.h - - PLATFORMIO_BUILD_FLAGS=-DMACHINE_FILENAME=test_drive.h platformio run - - sed -i "s/\/\/#define ENABLE_BLUETOOTH/#define ENABLE_BLUETOOTH/g" $TRAVIS_BUILD_DIR/Grbl_Esp32/config.h - - sed -i "s/\/\/#define ENABLE_WIFI/#define ENABLE_WIFI/g" $TRAVIS_BUILD_DIR/Grbl_Esp32/config.h - - sed -n '118,136p;137q' $TRAVIS_BUILD_DIR/Grbl_Esp32/config.h - - ./build-all.sh + - ./configure-features.py -e WIFI -d BLUETOOTH + - ./build-machine.py test_drive.h + - ./configure-features.py -e BLUETOOTH -d WIFI + - ./build-machine.py test_drive.h + - ./configure-features.py -e BLUETOOTH WIFI + - ./build-all.py notifications: email: diff --git a/Grbl_Esp32/config.h b/Grbl_Esp32/config.h index dbc96f38..0cb8d532 100644 --- a/Grbl_Esp32/config.h +++ b/Grbl_Esp32/config.h @@ -114,7 +114,7 @@ Some features should not be changed. See notes below. //Connect to your local AP with these credentials //#define CONNECT_TO_SSID "your SSID" //#define SSID_PASSWORD "your SSID password" - +//CONFIGURE_EYECATCH_BEGIN (DO NOT MODIFY THIS LINE) #define ENABLE_BLUETOOTH // enable bluetooth #define ENABLE_SD_CARD // enable use of SD Card to run jobs @@ -134,7 +134,7 @@ Some features should not be changed. See notes below. #define ENABLE_CAPTIVE_PORTAL //#define ENABLE_AUTHENTICATION - +//CONFIGURE_EYECATCH_END (DO NOT MODIFY THIS LINE) #define NAMESPACE "GRBL" #define ESP_RADIO_MODE "RADIO_MODE" diff --git a/build-all.py b/build-all.py index 502ed8d5..24c646df 100755 --- a/build-all.py +++ b/build-all.py @@ -21,9 +21,14 @@ cmd = ['platformio','run'] verbose = '-v' in sys.argv +numErrors = 0 adderBase = '3axis_v4.h' for name in os.listdir('Grbl_Esp32/Machines'): if name.startswith('add_'): - buildMachine(adderBase, addName=name, verbose=verbose) + exitCode = buildMachine(adderBase, addName=name, verbose=verbose) else: - buildMachine(name, verbose=verbose) + exitCode = buildMachine(name, verbose=verbose) + if exitCode != 0: + numErrors += 1 + +sys.exit(numErrors) diff --git a/build-machine.py b/build-machine.py index cb668d91..aa821e39 100755 --- a/build-machine.py +++ b/build-machine.py @@ -24,12 +24,15 @@ if '-u' in sys.argv: sys.argv.remove('-u') extraArgs = '--target=upload' +exitCode = 255 if len(sys.argv) == 2: - buildMachine(sys.argv[1], addName=None, verbose=verbose, extraArgs=extraArgs) + exitCode = buildMachine(sys.argv[1], addName=None, verbose=verbose, extraArgs=extraArgs) elif len(sys.argv) == 3: - buildMachine(sys.argv[1], addName=sys.argv[2], verbose=verbose, extraArgs=extraArgs) + exitCode = buildMachine(sys.argv[1], addName=sys.argv[2], verbose=verbose, extraArgs=extraArgs) else: print("Usage: ./build-machine.py [-q] [-u] machine_name.h [add_name.h]") print(' Build for the given machine and optional add-on regardless of machine.h') print(' -q suppresses most messages') print(' -u uploads to the target after compilation') + +sys.exit(exitCode) \ No newline at end of file diff --git a/builder.py b/builder.py index d9b09780..ba3bdb6a 100755 --- a/builder.py +++ b/builder.py @@ -30,3 +30,4 @@ def buildMachine(baseName, addName=None, verbose=True, extraArgs=None): print(line, end='') app.wait() print() + return app.returncode \ No newline at end of file diff --git a/configure-features.py b/configure-features.py new file mode 100755 index 00000000..81fa95f2 --- /dev/null +++ b/configure-features.py @@ -0,0 +1,209 @@ +#!/usr/bin/env python2 +# -*- coding: utf-8 -*- + +# Configure Grbl_ESP32 by specified options. +# This is useful for automated testing, to make sure you haven't broken something + +from __future__ import print_function +import os, sys, argparse, re + +configDirName = r'Grbl_Esp32' +configFileName = r'config.h' + +validFeatureList = [ + 'BLUETOOTH', + 'WIFI', + 'SD_CARD', + 'HTTP', + 'OTA', + 'TELNET', + 'TELNET_WELCOME_MSG', + 'MDNS', + 'SSDP', + 'NOTIFICATIONS', + 'SERIAL2SOCKET_IN', + 'SERIAL2SOCKET_OUT', + 'CAPTIVE_PORTAL', + 'AUTHENTICATION' + ] +eyecatchBeginString = 'CONFIGURE_EYECATCH_BEGIN' +eyecatchEndString = 'CONFIGURE_EYECATCH_END' +enablePrefix = 'ENABLE_' + +def printValidFeatureList(): + print("valid feature names:") + for n in sorted(validFeatureList): + print(" " + n) + +def usage(parser): + parser.print_usage() + printValidFeatureList() + sys.exit(255) + +def isValidFeature(feature): + if feature: + if feature.upper() in validFeatureList: + return True #valid + return False #invalid + +def checkFeatureList(optname, features, verbose=False): + if features: + for n in features: + if isValidFeature(n) is True: + if verbose: + print("valid " + optname + " feature: " + n) + else: + print("unknown " + optname + " feature: " + n) + return -1 + else: + if verbose: + print(optname + " is not specified") + return 0 + + return len(features) + +def resolveConflicts(high_priority, low_priority): + if low_priority: + for n in low_priority[:]: + if n in high_priority: + low_priority.remove(n) + return + +def readConfig(path): + # Read config.h to memory + try: + f = open(path) + except IOError: + print("unable to open file for read: " + path) + sys.exit(255) + else: + try: + src = f.readlines() + except IOError: + print("file read error: " + path) + f.close() + sys.exit(255) + else: + f.close() + return src + +def writeConfig(path, buf): + try: + f = open(path, 'w') + except IOError: + print("unable to open file for write: " + path) + sys.exit(255) + else: + try: + src = f.write(buf) + except IOError: + print("file write error: " + path) + f.close() + sys.exit(255) + else: + f.close() + +def main(): + # Concatinate dir and file + configFilePath = os.path.join(configDirName, configFileName) + + # Argument parser (-h is also available) + parser = argparse.ArgumentParser(description='Configure Grbl_ESP32 features') + parser.add_argument('-v', '--verbose', action='store_true') + parser.add_argument('-c', '--configfile', default=configFilePath) + parser.add_argument('-e', '--enable', nargs='*', help='specify feature name(ex. WIFI)' + #, choices=validFeatureList + ) + parser.add_argument('-d', '--disable', nargs='*', help='specify feature name(ex. BLUETOOTH)' + #,choices=validFeatureList + ) + args = parser.parse_args() + + # Set params to local variables + verbose = args.verbose + configFilePath = args.configfile + + # Copy and remove duplicates from enable/disable list + enabledFeatures = [] + disabledFeatures = [] + if args.enable: + enabledFeatures = sorted(set(args.enable), key=args.enable.index) + if args.disable: + disabledFeatures = sorted(set(args.disable), key=args.disable.index) + + # If both enable and disable are specified, treat as enable + # (Remove items from 2nd param if same item in 1st param) + resolveConflicts(enabledFeatures, disabledFeatures) + + # Verification (whether or not to use "choice" with argparse) + numEnables = checkFeatureList("-e", enabledFeatures, verbose) + numDisables = checkFeatureList("-d", disabledFeatures, verbose) + if verbose: + print("enables: ", numEnables) + print(enabledFeatures) + print("disables: ", numDisables) + print(disabledFeatures) + print("config file: " + configFilePath) + + # Final checking about args + if numEnables < 0 or numDisables < 0 or (numEnables == 0 and numDisables == 0): + usage(parser) + + # Check if the target file exists + configFilePathAbs = os.path.abspath(configFilePath) + if verbose: + print("full path: " + configFilePathAbs) + if not os.path.isfile(configFilePathAbs): + print("config file not found: " + configFilePathAbs) + sys.exit(255) + + # read config file + src = readConfig(configFilePathAbs) + + # Change the specified settings + regstart = re.compile(r'^\s*//\s*' + eyecatchBeginString) + regend = re.compile(r'^\s*//\s*' + eyecatchEndString) + dst = "" + status = 0; + for line in src: + if status == 0: + # out of the defines block to modify + if regstart.match(line): + status = 1 + dst += line + elif status == 1: + # in the defines block to modify + if regend.match(line): + # end of block found + status = 0 + dst += line + else: + dstLine = "" + if numEnables > 0: + for name in enabledFeatures: + s = enablePrefix + name + m = re.match(r'^s*//\s*#define\s+(' + s + r'.*)$', line) + if m: + dstLine = "#define " + m.group(1) + '\n' + break + if numDisables > 0: + for name in disabledFeatures: + s = enablePrefix + name + m = re.match(r'^\s*#define\s+' + s + r'.*$', line) + if m: + dstLine = "//" + line + break + if len(dstLine) != 0: + dst += dstLine + print(dstLine.rstrip()) + else: + dst += line + print(line.rstrip()) + + # Write back + writeConfig(configFilePathAbs, dst) + + sys.exit(0) + +if __name__ == "__main__": + main() \ No newline at end of file