Skip to content

Commit

Permalink
🔨 Python config helpers (#27483)
Browse files Browse the repository at this point in the history
  • Loading branch information
thinkyhead authored Oct 19, 2024
1 parent cf137cb commit 4e41ff3
Show file tree
Hide file tree
Showing 7 changed files with 164 additions and 112 deletions.
Empty file added buildroot/bin/__init__.py
Empty file.
96 changes: 96 additions & 0 deletions buildroot/bin/config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
'''
config.py - Helper functions for config manipulation
'''
import re

FILES = ('Marlin/Configuration.h', 'Marlin/Configuration_adv.h')

def set(file_path, define_name, value):
'''
Replaces a define in a file with a new value.
Returns True if the define was found and replaced, False otherwise.
'''
# Read the contents of the file
with open(file_path, 'r') as f:
content = f.readlines()

modified = False
for i in range(len(content)):
# Regex to match the desired pattern
match = re.match(r'^(\s*)(/*)(\s*)(#define\s+{})\s+(.*)$'.format(re.escape(define_name)), content[i])
if match:
new_line = f"{match[1]}{match[3]}{match[4]} {value} // {match[5]}\n"
content[i] = new_line
modified = True

# Write the modified content back to the file only if changes were made
if modified:
with open(file_path, 'w') as f:
f.writelines(content)
return True

return False

def add(file_path, define_name, value=""):
'''
Insert a define on the first blank line in a file.
Returns True if the define was found and replaced, False otherwise.
'''
with open(file_path, 'r') as f:
content = f.readlines()

# Prepend a space to the value if it's not empty
if value != "":
value = " " + value

# Find the first blank line to insert the new define
for i in range(len(content)):
if content[i].strip() == '':
# Insert the define at the first blank line
content.insert(i, f"#define {define_name}{value}\n")
break
else:
# If no blank line is found, append to the end
content.append(f"#define {define_name}{value}\n")

with open(file_path, 'w') as f:
f.writelines(content)

def enable(file_path, define_name, enable=True):
'''
Uncomment or comment the named defines in the given file path.
Returns True if the define was found, False otherwise.
'''
# Read the contents of the file
with open(file_path, 'r') as f:
content = f.readlines()

# Prepare the regex
regex = re.compile(r'^(\s*)(/*)(\s*)(#define\s+{}\b.*?)( *//.*)?$'.format(re.escape(define_name)))

# Find the define in the file and uncomment or comment it
found = False
modified = False
for i in range(len(content)):
match = regex.match(content[i])
if not match: continue
found = True
if enable:
if match[2]:
modified = True
comment = '' if match[5] is None else ' ' + match[5]
content[i] = f"{match[1]}{match[3]}{match[4]}{comment}\n"
else:
if not match[2]:
modified = True
comment = '' if match[5] is None else match[5]
if comment.startswith(' '): comment = comment[2:]
content[i] = f"{match[1]}//{match[3]}{match[4]}{comment}\n"
break

# Write the modified content back to the file only if changes were made
if modified:
with open(file_path, 'w') as f:
f.writelines(content)

return found
12 changes: 10 additions & 2 deletions buildroot/bin/opt_add
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
#!/usr/bin/env bash
#!/usr/bin/env python

eval "echo '#define ${@}' | cat - Marlin/Configuration.h > temp && mv temp Marlin/Configuration.h"
import sys, config

def main():
args = sys.argv[1:]
for name in args:
config.add(config.FILES[0], name)

if __name__ == "__main__":
main()
51 changes: 18 additions & 33 deletions buildroot/bin/opt_disable
Original file line number Diff line number Diff line change
@@ -1,36 +1,21 @@
#!/usr/bin/env bash
#!/usr/bin/env python

# exit on first failure
set -e
import sys, os,config

# Get SED_CMD, SED_I, and the BSDSED flag
. $(dirname $0)/opt_sed
def main():
args = sys.argv[1:]

for opt in "$@" ; do
DID=0 ; FOUND=0
for FN in Marlin/Configuration.h Marlin/Configuration_adv.h; do
if [[ $BSDSED ]]; then
# BSD sed version (macOS)
"${SED_CMD}" "${SED_I[@]}" \
"/^[[:space:]]*#define[[:space:]]+${opt}\b/{
s/^[[:space:]]*\(#define[[:space:]]+${opt}\b.*\)/\/\/\1/
h
\$b end
}
\$!b
:end
x
/./{ x; q0; }
x
q1" \
$FN && DID=1
else
# GNU sed version
"${SED_CMD}" "${SED_I[@]}" \
"/^\(\s*\)\(#define\s\+${opt}\b\s\?\)\(\s\s\)\?/{s//\1\/\/\2/;h};\${x;/./{x;q0};x;q1}" \
$FN && DID=1
fi
((DID||FOUND)) || { grep -E "^\s*\/\/#define\s+${opt}\b" $FN >/dev/null && FOUND=1 ; }
done
((DID||FOUND)) || (echo "ERROR: $(basename $0) Can't find ${opt}" >&2 && exit 9)
done
for name in args:
changed = False

for file in config.FILES:
if os.path.exists(file):
if config.enable(file, name, False):
changed = True

if not changed:
print(f"ERROR: Can't find {name}")
exit(1)

if __name__ == "__main__":
main()
51 changes: 18 additions & 33 deletions buildroot/bin/opt_enable
Original file line number Diff line number Diff line change
@@ -1,36 +1,21 @@
#!/usr/bin/env bash
#!/usr/bin/env python

# exit on first failure
set -e
import sys, os,config

# Get SED_CMD, SED_I, and the BSDSED flag
. $(dirname $0)/opt_sed
def main():
args = sys.argv[1:]

for opt in "$@" ; do
DID=0 ; FOUND=0
for FN in Marlin/Configuration.h Marlin/Configuration_adv.h; do
if [[ $BSDSED ]]; then
# BSD sed version (macOS)
"${SED_CMD}" "${SED_I[@]}" \
"/^[[:space:]]*\/\/[[:space:]]*#define[[:space:]]+${opt}\b/{
s/^[[:space:]]*\/\/[[:space:]]*\(#define[[:space:]]+${opt}\b\)[[:space:]]*/\1 /
h
\$b end
}
\$!b
:end
x
/./{ x; q0; }
x
q1" \
$FN && DID=1
else
# GNU sed version
"${SED_CMD}" "${SED_I[@]}" \
"/^\(\s*\)\/\/\(\s*\)\(#define\s\+${opt}\b\)\( \?\)/{s//\1\2\3\4\4\4/;h};\${x;/./{x;q0};x;q1}" \
$FN && DID=1
fi
((DID||FOUND)) || { grep -E "^\s*#define\s+${opt}\b" $FN >/dev/null && FOUND=1 ; }
done
((DID||FOUND)) || (echo "ERROR: $(basename $0) Can't find ${opt}" >&2 && exit 9)
done
for name in args:
changed = False

for file in config.FILES:
if os.path.exists(file):
if config.enable(file, name):
changed = True

if not changed:
print(f"ERROR: Can't find {name}")
exit(1)

if __name__ == "__main__":
main()
9 changes: 0 additions & 9 deletions buildroot/bin/opt_sed

This file was deleted.

57 changes: 22 additions & 35 deletions buildroot/bin/opt_set
Original file line number Diff line number Diff line change
@@ -1,38 +1,25 @@
#!/usr/bin/env bash
#!/usr/bin/env python

# exit on first failure
set -e
import sys, os, config

# Get SED_CMD, SED_I, and the BSDSED flag
. $(dirname $0)/opt_sed
def main():
args = sys.argv[1:]
if len(args) % 2 != 0:
print("ERROR: Please provide pairs of <name> <value>")
return

while [[ $# > 1 ]]; do
DID=0
for FN in Marlin/Configuration.h Marlin/Configuration_adv.h; do
if [[ $BSDSED ]]; then
# BSD sed version (macOS)
$SED_CMD "${SED_I[@]}" \
"/^[[:space:]]*\/\{0,2\}[[:space:]]*#define[[:space:]]+${1}\b/{
s/^[[:space:]]*\/\{0,2\}[[:space:]]*\(#define[[:space:]]+${1}\b\)[[:space:]]*.*/\1 ${2} \/\/ &/
h
\$b end
}
\$!b
:end
x
/./{ x; q0; }
x
q1" \
$FN && DID=1
else
# GNU sed version
$SED_CMD "${SED_I[@]}" \
"/^\(\s*\)\/\{0,2\}\s*\(#define\s\+${1}\b\)\s*\(.*\)$/{s//\1\2 ${2} \/\/ \3/;h};\${x;/./{x;q0};x;q1}" \
$FN && DID=1
fi
done
((DID)) ||
eval "echo '#define ${1} ${2}' >>Marlin/Configuration.h" ||
(echo "ERROR: opt_set Can't set or add ${1}" >&2 && exit 9)
shift 2
done
for i in range(0, len(args), 2):
name = args[i]
value = args[i + 1]
changed = False

for file in config.FILES:
if os.path.exists(file):
if config.set(file, name, value):
changed = True

if not changed:
config.add(config.FILES[0], name, value)

if __name__ == "__main__":
main()

0 comments on commit 4e41ff3

Please sign in to comment.