diff --git a/pio-tools/gzip-firmware.py b/pio-tools/gzip-firmware.py index fac23cf2d..63394789e 100644 --- a/pio-tools/gzip-firmware.py +++ b/pio-tools/gzip-firmware.py @@ -1,33 +1,32 @@ -Import('env') +Import("env") import os import shutil import gzip +import pathlib -platform = env.PioPlatform() -board = env.BoardConfig() -mcu = board.get("build.mcu", "esp32") +import tasmotapiolib -OUTPUT_DIR = "build_output{}".format(os.path.sep) def map_gzip(source, target, env): - variant = str(target[0]).split(os.path.sep)[2] - # create string with location and file names based on variant - bin_file = "{}map{}{}.map".format(OUTPUT_DIR, os.path.sep, variant) + map_file = tasmotapiolib.get_final_map_path(env) - if os.path.isfile(bin_file): - gzip_file = "{}map{}{}.map.gz".format(OUTPUT_DIR, os.path.sep, variant) + if map_file.is_file(): + gzip_file = map_file.with_suffix(".map.gz") # check if new target map files exist and remove if necessary - if os.path.isfile(gzip_file): os.remove(gzip_file) + if gzip_file.is_file(): + gzip_file.unlink() # write gzip map file - with open(bin_file,"rb") as fp: - with gzip.open(gzip_file, "wb", compresslevel = 9) as f: + with map_file.open("rb") as fp: + with gzip.open(gzip_file, "wb", compresslevel=9) as f: shutil.copyfileobj(fp, f) # remove map file - if os.path.isfile(bin_file): os.remove(bin_file) + if map_file.is_file(): + map_file.unlink() + env.AddPostAction("$BUILD_DIR/${PROGNAME}.bin", [map_gzip]) @@ -35,26 +34,35 @@ env.AddPostAction("$BUILD_DIR/${PROGNAME}.bin", [map_gzip]) if env["PIOPLATFORM"] != "espressif32": def bin_gzip(source, target, env): - variant = str(target[0]).split(os.path.sep)[2] - # create string with location and file names based on variant - bin_file = "{}firmware{}{}.bin".format(OUTPUT_DIR, os.path.sep, variant) - gzip_file = "{}firmware{}{}.bin.gz".format(OUTPUT_DIR, os.path.sep, variant) + bin_file = tasmotapiolib.get_final_bin_path(env) + gzip_file = bin_file.with_suffix(".bin.gz") # check if new target files exist and remove if necessary - if os.path.isfile(gzip_file): os.remove(gzip_file) + if os.path.isfile(gzip_file): + os.remove(gzip_file) # write gzip firmware file - with open(bin_file,"rb") as fp: - with gzip.open(gzip_file, "wb", compresslevel = 9) as f: + with open(bin_file, "rb") as fp: + with gzip.open(gzip_file, "wb", compresslevel=9) as f: shutil.copyfileobj(fp, f) - ORG_FIRMWARE_SIZE = os.stat(bin_file).st_size - GZ_FIRMWARE_SIZE = os.stat(gzip_file).st_size + ORG_FIRMWARE_SIZE = bin_file.stat().st_size + GZ_FIRMWARE_SIZE = gzip_file.stat().st_size if ORG_FIRMWARE_SIZE > 995326: - print("\u001b[31;1m!!! Tasmota firmware size is too big with {} bytes. Max size is 995326 bytes !!! \u001b[0m".format(ORG_FIRMWARE_SIZE)) + print( + "\u001b[31;1m!!! Tasmota firmware size is too big with {} bytes. Max size is 995326 bytes !!! \u001b[0m".format( + ORG_FIRMWARE_SIZE + ) + ) else: - print("Compression reduced firmware size by {:.0f}% (was {} bytes, now {} bytes)".format((GZ_FIRMWARE_SIZE / ORG_FIRMWARE_SIZE) * 100, ORG_FIRMWARE_SIZE, GZ_FIRMWARE_SIZE)) + print( + "Compression reduced firmware size by {:.0f}% (was {} bytes, now {} bytes)".format( + (GZ_FIRMWARE_SIZE / ORG_FIRMWARE_SIZE) * 100, + ORG_FIRMWARE_SIZE, + GZ_FIRMWARE_SIZE, + ) + ) env.AddPostAction("$BUILD_DIR/${PROGNAME}.bin", [bin_gzip]) diff --git a/pio-tools/name-firmware.py b/pio-tools/name-firmware.py index ce6ee0339..b49def236 100644 --- a/pio-tools/name-firmware.py +++ b/pio-tools/name-firmware.py @@ -1,54 +1,27 @@ -Import('env') -Import('projenv') +Import("env") +Import("projenv") import os import shutil +import pathlib + +import tasmotapiolib -OUTPUT_DIR = "build_output{}".format(os.path.sep) def bin_map_copy(source, target, env): - variant = str(target[0]).split(os.path.sep)[2] + firsttarget = pathlib.Path(target[0].path) - # check if output directories exist and create if necessary - if not os.path.isdir(OUTPUT_DIR): - os.mkdir(OUTPUT_DIR) - - for d in ['firmware', 'map']: - if not os.path.isdir("{}{}".format(OUTPUT_DIR, d)): - os.mkdir("{}{}".format(OUTPUT_DIR, d)) - - # create string with location and file names based on variant - map_file = "{}map{}{}.map".format(OUTPUT_DIR, os.path.sep, variant) - bin_file = "{}firmware{}{}.bin".format(OUTPUT_DIR, os.path.sep, variant) + # get locations and file names based on variant + map_file = tasmotapiolib.get_final_map_path(env) + bin_file = tasmotapiolib.get_final_bin_path(env) # check if new target files exist and remove if necessary for f in [map_file, bin_file]: - if os.path.isfile(f): - os.remove(f) + if f.is_file(): + f.unlink() - # copy firmware.bin to firmware/.bin - shutil.copy(str(target[0]), bin_file) + # copy firmware.bin and map to final destination + shutil.copy(firsttarget, bin_file) + shutil.move(tasmotapiolib.get_source_map_path(env), map_file) - # move firmware.map to map/.map - if os.path.isfile("firmware.map"): - shutil.move("firmware.map", map_file) - #map_new_loc = str(target[0]).split(os.path.sep)[0] + os.path.sep + str(target[0]).split(os.path.sep)[1] + os.path.sep + str(target[0]).split(os.path.sep)[2] + os.path.sep + "Tasmota.map" - # PIO env variables see: https://github.com/platformio/platformio-core/blob/develop/platformio/builder/main.py#L108:L128 - proj_build_dir = env["PROJECT_BUILD_DIR"] - #build_dir = env["BUILD_DIR"] - pio_env = env["PIOENV"] - proj_dir = env["PROJECT_DIR"] - map_name = str(proj_dir).split(os.path.sep)[-1] - map_new_loc = proj_build_dir + os.path.sep + pio_env + os.path.sep + map_name + ".map" - #print("proj_build_dir: {}".format(proj_build_dir)) - #print("pioenv: {}".format(pio_env)) - #print("build_dir: {}".format(build_dir)) - #print("map_name: {}".format(map_name)) - #print("proj_dir: {}".format(proj_dir)) - #print("map_new_loc: {}".format(map_new_loc)) - - # move Tasmota.map to map/.map - if os.path.isfile(map_new_loc): - shutil.move(map_new_loc, map_file) - -env.AddPostAction("$BUILD_DIR/${PROGNAME}.bin", [bin_map_copy]) +env.AddPostAction("$BUILD_DIR/${PROGNAME}.bin", bin_map_copy) diff --git a/pio-tools/tasmotapiolib.py b/pio-tools/tasmotapiolib.py new file mode 100644 index 000000000..52ce83c9a --- /dev/null +++ b/pio-tools/tasmotapiolib.py @@ -0,0 +1,49 @@ +"""Supporting library for pio-tools scripts""" +import pathlib + +OUTPUT_DIR = pathlib.Path("build_output") + + +def get_variant(env) -> str: + """Get the current build variant.""" + return env["PIOENV"] + + +def get_final_bin_path(env) -> pathlib.Path: + """Path to the final destination for the .bin + + If the parent directory does not exist, it will be created""" + firmware_dir = OUTPUT_DIR / "firmware" + firmware_dir.mkdir(parents=True, exist_ok=True) + return firmware_dir / "{}.bin".format(get_variant(env)) + + +def get_final_map_path(env) -> pathlib.Path: + """Path to the final destination for the .map file + + If the parent directory does not exist, it will be created""" + map_dir = OUTPUT_DIR / "map" + map_dir.mkdir(parents=True, exist_ok=True) + return map_dir / "{}.map".format(get_variant(env)) + + +def get_source_map_path(env) -> pathlib.Path: + """Path to the built .map file. + + Tests potential locations, returning the first match. + Raises FileNotFoundError if no match found""" + fwmap_path = pathlib.Path("firmware.map") + if fwmap_path.is_file(): + return fwmap_path + + # firmware maybe in project build directory + # PIO env variables see: https://github.com/platformio/platformio-core/blob/develop/platformio/builder/main.py#L108:L128 + proj_build_dir = pathlib.Path(env["PROJECT_BUILD_DIR"]) + proj_dir = pathlib.Path(env["PROJECT_DIR"]) + map_name = proj_dir.parts[-1] + ".map" + fwmap_path = proj_build_dir / get_variant(env) / map_name + + if fwmap_path.is_file(): + return fwmap_path + + raise FileNotFoundError