Skip to content

Commit

Permalink
feat: ✨ many features + fix --no-compress
Browse files Browse the repository at this point in the history
- log levels
- supported kernels arg
- destination arg
- info log level
- catch a bug with everything after --target being interpretted as
  a target param
- don't put template.pros in tmp directory if we are not zipping
- add --compress flag
- instead of just `pros c create-template ...`, `pros conductor
  create-template ...` also works now
- provide useful logging for invalid subcommands
- add more debug logs
- ensure that if we are zipping, destination is handled properly (
  append .zip if there is not already a file extension there)
- expand out some flags to be --word flags rather than -w
- print colors properly in parse_zip_output
- remove './' whereever possible in parse_zip_output to make everything
  uniform
- filter out directories when sending verbose copy output to
  parse_zip_output
  • Loading branch information
meisZWFLZ committed May 21, 2024
1 parent cc609f0 commit 91e811e
Showing 1 changed file with 163 additions and 45 deletions.
208 changes: 163 additions & 45 deletions pros-fake/bin/pros
Original file line number Diff line number Diff line change
Expand Up @@ -2,35 +2,79 @@
index=0
is_system_arg=0
is_target_arg=0
is_kernel_arg=0
is_destination_arg=0
is_log_level_arg=0

system_files=''

path=''
name=''
version=''
target=''
debug=0
destination=''
supported_kernels=''

# the lowest level of logging, can be one of:
possible_log_levels=("DEBUG" "INFO" "WARN" "ERROR")
log_level="INFO"

# if set, tells this script to not zip the template, and instead place it in a directory
# specified with --no-compress
no_zip=0

RED='\033[0;31m'
YELLOW='\033[1;33m'
PURPLE='\033[0;35m'
BLUE='\033[0;34m'
RESET='\033[0m'

translate_log_level() {
case "$1" in
DEBUG) echo 0 ;;
INFO) echo 1 ;;
WARN) echo 2 ;;
ERROR) echo 3 ;;
*) echo -1 ;;
esac
}

is_level_enabled() {
# will return 1 if this log level is enabled
level=$(translate_log_level "$1")
# the current log level in integer form
current=$(translate_log_level "$log_level")
# echo "$level >= $current" >/dev/stdout
if [ $level -ge $current ]; then
echo 1
else
echo 0
fi
}

debug_echo() {
if [ $debug -eq 1 ]; then
echo "$PURPLE[DEBUG]$RESET" $@
fi
if [ "$(is_level_enabled "DEBUG")" -eq 1 ]; then
echo -e "$PURPLE[DEBUG]$RESET" $@
fi
}

error_echo() {
echo -e "$RED[ERROR]$RESET" $@ >&2
if [ "$(is_level_enabled "ERROR")" -eq 1 ]; then
echo -e "$RED[ERROR]$RESET" $@ >&2
fi
}

warning_echo() {
echo -e "$YELLOW[WARN]$RESET" $@ >&2
if [ "$(is_level_enabled "WARN")" -eq 1 ]; then
echo -e "$YELLOW[WARN]$RESET" $@ >&2
fi

}

info_echo() {
if [ "$(is_level_enabled "INFO")" -eq 1 ]; then
echo -e "$BLUE[INFO]$RESET" $@
fi
}

newline="
Expand All @@ -49,10 +93,35 @@ for arg in "$@"; do
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
error_echo "target must be of type v5 or cortex. Got: $target"
exit 5
fi
is_system_arg=0
is_target_arg=0
continue
fi

if [ $is_kernel_arg -eq 1 ]; then
supported_kernels="$arg"
is_kernel_arg=0
continue
fi

if [ $is_destination_arg -eq 1 ]; then
destination="$arg"
is_destination_arg=0
continue
fi

if [ $is_log_level_arg -eq 1 ]; then
# check if the log level is valid
new_log_level=$(echo "${possible_log_levels[@]}" | xargs -n 1 | grep -iF "$arg")
if [ -z new_log_level ]; then
error_echo "Invalid log level: $arg"
exit 5
fi

log_level="$new_log_level"
is_log_level_arg=0
continue
fi

Expand All @@ -66,38 +135,56 @@ for arg in "$@"; do
continue
fi

if [ "$arg" == "--debug" ]; then
debug=1
if [ "$arg" == "--kernels" ]; then
is_kernel_arg=1
continue
fi

if [ "$arg" == "--destination" ]; then
is_destination_arg=1
continue
fi

if [ "$arg" == "--level" ]; then
is_log_level_arg=1
continue
fi

if [ "$arg" == "--no-compress" ]; then
debug=1
no_zip=1
continue
fi

if [ "$arg" == "--compress" ]; then
no_zip=0
continue
fi


case $index in
0) if [ "$arg" != "c" ]; then
echo "Invalid argument: $arg"
0) if [ "$arg" != "c" -a "$arg" != "conductor" ]; then
error_echo "Invalid argument: "'"'"$arg"'"'", expected c or conductor."
exit 1
fi ;;
1) if [ "$arg" != "create-template" ]; then
echo "Invalid argument: $arg"
error_echo "Invalid argument: "'"'"$arg"'"'", expected create-template."
exit 1
fi ;;
2) path="$arg" ;;
3) name="$arg" ;;
4) version="$arg" ;;
*) echo "Invalid argument: $arg" ;;
*) warning_echo "Invalid argument: $arg" ;;
esac

