-
Notifications
You must be signed in to change notification settings - Fork 0
/
platformio.patch.py
78 lines (61 loc) · 2.88 KB
/
platformio.patch.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# A small PlatformIO integration script (autogenerated by cargo-pio) that provides the capability to patch
# PlatformIO packages (or the platform itself) before the build is triggered
#
# How to use:
# Insert/update the following line in one of platformio.ini's environments:
# extra_scripts = pre:platformio.patch.py
# Specify a newline-separated list of patches to apply:
# patches = <pio-package-directory1>@<patch-file1> \n <pio-package-directory2>@<patch-file2>...
# ... where <patch-file-1>, <patch-file-2> etc. are expected to be placed in a 'patches/' folder of your project
#
# When <pio-package-directory> is equal to "__platform__", the platform itself will be patched
import os
import shutil
Import("env")
class Patch:
def run(self, env):
for (patch, patch_name, dir) in self.__patches_list(env):
self.__patch(env, patch, patch_name, dir)
def __patch(self, env, patch, patch_name, dir):
patch_flag = os.path.join(dir, f"{patch_name}.applied")
if not os.path.isfile(patch_flag):
# In recent PlatformIO, framework_espidf is no longer a true GIT repository
# (i.e. it does not contain a .git subfolder)
# As a result, "git apply" does not really work
#
# One workaround would've been to use `patch` instead of `git apply`,
# however `patch` does not seem to be available on Windows out of the box
#
# Therefore, instead we do a nasty hack here: we check if `dir`
# contains a `.git` folder, and if not we create it using "git init"
#
# Once the patch is applied, we remove the `.git` folder
git_dir = os.path.join(dir, ".git")
git_dir_exists = True
if not os.path.exists(git_dir):
if env.Execute("git init", chdir = dir):
env.Exit(1)
git_dir_exists = False
res = env.Execute(f"git apply {patch}", chdir = dir)
if not git_dir_exists:
shutil.rmtree(git_dir)
if res:
env.Exit(1)
self.__touch(patch_flag)
def __patches_list(self, env):
patches_dir = os.path.join(env.subst("$PROJECT_DIR"), "patches")
def get_patch(item):
dir, patch = item.split("@", 1)
package = dir.strip()
if package == "__platform__":
package_dir = env.PioPlatform().get_dir()
else:
package_dir = env.PioPlatform().get_package_dir(package)
return (
os.path.join(patches_dir, patch.strip()),
patch.strip(),
package_dir)
return [get_patch(item) for item in env.GetProjectOption("patches", default = "").split("\n") if len(item.strip()) > 0]
def __touch(self, path):
os.open(path, os.O_CREAT | os.O_RDWR)
Patch().run(env)