diff --git a/pros-fake/bin/pros b/pros-fake/bin/pros index 43c744d18..07c2a7cc7 100755 --- a/pros-fake/bin/pros +++ b/pros-fake/bin/pros @@ -2,6 +2,9 @@ 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='' @@ -9,7 +12,13 @@ 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 @@ -17,20 +26,55 @@ 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=" @@ -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 @@ -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" @@ -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="" @@ -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" @@ -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 } @@ -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 @@ -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 @@ -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 @@ -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" @@ -270,13 +383,20 @@ 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 @@ -284,7 +404,7 @@ 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", @@ -292,18 +412,16 @@ jq --null-input --tab --sort-keys \ "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 \ No newline at end of file