2023-11-07 20:25:54 +00:00
|
|
|
Import("env")
|
2023-11-17 18:28:40 +00:00
|
|
|
import os
|
|
|
|
import gzip
|
2024-12-20 22:02:54 +00:00
|
|
|
from shutil import copyfileobj, rmtree, copyfile, copytree
|
2023-11-17 18:28:40 +00:00
|
|
|
from pathlib import Path
|
2024-05-18 23:32:45 +00:00
|
|
|
import subprocess
|
|
|
|
|
2024-12-18 19:41:42 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
2024-05-18 23:32:45 +00:00
|
|
|
revision = (
|
|
|
|
subprocess.check_output(["git", "rev-parse", "HEAD"])
|
|
|
|
.strip()
|
|
|
|
.decode("utf-8")
|
|
|
|
)
|
2023-11-17 18:28:40 +00:00
|
|
|
|
|
|
|
def gzip_file(input_file, output_file):
|
|
|
|
with open(input_file, 'rb') as f_in:
|
|
|
|
with gzip.open(output_file, 'wb') as f_out:
|
|
|
|
copyfileobj(f_in, f_out)
|
|
|
|
|
|
|
|
def process_directory(input_dir, output_dir):
|
2023-11-17 19:14:28 +00:00
|
|
|
if os.path.exists(output_dir):
|
|
|
|
rmtree(output_dir)
|
2023-11-17 18:28:40 +00:00
|
|
|
for root, dirs, files in os.walk(input_dir):
|
|
|
|
relative_path = os.path.relpath(root, input_dir)
|
|
|
|
output_root = os.path.join(output_dir, relative_path)
|
|
|
|
|
|
|
|
Path(output_root).mkdir(parents=True, exist_ok=True)
|
|
|
|
|
|
|
|
for file in files:
|
2024-12-20 22:02:54 +00:00
|
|
|
# if not file.endswith(('.bin')):
|
2023-11-17 18:28:40 +00:00
|
|
|
input_file_path = os.path.join(root, file)
|
|
|
|
output_file_path = os.path.join(output_root, file + '.gz')
|
|
|
|
gzip_file(input_file_path, output_file_path)
|
|
|
|
print(f'Compressed: {input_file_path} -> {output_file_path}')
|
2024-05-18 23:32:45 +00:00
|
|
|
file_path = os.path.join(output_dir, "fs_hash.txt")
|
|
|
|
with open(file_path, "w") as file:
|
|
|
|
file.write(revision)
|
2023-11-17 18:28:40 +00:00
|
|
|
|
2023-11-07 20:25:54 +00:00
|
|
|
|
|
|
|
# Build web interface before building FS
|
|
|
|
def before_buildfs(source, target, env):
|
2024-12-20 22:02:54 +00:00
|
|
|
|
2023-11-30 19:58:37 +00:00
|
|
|
env.Execute("cd data && yarn && yarn postinstall && yarn build")
|
2023-11-17 18:28:40 +00:00
|
|
|
input_directory = 'data/dist'
|
|
|
|
output_directory = 'data/build_gz'
|
2024-12-20 22:02:54 +00:00
|
|
|
# copytree("assets", "data/dist/assets")
|
|
|
|
|
2023-11-17 18:28:40 +00:00
|
|
|
process_directory(input_directory, output_directory)
|
2023-11-07 20:25:54 +00:00
|
|
|
|
2024-12-20 22:02:54 +00:00
|
|
|
def get_fs_partition_size(env):
|
|
|
|
import csv
|
|
|
|
|
|
|
|
# Get partition table path - first try custom, then default
|
|
|
|
board_config = env.BoardConfig()
|
|
|
|
partition_table = board_config.get("build.partitions", "default.csv")
|
|
|
|
|
|
|
|
# Handle default partition table path
|
|
|
|
if partition_table == "default.csv" or partition_table == "huge_app.csv":
|
|
|
|
partition_table = os.path.join(env.PioPlatform().get_package_dir("framework-arduinoespressif32"),
|
|
|
|
"tools", "partitions", partition_table)
|
|
|
|
|
|
|
|
# Parse CSV to find spiffs/littlefs partition
|
|
|
|
with open(partition_table, 'r') as f:
|
|
|
|
for row in csv.reader(f):
|
|
|
|
if len(row) < 5:
|
|
|
|
continue
|
|
|
|
# Remove comments and whitespace
|
|
|
|
row = [cell.strip().split('#')[0] for cell in row]
|
|
|
|
# Check if this is a spiffs or littlefs partition
|
|
|
|
if row[0].startswith(('spiffs', 'littlefs')):
|
|
|
|
# Size is in hex format
|
|
|
|
return int(row[4], 16)
|
|
|
|
return 0
|
|
|
|
|
|
|
|
def get_littlefs_used_size(binary_path):
|
|
|
|
mklittlefs_path = os.path.join(env.PioPlatform().get_package_dir("tool-mklittlefs-rp2040-earlephilhower"), "mklittlefs")
|
|
|
|
|
|
|
|
try:
|
|
|
|
result = subprocess.run([mklittlefs_path, '-l', binary_path], capture_output=True, text=True)
|
|
|
|
|
|
|
|
if result.returncode == 0:
|
|
|
|
# Parse the output to sum up file sizes
|
|
|
|
total_size = 0
|
|
|
|
for line in result.stdout.splitlines():
|
|
|
|
if line.strip() and not line.startswith('<dir>') and not line.startswith('Creation'):
|
|
|
|
# Each line format: size filename
|
|
|
|
size = line.split()[0]
|
|
|
|
total_size += int(size)
|
|
|
|
return total_size
|
|
|
|
except Exception as e:
|
|
|
|
print(f"Error getting filesystem size: {e}")
|
|
|
|
return 0
|
|
|
|
|
|
|
|
|
|
|
|
def after_littlefs(source, target, env):
|
|
|
|
binary_path = str(target[0])
|
|
|
|
partition_size = get_fs_partition_size(env)
|
|
|
|
used_size = get_littlefs_used_size(binary_path)
|
|
|
|
|
|
|
|
percentage = (used_size / partition_size) * 100
|
|
|
|
bar_width = 50
|
|
|
|
filled = int(bar_width * percentage / 100)
|
|
|
|
bar = '=' * filled + '-' * (bar_width - filled)
|
|
|
|
|
|
|
|
print(f"\nLittleFS Actual Usage: [{bar}] {percentage:.1f}% ({used_size}/{partition_size} bytes)")
|
|
|
|
|
|
|
|
|
2024-12-18 19:41:42 +00:00
|
|
|
flash_size = env.BoardConfig().get("upload.flash_size", "4MB")
|
|
|
|
fs_image_name = f"littlefs_{flash_size}"
|
|
|
|
env.Replace(ESP32_FS_IMAGE_NAME=fs_image_name)
|
|
|
|
env.Replace(ESP8266_FS_IMAGE_NAME=fs_image_name)
|
|
|
|
|
2023-11-30 19:58:37 +00:00
|
|
|
os.environ["PUBLIC_BASE_URL"] = ""
|
2024-12-18 19:41:42 +00:00
|
|
|
fs_name = env.get("ESP32_FS_IMAGE_NAME", "littlefs.bin")
|
|
|
|
# Or alternatively:
|
|
|
|
# fs_name = env.get("FSTOOLNAME", "littlefs.bin")
|
|
|
|
|
|
|
|
# Use the variable in the pre-action
|
|
|
|
env.AddPreAction(f"$BUILD_DIR/{fs_name}.bin", before_buildfs)
|
2024-12-20 22:02:54 +00:00
|
|
|
env.AddPostAction(f"$BUILD_DIR/{fs_name}.bin", after_littlefs)
|
|
|
|
# LittleFS Actual Usage: [==============================--------------------] 60.4% (254165/420864 bytes)
|
|
|
|
# LittleFS Actual Usage: [==============================--------------------] 60.2% (253476/420864 bytes)
|
|
|
|
# 372736 used
|