Skip to content

Commit

Permalink
Added support for JSON merging during builds
Browse files Browse the repository at this point in the history
Signed-off-by: Ole Herman Schumacher Elgesem <[email protected]>
  • Loading branch information
olehermanse committed Apr 26, 2021
1 parent de395e9 commit a554946
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 26 deletions.
50 changes: 25 additions & 25 deletions cfbs/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@
pad_right,
write_json,
read_json,
merge_json,
mkdir,
rm,
cp,
sh,
)


Expand Down Expand Up @@ -138,31 +143,9 @@ def add_command(to_add: list) -> int:
put_definition(definition)


def sh(cmd: str, directory=None):
if directory:
os.system(f"( cd {directory} && {cmd} 1>/dev/null 2>/dev/null )")
return
os.system(f"{cmd} 1>/dev/null 2>/dev/null")


def mkdir(path: str):
os.system(f"mkdir -p {path}")


def rm(path: str):
os.system(f"rm -rf '{path}'")


def cp(src, dst):
if os.path.isfile(src):
os.system(f"rsync -r {src} {dst}")
return
os.system(f"rsync -r {src}/ {dst}")


def init_build_folder():
rm("build")
mkdir("build")
rm("out")
mkdir("out")
mkdir("out/masterfiles")
mkdir("out/steps")

Expand Down Expand Up @@ -227,7 +210,7 @@ def build_step(module, step, max_length):
src, dst = os.path.join(source, src), os.path.join(destination, dst)
cp(src, dst)
elif operation == "run":
shell_command = args
shell_command = " ".join(args)
print(f"{prefix} run '{shell_command}'")
sh(shell_command, source)
elif operation == "delete":
Expand All @@ -237,6 +220,21 @@ def build_step(module, step, max_length):
print(f"{prefix} delete {as_string}")
for file in files:
rm(file)
elif operation == "json":
src, dst = args
if dst in [".", "./"]:
dst = ""
print(f"{prefix} json '{src}' 'masterfiles/{dst}'")
src, dst = os.path.join(source, src), os.path.join(destination, dst)
extras, original = read_json(src), read_json(dst)
assert extras
if original:
merged = merge_json(original, extras)
else:
merged = extras
write_json(dst, merged)
else:
user_error(f"Unknown build step operation: {operation}")


def build_steps() -> int:
Expand All @@ -245,6 +243,8 @@ def build_steps() -> int:
for module in get_definition()["build"]:
for step in module["steps"]:
build_step(module, step, module_name_length)
if os.path.isfile("out/masterfiles/def.json"):
sh("prettier --write out/masterfiles/def.json")
print("Generating tarball...")
sh("( cd out/ && tar -czf masterfiles.tgz masterfiles )")
print("\nBuild complete, ready to deploy 🐿")
Expand Down
49 changes: 48 additions & 1 deletion cfbs/utils.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,34 @@
import os
import sys
import json
import copy
from collections import OrderedDict

import requests


def sh(cmd: str, directory=None):
if directory:
os.system(f"( cd {directory} && {cmd} 1>/dev/null 2>/dev/null )")
return
os.system(f"{cmd} 1>/dev/null 2>/dev/null")


def mkdir(path: str):
os.system(f"mkdir -p {path}")


def rm(path: str):
os.system(f'rm -rf "{path}"')


def cp(src, dst):
if os.path.isfile(src):
os.system(f"rsync -r {src} {dst}")
return
os.system(f"rsync -r {src}/ {dst}")


def pad_left(s, n) -> int:
return s if len(s) >= n else " " * (n - len(s)) + s

Expand Down Expand Up @@ -63,5 +87,28 @@ def read_json(path):


def write_json(path, data):
data = pretty(data)
data = pretty(data) + "\n"
return save_file(path, data)


def merge_json(a, b, overwrite_callback=None, stack=None):
if not stack:
stack = []
a, b = copy.deepcopy(a), copy.deepcopy(b)
for k, v in b.items():
if k not in a:
a[k] = v
elif isinstance(a[k], dict) and isinstance(v, dict):
a[k] = merge_json(a[k], v, overwrite_callback, [*stack, k])
elif type(a[k]) is not type(v):
if overwrite_callback:
overwrite_callback(k, stack, "type mismatch")
a[k] = v
elif type(v) is list:
a[k].extend(v)
else:
if overwrite_callback:
overwrite_callback(k, stack, "primitive overwrite")
a[k] = v

return a

0 comments on commit a554946

Please sign in to comment.