-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: ➖ fake pros c create-template (#1)
* feat: ➖ fake pros c create-template doing this means we do not need to install pros and thus makes the action faster * ⚗️ trigger ci test * ⚗️ test finding pros executable * ⚗️ echo $PATH * ⚗️ more prints * ⚗️ try using github env variables to set PATH * ⚗️ use $PATH instead * ⚗️ check pros executable permissions * ⚗️ add execute permissions * 🔇 cleanup debug logs
- Loading branch information
Showing
2 changed files
with
289 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,284 @@ | ||
#! /bin/env bash | ||
index=0 | ||
is_system_arg=0 | ||
is_target_arg=0 | ||
|
||
system_files='' | ||
|
||
path='' | ||
name='' | ||
version='' | ||
target='' | ||
debug=0 | ||
|
||
RED='\033[0;31m' | ||
YELLOW='\033[1;33m' | ||
PURPLE='\033[0;35m' | ||
RESET='\033[0m' | ||
|
||
debug_echo() { | ||
if [ $debug -eq 1 ]; then | ||
echo "$PURPLE[DEBUG]$RESET" $@ | ||
fi | ||
} | ||
|
||
error_echo() { | ||
echo -e "$RED[ERROR]$RESET" $@ >&2 | ||
} | ||
|
||
warning_echo() { | ||
echo -e "$YELLOW[WARN]$RESET" $@ >&2 | ||
} | ||
|
||
newline=" | ||
" | ||
|
||
for arg in "$@"; do | ||
if [ $is_system_arg -eq 1 ]; then | ||
for file in $arg; do | ||
system_files="$system_files$newline$file" | ||
done | ||
|
||
is_system_arg=0 | ||
continue | ||
fi | ||
|
||
if [ $is_target_arg -eq 1 ]; then | ||
target="$arg" | ||
if [ "$target" != "v5" -a "$target" != "cortex" ]; then | ||
echo "target must be of type v5 or cortex. Got: $target" | ||
exit 1 | ||
fi | ||
is_system_arg=0 | ||
continue | ||
fi | ||
|
||
if [ "$arg" == "--system" ]; then | ||
is_system_arg=1 | ||
continue | ||
fi | ||
|
||
if [ "$arg" == "--target" ]; then | ||
is_target_arg=1 | ||
continue | ||
fi | ||
|
||
if [ "$arg" == "--debug" ]; then | ||
debug=1 | ||
continue | ||
fi | ||
|
||
case $index in | ||
0) if [ "$arg" != "c" ]; then | ||
echo "Invalid argument: $arg" | ||
exit 1 | ||
fi ;; | ||
1) if [ "$arg" != "create-template" ]; then | ||
echo "Invalid argument: $arg" | ||
exit 1 | ||
fi ;; | ||
2) path="$arg" ;; | ||
3) name="$arg" ;; | ||
4) version="$arg" ;; | ||
*) echo "Invalid argument: $arg" ;; | ||
esac | ||
|
||
index=$((index + 1)) | ||
done | ||
|
||
debug_echo "path: $path" | ||
debug_echo "name: $name" | ||
debug_echo "version: $version" | ||
debug_echo "target: $target" | ||
|
||
if [ -z "$path" ]; then | ||
error_echo "Invalid argument: path" | ||
exit 1 | ||
fi | ||
if [ -z "$name" ]; then | ||
error_echo "Invalid argument: name" | ||
exit 1 | ||
fi | ||
if [ -z "$version" ]; then | ||
error_echo "Invalid argument: version" | ||
exit 1 | ||
fi | ||
if [ -z "$target" ]; then | ||
error_echo "Invalid argument: target" | ||
exit 1 | ||
fi | ||
|
||
destination="./$name@$version.zip" | ||
debug_echo "destination: $destination" | ||
|
||
kernel_version=$(cat "$path/project.pros" | jq -r '.["py/state"].templates?.kernel.version') | ||
|
||
if [ "$kernel_version" != "null" ]; then | ||
kernel_version="^$kernel_version"; | ||
fi | ||
|
||
debug_echo "kernel_version: $kernel_version"; | ||
|
||
# sort and remove duplicates | ||
system_files=$(echo "$system_files" | sort | uniq) | ||
|
||
# remove destination if it exists | ||
rm -f "$destination" | ||
|
||
# will be deleted after zipping | ||
tmp_files="" | ||
|
||
add_tmp_file() { | ||
tmp_files="$tmp_files $1" | ||
} | ||
|
||
find_index() { | ||
target="$1" | ||
array=($2) | ||
|
||
for i in "${!array[@]}"; do | ||
if echo "${array[$i]}" | grep -qFe "$target"; then | ||
echo "${i}"; | ||
return | ||
fi | ||
done | ||
echo "-1" | ||
} | ||
|
||
get_at_index() { | ||
index="$1" | ||
array=($2) | ||
echo ${array[$index]} | ||
} | ||
|
||
new_files="" | ||
old_files="" | ||
|
||
parse_zip_output() { | ||
local old_files=$(echo "$old_files" | sed 's%\./%%g') | ||
function parse_zip_output_line() { | ||
file=$(echo "$@" \ | ||
| sed "s/adding: //" \ | ||
| sed -E "s/\([^()]+\)//" \ | ||
| xargs) # trims whitespace | ||
|
||
index=$(find_index "$file" "$new_files") | ||
|
||
if [ "$index" = "-1" ]; then | ||
error_echo "File not found: $file" | ||
exit 4 | ||
fi | ||
|
||
old_file=$(get_at_index "$index" "$old_files") | ||
|
||
if [ "$old_file" != "$file" ]; then | ||
echo "S: $old_file -> $file" | ||
else | ||
echo "S: $file" | ||
fi | ||
} | ||
export -f parse_zip_output_line | ||
export -f get_at_index | ||
export -f find_index | ||
export new_files | ||
export old_files | ||
xargs -I{} bash -c 'parse_zip_output_line "$@"' _ {} | ||
} | ||
|
||
tmp_dir="/tmp/pros-fake" | ||
mkdir "$tmp_dir" | ||
|
||
add_tmp_file "$tmp_dir" | ||
|
||
# ensures that tmp files are deleted | ||
cleanup() { | ||
debug_echo "Cleaning up: $tmp_files" | ||
rm -Rf $tmp_files | ||
} | ||
|
||
# if prompted to exit early, make sure to cleanup | ||
trap "cleanup; exit 3" SIGINT | ||
|
||
add_to_zip() { | ||
old_path="$1" | ||
new_path="$2" | ||
is_tmp="$3" | ||
|
||
if [ -z "$new_path" ]; then | ||
new_path="$old_path" | ||
if [ -z "$is_tmp" ]; then | ||
is_tmp=1 | ||
fi | ||
else | ||
if [ -z "$is_tmp" ]; then | ||
if [ ! -e "$new_path" ]; then | ||
is_tmp=1 | ||
cp "$old_path" "$new_path" | ||
fi | ||
fi | ||
fi | ||
|
||
if [ "$is_tmp" = 1 ]; then | ||
add_tmp_file "$new_path" | ||
fi | ||
|
||
new_files="$new_files $new_path" | ||
old_files="$old_files $old_path" | ||
} | ||
|
||
# used to generate json | ||
system_files_strings="" | ||
|
||
# add system files to zip | ||
for path in $system_files; do | ||
# should only be different from $path if it is inside bin | ||
new_path=$(echo "$path" | sed 's/\.\/bin/\.\/firmware/') | ||
|
||
# if is bin, copy file into firmware | ||
if [ "$path" != "$new_path" ]; then | ||
if [ -e "$new_path" ]; then | ||
error_echo "File already exists: $new_path. Fatal error." | ||
cleanup | ||
exit 2 | ||
fi | ||
else | ||
if [ ! -f "$new_path" ]; then | ||
warning_echo "File not found: $path" | ||
continue | ||
fi | ||
fi | ||
|
||
add_to_zip "$path" "$new_path" | ||
|
||
system_files_strings="$system_files_strings"'"'"$new_path"'"'"$newline" | ||
done | ||
|
||
system_files_json="$(echo "$system_files_strings" | jq --slurp --compact-output "sort")" | ||
|
||
template_pros_target="$tmp_dir/template.pros" | ||
|
||
zip -9 "$destination" $new_files | parse_zip_output | ||
|
||
jq --null-input --tab --sort-keys \ | ||
--arg name "$name" \ | ||
--arg version "$version" \ | ||
--arg target "$target" \ | ||
--arg kernel_version "$kernel_version" \ | ||
--argjson sysfiles "$system_files_json" \ | ||
'{ | ||
"py/object": "pros.conductor.templates.external_template.ExternalTemplate", | ||
"py/state": { | ||
"name": $name, | ||
"version": $version, | ||
"target": $target, | ||
"supported_kernels": $kernel_version, | ||
"system_files": $sysfiles, | ||
"metadata": {}, | ||
"user_files": [] | ||
} | ||
}' > "$template_pros_target" | ||
add_tmp_file "$template_pros_target" | ||
|
||
zip -9qj "$destination" "$template_pros_target" | ||
|
||
cleanup |