diff --git a/.gitignore b/.gitignore index 761d5760..c983b021 100644 --- a/.gitignore +++ b/.gitignore @@ -17,11 +17,8 @@ .vscode/c_cpp_properties.json .vscode/launch.json _pycache_/ -code/html/build/ code/espurna/config/custom.h code/libraries/ code/node_modules -code/test/unit/cache -code/test/unit/build compile_commands.json firmware* diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0ae98c90..ffc7a720 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -8,7 +8,8 @@ Second. Let's try to keep it homogeneous and readable. I have my coding style. I * Do the pull request against the **`dev` branch** * **Only touch relevant files** (beware if your editor has auto-formatting feature enabled) * If you are adding a new functionality (new hardware, new library support) not related to an existing component move it to it's **own modules** (.cpp or .h file) -* If you are adding new library, include it in one of the **[sample test/build/\*.h profiles](https://github.com/xoseperez/espurna/tree/dev/code/test/build)**, so our integrated CI will try to compile it. +* If the code you are adding is optional or not always enabled, make sure to include and enable `*_SUPPORT` flag in one of the **[sample test/build/config/\*.h profiles](https://github.com/xoseperez/espurna/tree/dev/code/test/build/config)**. This would ensure that our CI would always build it. +* When it is possible, add a unit test or improve existing ones. See **[test/unit/src](https://github.com/xoseperez/espurna/tree/dev/code/test/unit/src)** * Make sure you check [Coding Style](https://github.com/xoseperez/espurna/wiki/CodingStyle) * PRs that don't compile or cause more coding errors will not be merged. Please fix the issue. Same goes for PRs that are raised against older commit in dev - you might need to rebase and resolve conflicts. diff --git a/code/html/.gitignore b/code/html/.gitignore new file mode 100644 index 00000000..567609b1 --- /dev/null +++ b/code/html/.gitignore @@ -0,0 +1 @@ +build/ diff --git a/code/scripts/test_build.py b/code/scripts/test_build.py index 6950564a..0f4bcac1 100755 --- a/code/scripts/test_build.py +++ b/code/scripts/test_build.py @@ -29,6 +29,16 @@ logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(mess log = logging.getLogger("main") +PWD = pathlib.Path(__file__).resolve().parent + +ROOT_PATH = (PWD / "..").resolve() +TEST_PATH = (ROOT_PATH / "test" / "build").resolve() + +CONFIG_PATH = TEST_PATH / "config" +CACHE_PATH = TEST_PATH / "cache" +BUILD_PATH = ROOT_PATH / ".pio" / "build" + + def bold(string): return clr(Color.BOLD, string) @@ -46,20 +56,19 @@ def pluralize(string, length): def build_configurations(args, configurations): cmd = ["platformio", "run"] - if not args.no_silent: + if args.silent: cmd.extend(["-s"]) cmd.extend(["-e", args.environment]) build_time = datetime.timedelta(seconds=0) - while len(configurations): + while configurations: cfg = configurations.pop() - with open(cfg, "r") as contents: - log.info("%s contents\n%s", bold(cfg), contents.read()) + log.info("%s contents\n%s", bold(cfg.name), cfg.read_text()) os_env = os.environ.copy() - os_env["PLATFORMIO_BUILD_CACHE_DIR"] = "test/pio_cache" - if not args.no_single_source: + os_env["PLATFORMIO_BUILD_CACHE_DIR"] = args.cache_path.resolve().as_posix() + if args.single_source: os_env["ESPURNA_BUILD_SINGLE_SOURCE"] = "1" os_env["PLATFORMIO_BUILD_SRC_FLAGS"] = " ".join( @@ -73,9 +82,8 @@ def build_configurations(args, configurations): build_start = time.time() try: subprocess.check_call(cmd, env=os_env) - except subprocess.CalledProcessError as e: + except subprocess.CalledProcessError: log.error("%s failed to build", bold(cfg)) - log.exception(e) if configurations: log.info( "%s %s left\n%s", @@ -87,9 +95,7 @@ def build_configurations(args, configurations): diff = datetime.timedelta(seconds=time.time() - build_start) - firmware_bin = pathlib.Path(".pio/build").joinpath( - args.environment, "firmware.bin" - ) + firmware_bin = args.build_path / args.environment / "firmware.bin" log.info( "%s finished in %s, %s is %s bytes", @@ -107,20 +113,28 @@ def main(args): log.error("No environment selected") return - log.info("Using env:%s", bold(args.environment)) + log.info("Using [env:%s]", bold(args.environment)) - configurations = [] - if not args.no_default: - configurations = list(pathlib.Path(".").glob(args.default_configurations)) - if args.start_from: - try: - offset = configurations.index(pathlib.Path(args.start_from)) - configurations = configurations[offset:] - except ValueError: - pass + configurations = [pathlib.Path(x) for x in args.configurations] + if not configurations: + configurations = [x for x in args.config_path.glob("*.h")] - if args.add: - configurations.extend(args.add) + configurations = [x.resolve() for x in configurations] + + if args.start_from: + offset = 0 + for n, p in enumerate(configurations, start=1): + if args.start_from in p.name: + offset = n + break + + if offset: + for cfg in configurations[offset:]: + log.info("Skipping %s", cfg) + configurations = configurations[:offset] + + if args.filter: + configurations = [p for p in configurations for f in args.filter if f in p.name] if not configurations: log.error("No configurations selected") @@ -133,52 +147,74 @@ def main(args): format_configurations(configurations), ) - if not args.no_build: + if args.build: build_configurations(args, configurations) if __name__ == "__main__": - parser = argparse.ArgumentParser() - parser.add_argument( - "-n", - "--no-default", - action="store_true", - help="Do not use default configurations (--default-configurations=...)", + parser = argparse.ArgumentParser( + formatter_class=argparse.ArgumentDefaultsHelpFormatter ) - - parser.add_argument( - "-a", - "--add", - type=pathlib.Path, - action="append", - help="Add path to selected configurations (can specify multiple times)", - ) - parser.add_argument("-e", "--environment", help="PIO environment") - parser.add_argument( - "--default-configurations", - default="test/build/*.h", - help="(glob) default configuration headers", - ) - parser.add_argument( "--start-from", - help="When using default configuration, skip everything until this name", + help="Skip configurations until this string is found in configuration filename", + default="", ) parser.add_argument( - "--no-silent", action="store_true", help="Do not silence pio-run" + "--filter", + action="append", + help="Only build configurations with filenames containing this string", ) parser.add_argument( - "--no-single-source", action="store_true", help="Disable 'unity' build" + "--silent", + default=True, + action=argparse.BooleanOptionalAction, + help="Silence PlatformIO output", ) parser.add_argument( - "--no-build", - action="store_true", - help="Stop after listing the available configurations", + "--single-source", + action=argparse.BooleanOptionalAction, + default=True, + help="Use SCons 'unity' build", + ) + + parser.add_argument( + "--build", + action=argparse.BooleanOptionalAction, + default=True, + help="Build specified configurations", + ) + + parser.add_argument( + "--config-path", + default=CONFIG_PATH, + type=pathlib.Path, + help="Directory with build test configuration headers", + ) + + parser.add_argument( + "--cache-path", + default=CACHE_PATH, + type=pathlib.Path, + help="PlatformIO SCons cache path", + ) + + parser.add_argument( + "--build-path", + default=BUILD_PATH, + type=pathlib.Path, + help="PlatformIO build path", + ) + + parser.add_argument( + "configurations", + nargs="*", + default=[], ) main(parser.parse_args()) diff --git a/code/test/.gitignore b/code/test/.gitignore index c8be6ce1..b6cc2b2d 100644 --- a/code/test/.gitignore +++ b/code/test/.gitignore @@ -1 +1,3 @@ -pio_cache +build/cache +unit/cache +unit/build diff --git a/code/test/build/basic.h b/code/test/build/config/basic.h similarity index 100% rename from code/test/build/basic.h rename to code/test/build/config/basic.h diff --git a/code/test/build/emon.h b/code/test/build/config/emon.h similarity index 100% rename from code/test/build/emon.h rename to code/test/build/config/emon.h diff --git a/code/test/build/garland.h b/code/test/build/config/garland.h similarity index 100% rename from code/test/build/garland.h rename to code/test/build/config/garland.h diff --git a/code/test/build/light_dimmer.h b/code/test/build/config/light_dimmer.h similarity index 100% rename from code/test/build/light_dimmer.h rename to code/test/build/config/light_dimmer.h diff --git a/code/test/build/light_my92xx.h b/code/test/build/config/light_my92xx.h similarity index 100% rename from code/test/build/light_my92xx.h rename to code/test/build/config/light_my92xx.h diff --git a/code/test/build/light_tuya.h b/code/test/build/config/light_tuya.h similarity index 100% rename from code/test/build/light_tuya.h rename to code/test/build/config/light_tuya.h diff --git a/code/test/build/minimal.h b/code/test/build/config/minimal.h similarity index 100% rename from code/test/build/minimal.h rename to code/test/build/config/minimal.h diff --git a/code/test/build/minimal_webui.h b/code/test/build/config/minimal_webui.h similarity index 100% rename from code/test/build/minimal_webui.h rename to code/test/build/config/minimal_webui.h diff --git a/code/test/build/nondefault.h b/code/test/build/config/nondefault.h similarity index 100% rename from code/test/build/nondefault.h rename to code/test/build/config/nondefault.h diff --git a/code/test/build/rfbridge.h b/code/test/build/config/rfbridge.h similarity index 100% rename from code/test/build/rfbridge.h rename to code/test/build/config/rfbridge.h diff --git a/code/test/build/secure_client.h b/code/test/build/config/secure_client.h similarity index 100% rename from code/test/build/secure_client.h rename to code/test/build/config/secure_client.h diff --git a/code/test/build/sensor.h b/code/test/build/config/sensor.h similarity index 100% rename from code/test/build/sensor.h rename to code/test/build/config/sensor.h