diff --git a/samples/bash.sh b/samples/bash.sh new file mode 100644 index 0000000..813077e --- /dev/null +++ b/samples/bash.sh @@ -0,0 +1,640 @@ +#!/bin/bash + +#sve = System Variable Exemplifier +#This script executes whatever file you tell regardless of in which directory it's currently in. + +# TO-DO +# + on recurse_dirs2() -- make it so that any file with 'Main' on its name will get compiled at the end, cuz else it's going to cause error +# + make it so that $temp_cp can be edited using this scritpt +# +,i remove one of the entries +# +,i add an entry +# + fix bugs +# +,i if entry if removed and entry is last of entries then the entry before that one will have an collon, which is something that will cause an error to the parser +# this is a simple test becas (done) +# + from $0 -ef a -> if "entry" is on $temp_cp then do not add entry, print message, else, add it (done) +# + edit --help str (done) +# + avoid compiling already compiled files +# +,i mkdir /tmp/2sve_tmp -- dir where "already compiled things" file is stored +# +,j touch /tmp/2sve_tmp/compiled_file_list.json +# +,i after first compile add all files compiled to list +# +,i if `stat --format "%Y" ` == `stat --format "%Y" hello.txt` of file with same name in compiled_file_list.json, then don't compile, else, do so + +OUT_DICT=out +temp_cp=/usr/local/bin/kt_temp_classpaths/kttemp_cp.json +temp_temp_cp=/usr/local/bin/kt_temp_classpaths/kttemp_temp_cp.json + +#lists +dir_compiled=/tmp/2sve_tmp/ +dir_sessions=/tmp/2sve_tmp/sessions/ +txt_sessions=/tmp/2sve_tmp/current_sessions.txt +lines_sessions=`wc -l $txt_sessions | awk '{ print $1 }'` +testable_file=/tmp/2sve_tmp/test1.txt +hashtag="#" + +#get shortened version of script's name +# this_scrpt=`basename "$0" &>/dev/null` +this_scrpt=`basename "$0"` + +script_help=$( cat << EOF + +This script simplifies the process of executing and compiling kolin code/projects +using simple configuration files. + +Usages: + #0: ${this_scrpt} [arg] +Arguments: + -h,--help See this help message. + -c,--compile Compile all .kt files in current dir into + current dir or a given dir a subargument. Fail: if errror on the code of given files. + -r,--run Run a .class file using 'kotlin'. Fail: if file + does not exist + -ef,--edit-file [mode: a(dd)/d(elete)] Edit the configuration file ($temp_cp) to + either add or remove an entry depinding on the mode. Fail [when adding]: if entry alredy + exists; Fail [when removing]: if out of range index is given. + -gcp|--get-class-paths Show prettily all the entries in the configuration + file ($temp_cp) +Example: + #0: $this_scrpt -c . 0 + Explanation: compile all .kt files in cwd into cwd using the default classpath + +EOF +) + +function create_dirs() { + +for_jsons=$( cat << EOF +{ + "test_key": "test_val" +} +EOF +) + + in_dir=$1 + compiled_list="${in_dir}compiled_list.json" + compiled_list_tmp="${in_dir}compiled_list_tmp.json" + touch $compiled_list $compiled_list_tmp + echo "$for_jsons" > $compiled_list + +} + + + +function recurse_dirs1() { + + # readarray -t assArrayCP2< <(jq -r '.[]' $compiled_list) + files_array=$(find . -type f -name "*.kt") #find all files with the .kt (kotlin) exte + test_array=() + + sub_str1="main" + sub_str2="Main" + c_line=1 + + for j in "${files_array[@]}"; do #this is because files on $files_array can't one by one + test_array+=($j) + done + + if [[ $lines_sessions == 0 ]]; then + new_session="${dir_sessions}session1/" + mkdir $new_session + + # append to file + echo "$out" >> $txt_sessions + create_dirs $new_session + else + while read -r line; do + # echo "current line = $c_line\ttotal lines = $lines_file" + if [[ "$line" == "$out" ]]; then + compiled_list="${dir_sessions}session$c_line/compiled_list.json" + compiled_list_tmp="${dir_sessions}session$c_line/compiled_list_tmp.json" + break + else + if [[ $c_line == $lines_sessions ]]; then + # echo "recursion limit reached"; break + new_session="${dir_sessions}session$((lines_sessions+1))/" + mkdir $new_session + + # append to file + echo "$out" >> $txt_sessions + create_dirs $new_session + break + else + c_line=$((c_line+1)) + fi + fi + done < $txt_sessions + fi + + + testarray_size=${#test_array[@]} + # echo "files array size = $testarray_size" + second_counter=0 + + + for file in "${test_array[@]}"; do + readarray -t assArrayCP2< <(jq -r '.[]' $compiled_list) + counter=-1 + + for key in ${!assArrayCP2[@]}; do + counter=$((counter+1)) + done + + counter_plus_two=$((counter+2)) + counter_plus_one=$((counter+1)) + counter_plus_three=$((counter+3)) + final_counter="${counter_plus_three}s" + + counter=$((AACP2_size + 1)) + last_entry=-1 + lines_in_list=`wc -l $compiled_list | awk '{ print $1 }'` + lines_minusone="$((lines_in_list - 1))s" + tarray_size=${#test_array[@]} + tas_plus1=$((tarray_size + 1)) + + # echo "\tSECOND COUNTER = $second_counter" + + AACP2_size=${#assArrayCP2[@]} + inner_counter=1 + + current_stats=`stat --format "%Y" $file` + only_name=`basename "$file"` + cmd1="cat $compiled_list | jq '.\"$only_name\"'" + # cmd1="cat $compiled_list | jq '.\"$test_name\"'" + evaluation_file=`eval $cmd1` + eval_file_without_apostrofes=${evaluation_file//\"/} + + if [[ "$evaluation_file" == "null" ]]; then #file is not on the list + if [[ "$file" == *"$sub_str2"* || "$file" == *"$sub_str1"* ]]; then + is_main=$file + to_change=true + second_counter=$((second_counter+1)) + + str_replacement="${hashtag}${counter_plus_one};${file_stats}" + cat $compiled_list | jq --arg fsts "$current_stats" '. + {"###": $fsts}' > $compiled_list_tmp; cat $compiled_list_tmp > $compiled_list; echo "" > $compiled_list_tmp + sed -i "$final_counter/"$hashtag$hashtag$hashtag"/"$only_name"/g" $compiled_list + + if [[ $((testarray_size)) == 1 ]]; then + : + else + continue #this continue is causing issues but it also helps in some situations + fi + else + : + fi + + echo "šŸ‰ File = $file" + # echo "var is empty, therefore file is not added into the array" + echo -e "\tIn config status: not sited" + echo -e "\tChanged? = Null\n" + + str_replacement="${hashtag}${counter_plus_one};${file_stats}" + cat $compiled_list | jq --arg fsts "$current_stats" '. + {"###": $fsts}' > $compiled_list_tmp; cat $compiled_list_tmp > $compiled_list; echo "" > $compiled_list_tmp + sed -i "$final_counter/"$hashtag$hashtag$hashtag"/"$only_name"/g" $compiled_list + + #compile the file here + if [[ -z "$out" ]]; then #var is empty, therefore no out dir was given + echo -e "\tšŸ”° compiling:\t$file"; `kotlinc $file -d . -cp $whichKeyCP` + echo "" + second_counter=$((second_counter+1)) + else #var has something, dir was given + echo -e "\tšŸ”° compiling:\t$file"; `kotlinc $file -d $out -cp $whichKeyCP` + echo "" + second_counter=$((second_counter+1)) + fi + + + if [[ $second_counter == $((testarray_size)) ]]; then + if [[ "${test_array[@]}" =~ "${is_main}" && $to_change = true ]]; then + echo "šŸ‰ File = $is_main" + # echo "var is empty, therefore file is not added into the array" + echo -e "\tIn config status: not sited" + echo -e "\tChanged? = Null\n" + if [[ -z "$out" ]]; then #var is empty, therefore no out dir was given + echo -e "\tšŸ”° compiling:\t$is_main"; `kotlinc $is_main -d . -cp $whichKeyCP` + echo "" + else + echo -e "\tšŸ”° compiling:\t$is_main"; `kotlinc $is_main -d $out -cp $whichKeyCP` + echo "" + fi + else + : + fi + else + : + fi + + + else #file is on the list + # echo "File is already on the the configuration file" + # echo -e "\tCurrent stats = $current_stats\n\tStats in config = $eval_file_without_apostrofes" + if [[ "$current_stats" == "$eval_file_without_apostrofes" ]]; then + if [[ "$file" == *"$sub_str2"* || "$file" == *"$sub_str1"* ]]; then + is_main=$file + to_change=false + second_counter=$((second_counter+1)) + else + : + fi + + echo "šŸ‰ File = $file" + echo -e "\tIn config status: sited" + # echo -e "\n---------File hasn't been changed---------\n" #file shouldn't be compiled + echo -e "\tChanged? = False\n" + second_counter=$((second_counter+1)) + #not compile + + else + + if [[ "$file" == *"$sub_str2"* || "$file" == *"$sub_str1"* ]]; then + is_main=$file + to_change=true + second_counter=$((second_counter+1)) + + cmd2="cat $compiled_list | jq --arg foo "$current_stats" '. + {\"$only_name\": \$foo}'" + final_str=`eval $cmd2` + echo "$final_str" > $compiled_list_tmp; cat $compiled_list_tmp > $compiled_list; echo "" > $compiled_list_tmp; continue + else + : + fi + + echo "šŸ‰ File = $file" + echo -e "\tIn config status: sited" + # echo -e "\n-------------File was changed--------------\n" + echo -e "\tChanged? = True\n" + + #replace with new stats + cmd2="cat $compiled_list | jq --arg foo "$current_stats" '. + {\"$only_name\": \$foo}'" + final_str=`eval $cmd2` + echo "$final_str" > $compiled_list_tmp; cat $compiled_list_tmp > $compiled_list; echo "" > $compiled_list_tmp + + if [[ -z "$out" ]]; then #var is empty, therefore no out dir was given + echo -e "\tšŸ”° compiling:\t$file"; `kotlinc $file -d . -cp $whichKeyCP` + echo "" + second_counter=$((second_counter+1)) + else #var has something, dir was given + echo -e "\tšŸ”° compiling:\t$file"; `kotlinc $file -d $out -cp $whichKeyCP` + echo "" + second_counter=$((second_counter+1)) + fi + fi + + if [[ $second_counter == $((testarray_size)) ]]; then + if [[ "${test_array[@]}" =~ "${is_main}" && $to_change = true ]]; then + echo "šŸ‰ File = $is_main" + # echo "var is empty, therefore file is not added into the array" + echo -e "\tIn config status: not sited" + echo -e "\tChanged? = Null\n" + if [[ -z "$out" ]]; then #var is empty, therefore no out dir was given + echo -e "\tšŸ”° compiling:\t$is_main"; `kotlinc $is_main -d . -cp $whichKeyCP` + else #var has something, dir was given + echo -e "\tšŸ”° compiling:\t$is_main"; `kotlinc $is_main -d $out -cp $whichKeyCP` + fi + else + : + fi + else + : + fi + fi + done + + time_end=`date +%s` + runtime=$((time_end-time_start)) + + case ${?} in + 0) + echo -e "\n-----------------------------------------" + echo -e "Everything was compiled successfully!" + echo -e "Time: ${runtime}secs." + ;; + *) + echo -e "\n\nAn error ocurred while compiling, check '$this_scrpt -h' for help." + echo -e "Time: ${runtime}secs." + ;; + esac +} + + +function recurse_dirs2() { + + files_array=$(find . -type f -name "*.kt") #find all files with the .kt (kotlin) extension + test_array=() + + for j in "${files_array[@]}"; do #this is because files on $files_array can't be accessed one by one + test_array+=($j) + done + + sub_str1="main" + sub_str2="Main" + + echo -e "\n\t--------Files--------\n" + #note: the emoji is for orientating the user in case the error output is huge + time_start=`date +%s` + if [[ -z "$out" ]]; then #var is empty, therefore no out dir was given + for file in "${test_array[@]}"; do + if [[ "$file" == *"$sub_str2"* || "$file" == *"$sub_str1"* ]]; then + is_main=$file + else + echo -e "šŸ‰ compiling:\t$file"; `kotlinc $file -d . -cp $whichKeyCP` + fi + done + echo -e "šŸ‰ compiling:\t$is_main"; `kotlinc $is_main -d . -cp $whichKeyCP` + else #var has something, dir was given + for file in "${test_array[@]}"; do + if [[ "$file" == *"$sub_str2"* || "$file" == *"$sub_str1"* ]]; then + is_main="$file" + else + + echo -e "šŸ‰ compiling:\t$file"; `kotlinc $file -d $out -cp $whichKeyCP` + fi + done + echo -e "šŸ‰ compiling:\t$is_main"; `kotlinc $is_main -d $out -cp $whichKeyCP` + fi + time_end=`date +%s` + runtime=$((time_end-time_start)) + + + case ${?} in + 0) + echo -e "\n\nEverything was compiled successfully!" + echo -e "Time: ${runtime}secs." + ;; + *) + echo -e "\n\nAn error ocurred while compiling, check '$this_scrpt -h' for help." + echo -e "Time: ${runtime}secs." + ;; + esac +} + +function get_class_paths() { + readarray -t assArrayCP< <(jq -r '.[]' $temp_cp) + + echo -e "This are the available classpaths: \n" + + echo -e "--------------------------CLASSPATHS--------------------------" + for key in ${!assArrayCP[@]}; do + echo -e " šŸ’”$key -> ${assArrayCP[$key]}" + done + echo -e "--------------------------CLASSPATHS--------------------------" +} + +function check_trailing_comma() { + `sed -i.bak ':begin;$!N;s/,\n}/\n}/g;tbegin;P;D' $temp_cp` #remove trailing comma if any +} + +function test_func() { + + for file in *; do + if [[ "$file" == "$0" ]]; then + echo "found" + else + continue + fi + done +} + +if [[ -n "$1" ]]; then + case "$1" in + -h|--help) + echo "$script_help" + exit 0 + ;; + -c|--compile) #$1 = "-c" + out=$2 + whichKeyCP=$3 + + if [[ -z "$out" ]]; then + out=`pwd` + else + : + fi + + # echo "1 = $1; 2 = $2; 3 = $3" + # echo -e "\n\nout= $out; whichKeyCP= $whichKeyCP" + readarray -t assArrayCP< <(jq -r '.[]' $temp_cp) + AACP_size=${#assArrayCP[@]} + + if [[ -z "$3" ]]; then #var is empty + echo "this ran" + whichKeyCP=0 + else + counter=1 + for key in ${!assArrayCP[@]}; do + # echo "key = $key" + if [[ "$key" == "$whichKeyCP" ]]; then + # echo -e " šŸ’”$key -> ${assArrayCP[$key]}" + whichKeyCP=${assArrayCP[$key]}; break + else + if [[ $AACP_size == $counter ]]; then + echo -e "\nERROR: Unfortunately the key '$whichKeyCP' was not found on the config file.\nFor more information run '$this_scrpt --get-class-paths' or '$this_scrpt -gcp'" + whichKeyCP=0 + exit 1 + else + : + fi + fi + counter=$((counter+1)) + done + fi + + # echo -e "which key = $whichKeyCP" + echo -e "\nCLASSPATH:\t$whichKeyCP\nOUT DIR:\t$out\n" + recurse_dirs2 + exit 0 + ;; + -sc|--smart-compile) + + if [[ -f "$compiled_list" ]]; then #exists + : + else #does not exist + # mkdir -p $dir_compiled && touch $compiled_list $compiled_list_tmp + # `echo '{ "test_file":"test_stats" }' | jq . > $compiled_list` + mkdir -p $dir_compiled $dir_sessions && touch $txt_sessions + lines_sessions=`wc -l $txt_sessions | awk '{ print $1 }'` + fi + + #--------Status of a file---------# + #In config staus: [sited|not sited] + #Change? = [Null|True|False] + # + #for config statuses: + # sited: the program already has a register of that given file in the configurationg files + # not sited: the program does not has a register of that given file in the configurationg files + #for changed: + # Null: for files that are yet to be registered in the archive + # True: Files' current stats and in-config stats are different, therefore file is considered to have changed + # +,i what is considered as changed? + # +,j if file was directly written + # +,j if a program saved the file (regardless of having edited something). E.g. when writing with vim (:w) + # False: File' current stats and in-config stats are the same, therefore file has not changed + + + out=$2 + whichKeyCP=$3 + time_start=`date +%s` + + # echo "1 = $1; 2 = $2; 3 = $3" + # echo -e "\n\nout= $out; whichKeyCP= $whichKeyCP" + readarray -t assArrayCP< <(jq -r '.[]' $temp_cp) + AACP_size=${#assArrayCP[@]} + + if [[ -z "$3" ]]; then #var is empty + echo "this ran" + whichKeyCP=0 + else + counter=1 + for key in ${!assArrayCP[@]}; do + # echo "key = $key" + if [[ "$key" == "$whichKeyCP" ]]; then + # echo -e " šŸ’”$key -> ${assArrayCP[$key]}" + whichKeyCP=${assArrayCP[$key]}; break + else + if [[ $AACP_size == $counter ]]; then + echo -e "\nERROR: Unfortunately the key '$whichKeyCP' was not found on the config file.\nFor more information run '$this_scrpt --get-class-paths' or '$this_scrpt -gcp'" + whichKeyCP=0 + exit 1 + else + : + fi + fi + counter=$((counter+1)) + done + fi + + echo -e "\nCLASSPATH:\t$whichKeyCP\nOUT DIR:\t$out\n" + recurse_dirs1 + exit 0 + ;; + -gcp|--get-class-paths) + get_class_paths + echo -e "\nNote: you can add/remove more if you want by accessing the configuration file or using\n\t'$this_scrpt --edit-file --add' #for adding a new entry\n\t'$this_scrpt --edit-file --delete' #for deleting entries\nThe configuration file is located at: $temp_cp\n" + exit 0 + ;; + -ef|--edit-file) + mode=$2 + get_class_paths; echo "" + AACP_size=${#assArrayCP[@]} + + if [ "$mode" == "d" ] || [ "$mode" == "-d" ] || [ "$mode" == "delete" ] || [ "$mode" == "--delete" ]; then #delete mode + read -p "Which of the aforeshown entries do you want to remove [0-$((AACP_size-1))]?: " entry_to_remove + + if (($entry_to_remove >= 0 && $entry_to_remove <= $((AACP_size-1)))); then + counter=1 + for key in ${!assArrayCP[@]}; do + # echo -e " šŸ’”$key -> ${assArrayCP[$key]}" + if [[ $key == $entry_to_remove ]]; then + #entry was found + entry="${assArrayCP[$key]}" + # match=`grep -n "$entry" $temp_cp &>/dev/null` #will supress output as well as error messages + match=`grep -n "$entry" $temp_cp` #will supress output as well as error messages + line_number=$(echo "$match" | cut -c1-1) #gets just the line number of the $match + line_wd="${line_number}d" + echo -e "\tentry = $entry\n\tmatch = $match\n\tline_number = $line_number\n\tline_wd = $line_wdn\n\tcounter = $counter" #show info + read -t 10 -n 1 -s -r -p "Press any key to continue (you have 10 seconds)..." #ask for authorization + `sed -i $line_wd $temp_cp` #delete the line + + case ${?} in + 0) + echo -e "\n\n-----------------------------------------" + echo -e "Entry removed successfully" + ;; + *) + echo -e "\n\nAn error ocurred while removing the entry, check '$this_scrpt -h' for help." + ;; + esac + + + # `sed -i.bak ':begin;$!N;s/,\n}/\n}/g;tbegin;P;D' $temp_cp` #remove trailing comma if any #mn: was replaced by a function + check_trailing_comma + echo "" + break; + else + if [[ $AACP_size == $counter ]]; then + echo -e "\nERROR: Unfortunately the key '$entry_to_remove' was not found on the config file.\nFor more information run '$this_scrpt --get-class-paths' or '$this_scrpt -gcp'" + exit 1 + else + : + fi + fi + counter=$((counter+1)) + done + else + echo -e "\nThe number $entry_to_remove is out of range, remember it must be between 0 and $((AACP_size-1)) (according to the options above)" + fi + elif [ "$mode" == "a" ] || [ "$mode" == "-a" ] ||[ "$mode" == "add" ] || [ "$mode" == "--add" ]; then #append mode + read -p "Type or paste the directories' path here: " entry_to_add + + for key in ${!assArrayCP[@]}; do + if [[ "$entry_to_add" == "${assArrayCP[$key]}" ]]; then + echo -e "Sorry, your desired entry ($entry_to_add) is already on the configuration (.json) file.\nIf you think this is a mistake you can run '$this_scrpt -ef --delete' to remove the 'problematic' entry". + exit 1 + else + : # do nothing + fi + done + + readarray -t assArrayCP< <(jq -r '.[]' $temp_cp) + AACP_size=${#assArrayCP[@]} + + counter=-1 + for key in ${!assArrayCP[@]}; do + # echo -e " šŸ’”$key -> ${assArrayCP[$key]}" + counter=$((counter+1)) + done + counter_plus_three=$((counter+3)) + counter_plus_two=$((counter+2)) + counter_plus_one=$((counter+1)) + final_counter="${counter_plus_three}s" + + read -t 10 -n 1 -s -r -p "Press any key to continue (you have 10 seconds)..." #ask for authorization + echo "\n" + cat $temp_cp | jq --arg classpath "$entry_to_add" '. + {"classpath#": $classpath}' > $temp_temp_cp && cat $temp_temp_cp > $temp_cp; echo "" > $temp_temp_cp + sed -i "$final_counter/"$hashtag"/"$hashtag$counter_plus_one"/g" $temp_cp + + case ${?} in + 0) + echo -e "\n-----------------------------------------" + echo -e "Entry added successfully" + ;; + *) + echo -e "\n\nAn error ocurred while adding the entry, check '$this_scrpt -h' for help." + ;; + esac + + check_trailing_comma + else + : + fi + + exit 0 + ;; + -r|--run) + file=$2 + final_file=${file/".class"/} + kotlin $final_file + exit + ;; + *) + i=0 + file=$1 + #echo "arg 1 = $1" #works + #it will try to find out/ 18 times, this so as to avoid overloading the ram + #trying to find an unexistent out/. Of course this number can be increased + + while [[ $i -le 18 ]]; do + if [[ -d "$OUT_DICT" ]]; then #out found + cd $OUT_DICT + kotlin $file + break + else #out not found + cd .. + i=$((i+1)) + fi + done + exit 0 + ;; + esac + shift +else + echo -e "This script needs at least one argument to work.\nType '$this_scrpt -h' or '$this_scrpt --help' for help " +fi +