Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LVGL Update Script #45

Open
wants to merge 39 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
4ffd8ec
Create clone and clean functions
unwieldycat Jun 11, 2024
eb632bd
Remove temp directory after cleaning template dir
unwieldycat Jun 11, 2024
0e5a93e
copy_lvgl_files function and simplify clone
unwieldycat Jun 11, 2024
42b5cf5
Remove repo argument and add wait function
unwieldycat Jun 11, 2024
088a62e
Delete lvgl source dir after files are copied
unwieldycat Jun 11, 2024
fd99b36
Add todos
unwieldycat Jun 11, 2024
a4aa68f
Keep llemu fonts
unwieldycat Jun 11, 2024
3bf6a08
Remove unused dependency
unwieldycat Jun 11, 2024
994458f
Fix includes function to make paths absolute
unwieldycat Jun 11, 2024
200f243
Improve fix_includes and use correct lvgl.h file
unwieldycat Jun 11, 2024
cc918d3
Improved (but broken) relative includes resolver
unwieldycat Jun 11, 2024
9554057
Improve fix_includes and add fixme
unwieldycat Jun 12, 2024
10ec4c2
Remove entry from TODO
unwieldycat Jun 12, 2024
8b01481
Ignore lv_font file, add another regex for changing paths, handle str…
unwieldycat Jun 12, 2024
a16eb60
Format with black and remove todos
unwieldycat Jun 12, 2024
eec6c93
Use pathlib functions instead of os
unwieldycat Jun 12, 2024
9a93b0b
Properly warn user if resolve_include_path fails
unwieldycat Jun 12, 2024
b9b47a9
Use copy instead of move in copy_lvgl_files and remove redundancy
unwieldycat Jun 12, 2024
e8c3050
Fix warning message formatting
unwieldycat Jun 13, 2024
9cd07cc
Improve output and create CLI
unwieldycat Jun 13, 2024
69e96de
Fix encoding error and fix clone output
unwieldycat Jun 18, 2024
97b236e
Add fixme message
unwieldycat Jun 18, 2024
59e3d77
Ignore errors when deleting lvgl source
unwieldycat Jun 18, 2024
f576976
Remove unused dependency
unwieldycat Jun 18, 2024
53710dd
Add more logging
unwieldycat Jun 18, 2024
1678ce4
Quit if clone fails
unwieldycat Jun 18, 2024
df75c3b
More error safeguards
unwieldycat Jun 18, 2024
dcfdc93
Windows permissionerror workaround
unwieldycat Jun 18, 2024
b681e05
Move configuration to top of file
unwieldycat Jun 18, 2024
df70294
Add colorized output
unwieldycat Jun 22, 2024
3aa8e27
Remove verbose argument
unwieldycat Jun 22, 2024
57d496c
Put lvgl repo in configuration
unwieldycat Jun 22, 2024
9ee3826
Fix error formatting
unwieldycat Jun 22, 2024
13de138
Use warn function for warning
unwieldycat Jun 22, 2024
f73e505
Don't overwrite files in keep_files
unwieldycat Jun 22, 2024
ea2d83b
Specify path format in comment
unwieldycat Jun 22, 2024
c5fea10
Consistent file path formatting
unwieldycat Jun 22, 2024
d1d2029
Add success message to end of script
unwieldycat Jun 22, 2024
e52f150
Order imports
unwieldycat Jun 22, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
217 changes: 217 additions & 0 deletions update.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
#!/usr/bin/env python3

################################ CONFIGURATION ################################

# Files that should persist in the template directory (as POSIX-formatted paths)
keep_files = [
"include/liblvgl/lv_conf.h",
"include/liblvgl/lv_conf.old.h",
"include/liblvgl/llemu.h",
"include/liblvgl/llemu.hpp",
"include/liblvgl/font/lv_font.h",
"src/liblvgl/display.c",
"src/liblvgl/llemu.c",
"src/liblvgl/llemu.cpp",
"src/liblvgl/lv_fonts/pros_font_dejavu_mono_10.c",
"src/liblvgl/lv_fonts/pros_font_dejavu_mono_18.c",
"src/liblvgl/lv_fonts/pros_font_dejavu_mono_30.c",
"src/liblvgl/lv_fonts/pros_font_dejavu_mono_40.c",
]

# URI to LVGL's source
lvgl_repo = "https://github.com/lvgl/lvgl.git"

############################# END OF CONFIGURATION #############################

from argparse import ArgumentParser
from os import chmod
from pathlib import Path
import re
import shutil
import stat
import subprocess

WARN_COLOR = "\033[1;33m"
ERR_COLOR = "\033[0;31m"
STEP_COLOR = "\033[1;37m"
MSG_COLOR = "\033[0;37m"
NO_COLOR = "\033[0m"


def warn(message):
print(f"{WARN_COLOR}WARNING: {MSG_COLOR}{message}{NO_COLOR}")