index=$((index + 1))
done

debug_echo "args: $@"
debug_echo "path: $path"
debug_echo "name: $name"
debug_echo "version: $version"
debug_echo "target: $target"
debug_echo "no_zip: $no_zip"

if [ -z "$path" ]; then
error_echo "Invalid argument: path"
Expand All @@ -116,27 +203,40 @@ if [ -z "$target" ]; then
exit 1
fi

destination="./$name@$version"
if [ -z "$destination" ]; then
destination="./$name@$version"

if [ $no_zip -eq 0 ]; then
destination="$destination.zip"
if [ $no_zip -eq 0 ]; then
destination="$destination.zip"
fi
elif [ $no_zip -eq 0 ]; then
# if the destination does not already have a file extension, the zip command will add a .zip
# in order to prevent things breaking (clearing the destination beforehand for example), we'll do it proactively
if echo "$destination" | grep -vF "."; then
destination="$destination.zip"
fi
fi

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";
if [ -z "$supported_kernels" ]; then
supported_kernels=$(cat "$path/project.pros" | jq --raw-output '.["py/state"].templates?.kernel.version')
if [ "$supported_kernels" != "null" ]; then
supported_kernels="^$supported_kernels";
fi
fi

debug_echo "kernel_version: $kernel_version";
debug_echo "supported_kernels: $supported_kernels";

# sort and remove duplicates
system_files=$(echo "$system_files" | sort | uniq)

# remove destination if it exists
rm -f "$destination"
rm --force --recursive "$destination"

if [ $no_zip -eq 1 ]; then
mkdir --parents "$destination"
fi

# will be deleted after zipping
tmp_files=""
Expand Down Expand Up @@ -169,33 +269,46 @@ old_files=""

parse_zip_output() {
local old_files=$(echo "$old_files" | sed 's%\./%%g')
local new_files=$(echo "$new_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"
info_echo "S: $old_file -> $file"
else
echo "S: $file"
info_echo "S: $file"
fi
}
debug_echo "new_files: $new_files"
debug_echo "old_files: $old_files"
export -f parse_zip_output_line
export -f get_at_index
export -f find_index
export -f error_echo
export -f info_echo
export -f is_level_enabled
export -f translate_log_level
export log_level
export new_files
export old_files
xargs -I{} bash -c 'parse_zip_output_line "$@"' _ {}
export RED
export YELLOW
export PURPLE
export BLUE
export RESET
sed 's%\./%%g' | xargs -I{} bash -c 'parse_zip_output_line "$@"' _ {}
}

tmp_dir="/tmp/pros-fake"
Expand All @@ -205,7 +318,7 @@ add_tmp_file "$tmp_dir"

# ensures that tmp files are deleted
cleanup() {
debug_echo "Cleaning up: $tmp_files"
debug_echo "Cleaning up: $tmp_files"
rm -Rf $tmp_files
}

Expand All @@ -216,7 +329,7 @@ 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
Expand All @@ -226,7 +339,7 @@ add_to_zip() {
if [ -z "$is_tmp" ]; then
if [ ! -e "$new_path" ]; then
is_tmp=1
cp "$old_path" "$new_path"
cp "$old_path" "$new_path"
fi
fi
fi
Expand All @@ -246,7 +359,7 @@ system_files_strings=""
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
Expand All @@ -260,7 +373,7 @@ for path in $system_files; do
continue
fi
fi

add_to_zip "$path" "$new_path"

system_files_strings="$system_files_strings"'"'"$new_path"'"'"$newline"
Expand All @@ -270,40 +383,45 @@ system_files_json="$(echo "$system_files_strings" | jq --slurp --compact-output

template_pros_target="$tmp_dir/template.pros"

if [ $no_zip -eq 1 ]; then
template_pros_target="$destination/template.pros"
fi

if [ $no_zip -eq 0 ]; then
zip -9 "$destination" $new_files | parse_zip_output;
else
cp -t "$destination" $new_files --verbose \
| sed 's/->.+//' \
| sed "s/'//" \
| xargs -I {} echo "adding: {} (mimic zip output)" \
cp --parents -t "$destination" $new_files --verbose \
| sed -E 's/.+->//' \
| sed "s/'//g" \
| sed "s%$destination/%%" \
| xargs -n 1 \
| xargs -d "\n" -I {} bash -c 'if [ ! -d "$1" ]; then echo "$1"; fi' _ {} \
| xargs -d "\n" -I {} echo "adding: {} (mimic zip output)" \
| parse_zip_output
fi

jq --null-input --tab --sort-keys \
--arg name "$name" \
--arg version "$version" \
--arg target "$target" \
--arg kernel_version "$kernel_version" \
--arg supported_kernels "$supported_kernels" \
--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,
"supported_kernels": $supported_kernels,
"system_files": $sysfiles,
"metadata": {},
"user_files": []
}
}' > "$template_pros_target"
add_tmp_file "$template_pros_target"

if [ $no_zip -eq 0 ]; then
add_tmp_file "$template_pros_target"
zip -9qj "$destination" "$template_pros_target";
else
cp "$template_pros_target" "$destination";
fi

cleanup
cleanup

0 comments on commit 91e811e

Please sign in to comment.