def error(message):
print(f"{ERR_COLOR}ERROR: {MSG_COLOR}{message}{NO_COLOR}")


def step(message):
print(f"{STEP_COLOR}- {message} -{NO_COLOR}")


def onexc_chmod(retry, path, err):
chmod(path, stat.S_IWUSR)
try:
retry(path)
except Exception as err:
error(f"Failed to rmtree with exception: {err}")


def clone(branch):
if Path("lvgl/").exists():
print("lvgl directory exists, attempting to remove before cloning...")
shutil.rmtree("lvgl/", onexc=onexc_chmod)

sub_proc = subprocess.Popen(
f"git clone -b {branch} {lvgl_repo} --recursive",
shell=True,
)
if sub_proc.wait() != 0:
error("Clone failed, exiting...")
exit(1)


def clean_template_dir():
print("Creating temp directory...")
Path("temp").mkdir(exist_ok=True)

print("Copying whitelisted files to temp directory...")
for file in keep_files:
if not Path(file).exists():
warn(f'Whitelisted file "{file}" does not exist')
keep_files.remove(file)
continue
output = Path(f"temp/{file}")
output.parent.mkdir(parents=True, exist_ok=True)
shutil.copy(file, output)

print("Removing template files...")
shutil.rmtree("include/liblvgl")
shutil.rmtree("src/liblvgl")

print("Copying whitelisted files back to template directories...")
for file in keep_files:
output = Path(file)
output.parent.mkdir(parents=True, exist_ok=True)
shutil.copy(f"temp/{file}", file)

print("Removing temp directory...")
shutil.rmtree("temp")


def copy_lvgl_files():
print("Getting lvgl files...")
lvgl_src = Path("lvgl/src").resolve()
header_files = list(lvgl_src.rglob("**/*.h"))
source_files = list(lvgl_src.rglob("**/*.c"))
files = header_files + source_files

print("Copying header and source files to respective directories...")
for file in files:
if file in header_files:
new_loc = Path(f"include/liblvgl/{file.relative_to(lvgl_src)}")
elif file in source_files:
new_loc = Path(f"src/liblvgl/{file.relative_to(lvgl_src)}")

if new_loc.as_posix() in keep_files:
print(f'Skipped overwriting whitelisted file "{new_loc}"')
continue

new_loc.parent.mkdir(parents=True, exist_ok=True)
shutil.copy(file, new_loc)
fix_includes(new_loc)

print("Swapping the proxy lvgl.h file with the full file...")
Path("include/liblvgl/lvgl.h").unlink(missing_ok=True)
shutil.copy("lvgl/lvgl.h", "include/liblvgl/lvgl.h")
fix_includes("include/liblvgl/lvgl.h")

print("Attempting to remove lvgl source...")
shutil.rmtree("lvgl/", onexc=onexc_chmod)


def fix_includes(file_path):
def resolve_include_path(match):
file = Path(file_path)
include_path = match.group(1)
resolved_path = file.parent.joinpath(include_path).resolve()

source_dir = Path.cwd().joinpath("src/")
include_dir = Path.cwd().joinpath("include/")

if resolved_path.is_relative_to(source_dir):
relative_path = resolved_path.relative_to(source_dir)
elif resolved_path.is_relative_to(include_dir):
relative_path = resolved_path.relative_to(include_dir)
else:
warn(
f'File "{file}" includes file "{include_path}",'
+ " which is outside of the src or include directory."
+ " Manual editing may be required."
)
relative_path = include_path

return f'#include "{relative_path}"'

with open(file_path, "r", encoding="utf-8") as file:
data = file.read()
data = re.sub(r"#include \"((?:\.\./)+.*\.h)\"", resolve_include_path, data)
data = re.sub(r"#include \"(src/|lvgl/)", '#include "liblvgl/', data)
data = re.sub(
r"(?<!LV_LVGL_H_INCLUDE_SIMPLE\n)(?:^[ \t]*(#include \"lvgl.h\")$)",
'#include "liblvgl/lvgl.h"',
data,
flags=re.M,
)

with open(file_path, "w", encoding="utf-8") as file:
file.write(data)


def main():
parser = ArgumentParser(
prog="./update.py",
description="A script to automatically update liblvgl from lvgl",
)
parser.add_argument(
"branch",
type=str,
help="branch to clone from lvgl's git repository",
)
parser.add_argument(
"-y",
"--yes",
action="store_true",
help="ignore initial warning",
)
args = parser.parse_args()

if not args.yes:
warn(
"Local changes may be deleted by this script."
+ " If you have made any changes, you should exit this script to"
+ " stash or commit them now."
)

print(
"The following liblvgl files will not be modified:\n "
+ "\n ".join(keep_files)
)

input("Press any key to continue...")

step("Clone LVGL")
clone(args.branch)

step("Remove old liblvgl files")
clean_template_dir()

step("Copy updated files")
copy_lvgl_files()

step("Successfully updated")


if __name__ == "__main__":
main()
Loading