diff --git a/bin/bamc b/bin/bamc index eb7d9f7..c4fa5e8 100755 --- a/bin/bamc +++ b/bin/bamc @@ -1,29 +1,31 @@ #!/bin/bash #!/bin/bash # Set SNAME, SDIR and SPATH if [ -h $0 ]; then SNAME=$(readlink $0); else SNAME=$0; fi SDIR=$(dirname $SNAME) if [[ "$SDIR" =~ ^/ ]]; then SPATH=$SDIR; else SPATH=$(realpath $(pwd)/$SDIR); fi # Set DIR_LIB DIR_LIB=$(realpath $SPATH/../lib/bash) # Source libs source $DIR_LIB/colors.sh source $DIR_LIB/io.sh +source $DIR_LIB/debugging.sh source $DIR_LIB/cmdline_parser.sh source $DIR_LIB/bamc_configuration.sh source $DIR_LIB/bamc_help.sh source $DIR_LIB/bamc_workspace.sh +source $DIR_LIB/bamc_exams.sh DEFAULT_ITEMS="" DEFAULT_ACTIONS="help" CALLBACK_PREFIX="action_" run $@ RC=$? debug "Return code: $RC" exit $RC diff --git a/lib/bash/bamc_actions.sh b/lib/bash/bamc_actions.sh index 168278b..e595031 100644 --- a/lib/bash/bamc_actions.sh +++ b/lib/bash/bamc_actions.sh @@ -1,59 +1,56 @@ #!/bin/bash function tell_if_verbose() { if [ "$(get_param_value 'mode')" = 'verbose' ]; then echo "$@"; fi } -function do_list() { -} - function check_project_exists() { } function get_teachers() { } function do_test() { } function check_file_exists() { } function get_lang() { } function import_student_file() { } function get_expected_page_per_exam() { } function customize_tex_files() { } function build_sections() { } function do_sample() { } function do_check() { } function do_blank() { } function do_pdf() { } function build_amc_project() { } function add_media_files() { } function do_project() { } function do_clean() { } diff --git a/lib/bash/bamc_workspace.sh b/lib/bash/bamc_exams.sh similarity index 71% copy from lib/bash/bamc_workspace.sh copy to lib/bash/bamc_exams.sh index 3b6e013..42dd8cd 100644 --- a/lib/bash/bamc_workspace.sh +++ b/lib/bash/bamc_exams.sh @@ -1,130 +1,129 @@ #/bin/bash -function get_workspace() { - is_set 'workspace' - if [ $? -eq 1 ]; then DIR_WORKSPACE=$(get_parameter 'workspace'); fi - is_set 'w' - if [ $? -eq 1 ]; then DIR_WORKSPACE=$(get_parameter 'w'); fi +function action_list() { + # Check workspace + assert_workspace; if [ $? -eq 1 ]; then return 1; fi - if [ -z $DIR_WORKSPACE ]; then DIR_WORKSPACE="."; fi + # List exams + verbose "List of exams" + for exam in $(find $DIR_WORKSPACE/$DIR_EXAMS -mindepth 1 -maxdepth 1 -type d -exec basename {} \;); do + echo $exam + done - if [[ ! "$DIR_WORKSPACE" =~ ^/ ]]; then DIR_WORKSPACE=$(echo "$(pwd)/$DIR_WORKSPACE" | sed 's?/\.$??'); fi + # Done + return 0 } -function check_workspace() { - if [ -r "$1/$FILE_WORKSPACE_ROOT" ]; then +function action_add-exam() { + # Check workspace + assert_workspace; if [ $? -eq 1 ]; then return 1; fi + + # Set source + DIR_EXAM=$DIR_SKEL/workspace/$DIR_EXAMS/skel + + if [ ! -d $DIR_EXAM ]; then + error_echo "Directory '$DIR_EXAM' not found." return 1 - else - return 0 fi -} -function locate_nearest_workspace() { - local next_dir=$DIR_WORKSPACE - if [ -d $next_dir ]; then next_dir=$(realpath $next_dir); fi - for i in $(echo 1 2 3 4); do - check_workspace $next_dir - if [ $? -eq 1 ]; then - # Workspace found - echo $next_dir - return - else - next_dir=$next_dir/../ - if [ -d $next_dir ]; then next_dir=$(realpath $next_dir); fi - fi - done - echo "~none~" - return + is_set 'exam' + if [ $? -eq 1 ]; then DESTINATION=$(get_parameter 'exam'); fi + is_set 'e' + if [ $? -eq 1 ]; then DESTINATION=$(get_parameter 'e'); fi + + if [ -z "$DESTINATION" ]; then error_echo "No truc provided."; fi + exit 1 + + # Set destination + DESTINATION=$DIR_WORKSPACE/$DIR_EXAMS/$DESTINATION + + if [ -d $DESTINATION ]; then + confirm "Do you want to write in existing exam '$(basename $DESTINATION)' ?" + if [ $? -eq 0 ]; then return 1; fi + fi + + # Copy + color_echo_n "Creating new exam '$(basename $DESTINATION)' from '$DIR_EXAM'... " + cp -rp $DIR_EXAM $DESTINATION + check_rc_echo $? + return $? } -function assert_workspace() { +function assert_exam() { get_workspace check_workspace $DIR_WORKSPACE if [ $? -eq 1 ]; then return 0; fi DIR_WORKSPACE=$(locate_nearest_workspace) if [ "$DIR_WORKSPACE" == "~none~" ]; then error_echo "No valid workspace found around here..." return 1 fi return 0 } -function action_list() { - # Check workspace - assert_workspace; if [ $? -eq 1 ]; then return 1; fi - - # List exams - for exam in $(find $DIR_WORKSPACE/$DIR_EXAMS -mindepth 1 -maxdepth 1 -type d -exec basename {} \;); do - echo $exam - done - - # Done - return 0 -} - function action_add-exam() { # Check workspace assert_workspace; if [ $? -eq 1 ]; then return 1; fi # Set source DIR_EXAM=$DIR_SKEL/workspace/$DIR_EXAMS/skel if [ ! -d $DIR_EXAM ]; then error_echo "Directory '$DIR_EXAM' not found." return 1 fi is_set 'exam' if [ $? -eq 1 ]; then DESTINATION=$(get_parameter 'exam'); fi is_set 'e' if [ $? -eq 1 ]; then DESTINATION=$(get_parameter 'e'); fi if [ -z "$DESTINATION" ]; then error_echo "No truc provided."; fi exit 1 # Set destination DESTINATION=$DIR_WORKSPACE/$DIR_EXAMS/$DESTINATION if [ -d $DESTINATION ]; then confirm "Do you want to write in existing exam '$(basename $DESTINATION)' ?" if [ $? -eq 0 ]; then return 1; fi fi # Copy color_echo_n "Creating new exam '$(basename $DESTINATION)' from '$DIR_EXAM'... " cp -rp $DIR_EXAM $DESTINATION check_rc_echo $? return $? } function action_init() { get_workspace EXISTING_WORKSPACE=$(locate_nearest_workspace) if [ "$EXISTING_WORKSPACE" != "~none~" ]; then error_echo "You cannot create a workspace within a workspace!" error_echo "Detected workspace location: '$EXISTING_WORKSPACE'" return 1 fi confirm "Do you want to initialize workspace: '${DIR_WORKSPACE}'?" if [ $? -eq 0 ]; then return 1; fi # Create directory color_echo_n "Creating directory '${DIR_WORKSPACE}'... " mkdir -p $DIR_WORKSPACE check_rc_echo $? if [ $? -ne 0 ]; then return 1; fi color_echo_n "Adding workspace flag... " touch $DIR_WORKSPACE/$FILE_WORKSPACE_ROOT check_rc_echo $? if [ $? -ne 0 ]; then return 1; fi color_echo_n "Importing skeleton files... " cp -rp $DIR_SKEL/workspace/* $DIR_WORKSPACE/ check_rc_echo $? if [ $? -ne 0 ]; then return 1; fi return 0 } diff --git a/lib/bash/bamc_help.sh b/lib/bash/bamc_help.sh index bb651a0..766c659 100644 --- a/lib/bash/bamc_help.sh +++ b/lib/bash/bamc_help.sh @@ -1,42 +1,42 @@ #!/bin/bash function action_help() { local item=$1 # Useless... echo -e "${DarkGreen}USAGE:${NoColor} "$(basename $0)" [-p|--params p1=v1,p2-v2,...] [-o|--only item1,item2,...] action1 [action2 ...] e.g.: $(basename $0) --params workspace=~/AMC_Workspace init e.g.: $(basename $0) show Parameters: ----------- ${DarkGreen}debug${NoColor} (GENERAL) print debugging messages ${DarkGreen}force${NoColor} (GENERAL) do not ask for user confirmation ${DarkGreen}workspace|w${NoColor} (GENERAL) name a specific workspace ${DarkGreen}exam|e${NoColor} (GENERAL) name a specific exam within the workspace Items: ----------- ${DarkGreen}item1${NoColor} (GENERAL) items are the existing exams (as printed by the 'list' action) Actions: -------- ${DarkGreen}init${NoColor} (WORKSPACE) create a new workspace in the current directory ${DarkGreen}add-exam${NoColor} (EXAMS) add a new exam in the current workspace ${DarkGreen}list${NoColor} (EXAMS) print list of exams in the current workspace ${DarkGreen}clean${NoColor} (PROJECTS) remove project and output directories -${DarkGreen}project${NoColor} (PROJECTS) (re)build the AMC project +${DarkGreen}project${NoColor} (PROJECTS) (re)build the AMC project(s) ${DarkGreen}check-latex${NoColor} (PROJECTS) check LaTeX syntax ${DarkGreen}check-cvs${NoColor} (PROJECTS) check CSV files syntax ${DarkGreen}check-amc${NoColor} (PROJECTS) check AMC specific syntax ${DarkGreen}check${NoColor} (PROJECTS) do all checks ${DarkGreen}blank${NoColor} (PDF) build a blank (anonymous) exam ${DarkGreen}catalog${NoColor} (PDF) build a catalog of questions ${DarkGreen}sample${NoColor} (PDF) build a sample (4 exams) exam ${DarkGreen}exam${NoColor} (PDF) build PDF exam" return 0 } diff --git a/lib/bash/bamc_workspace.sh b/lib/bash/bamc_workspace.sh index 3b6e013..ec2ae35 100644 --- a/lib/bash/bamc_workspace.sh +++ b/lib/bash/bamc_workspace.sh @@ -1,130 +1,82 @@ #/bin/bash function get_workspace() { is_set 'workspace' if [ $? -eq 1 ]; then DIR_WORKSPACE=$(get_parameter 'workspace'); fi is_set 'w' if [ $? -eq 1 ]; then DIR_WORKSPACE=$(get_parameter 'w'); fi if [ -z $DIR_WORKSPACE ]; then DIR_WORKSPACE="."; fi if [[ ! "$DIR_WORKSPACE" =~ ^/ ]]; then DIR_WORKSPACE=$(echo "$(pwd)/$DIR_WORKSPACE" | sed 's?/\.$??'); fi } function check_workspace() { if [ -r "$1/$FILE_WORKSPACE_ROOT" ]; then return 1 else return 0 fi } function locate_nearest_workspace() { local next_dir=$DIR_WORKSPACE if [ -d $next_dir ]; then next_dir=$(realpath $next_dir); fi for i in $(echo 1 2 3 4); do check_workspace $next_dir if [ $? -eq 1 ]; then # Workspace found echo $next_dir return else next_dir=$next_dir/../ if [ -d $next_dir ]; then next_dir=$(realpath $next_dir); fi fi done echo "~none~" return } function assert_workspace() { get_workspace check_workspace $DIR_WORKSPACE if [ $? -eq 1 ]; then return 0; fi DIR_WORKSPACE=$(locate_nearest_workspace) if [ "$DIR_WORKSPACE" == "~none~" ]; then error_echo "No valid workspace found around here..." return 1 fi return 0 } -function action_list() { - # Check workspace - assert_workspace; if [ $? -eq 1 ]; then return 1; fi - - # List exams - for exam in $(find $DIR_WORKSPACE/$DIR_EXAMS -mindepth 1 -maxdepth 1 -type d -exec basename {} \;); do - echo $exam - done - - # Done - return 0 -} - -function action_add-exam() { - # Check workspace - assert_workspace; if [ $? -eq 1 ]; then return 1; fi - - # Set source - DIR_EXAM=$DIR_SKEL/workspace/$DIR_EXAMS/skel - - if [ ! -d $DIR_EXAM ]; then - error_echo "Directory '$DIR_EXAM' not found." - return 1 - fi - - is_set 'exam' - if [ $? -eq 1 ]; then DESTINATION=$(get_parameter 'exam'); fi - is_set 'e' - if [ $? -eq 1 ]; then DESTINATION=$(get_parameter 'e'); fi - - if [ -z "$DESTINATION" ]; then error_echo "No truc provided."; fi - exit 1 - - # Set destination - DESTINATION=$DIR_WORKSPACE/$DIR_EXAMS/$DESTINATION - - if [ -d $DESTINATION ]; then - confirm "Do you want to write in existing exam '$(basename $DESTINATION)' ?" - if [ $? -eq 0 ]; then return 1; fi - fi - - # Copy - color_echo_n "Creating new exam '$(basename $DESTINATION)' from '$DIR_EXAM'... " - cp -rp $DIR_EXAM $DESTINATION - check_rc_echo $? - return $? -} - function action_init() { get_workspace EXISTING_WORKSPACE=$(locate_nearest_workspace) if [ "$EXISTING_WORKSPACE" != "~none~" ]; then error_echo "You cannot create a workspace within a workspace!" error_echo "Detected workspace location: '$EXISTING_WORKSPACE'" return 1 fi confirm "Do you want to initialize workspace: '${DIR_WORKSPACE}'?" if [ $? -eq 0 ]; then return 1; fi # Create directory color_echo_n "Creating directory '${DIR_WORKSPACE}'... " mkdir -p $DIR_WORKSPACE check_rc_echo $? if [ $? -ne 0 ]; then return 1; fi color_echo_n "Adding workspace flag... " touch $DIR_WORKSPACE/$FILE_WORKSPACE_ROOT check_rc_echo $? if [ $? -ne 0 ]; then return 1; fi color_echo_n "Importing skeleton files... " cp -rp $DIR_SKEL/workspace/* $DIR_WORKSPACE/ check_rc_echo $? if [ $? -ne 0 ]; then return 1; fi return 0 } diff --git a/lib/bash/cmdline_parser.sh b/lib/bash/cmdline_parser.sh index e787d80..ff79fdd 100644 --- a/lib/bash/cmdline_parser.sh +++ b/lib/bash/cmdline_parser.sh @@ -1,121 +1,112 @@ #!/bin/bash # Command line parser # USAGE: [in the calling script] # 1) set the global variables: $DEFAULT_ITEMS and $DEFAULT_ACTIONS # 2) set the global variable: $CALLBACK_PREFIX (default: cb_ ) # 3) implement each the callback: e.g. function cb_list() { ... } to implement the list action # 4) call: run $@ ACTIONS='' PARAMS='' ITEMS='' CALLBACK_PREFIX=${CALLBACK_PREFIX:-cb_} -function error() { - error_echo $@ -} - -function debug() { - is_set debug - if [ $? -eq 1 ]; then debug_echo $@; fi -} - function parse_args() { while [ $# -gt 0 ]; do case $1 in "-o"|"--only") shift ITEMS=$1 shift continue ;; "-p"|"--params") shift PARAMS=$1 shift continue ;; *) if [ -z "$ACTIONS" ]; then ACTIONS=$1; else ACTIONS="$ACTIONS $1"; fi shift ;; esac done if [ -z "$ITEMS" ]; then ITEMS=$(get_default_items); fi if [ -z "$ITEMS" ]; then ITEMS='~no~items~'; fi if [ -z "$ACTIONS" ]; then ACTIONS=$(get_default_actions); fi debug "actions: '$ACTIONS' | items: '$ITEMS' | parameters: '$PARAMS'" } function get_items() { echo "$ITEMS" | sed "s/,/\n/g" } function get_actions() { echo "$ACTIONS" | sed "s/ /\n/g" } function get_params() { echo "$PARAMS" | sed "s/,/\n/g" } function get_parameter() { key=$1 # Key alone line=$(echo $PARAMS | sed "s/,/\n/g" | grep "^$key$") if [ -n "$line" ]; then echo "set"; return; fi # Key + value line=$(echo $PARAMS | sed "s/,/\n/g" | grep "^$key=" | cut -d '=' -f 2-) if [ -n "$line" ]; then echo $line; return; fi # unset echo "unset" } function is_set() { param=$1 value=$(get_parameter $param) if [ "$value" != "unset" ]; then return 1; else return 0; fi } function run() { local action local item local rc=0 parse_args $@ for action in $(get_actions); do for item in $(get_items); do debug "Running action '$action' on item '$item'" action_switch $action $item rc=$((rc+$?)) done done return $rc } function get_default_items() { echo $DEFAULT_ITEMS } function get_default_actions() { echo $DEFAULT_ACTIONS } function action_switch() { local action=$1 local item=$2 local function_to_call="${CALLBACK_PREFIX}${action}" local function_exists=$(type "$function_to_call" 2>&1 | grep -c "$function_to_call"' is a function'); if [ $function_exists -eq 1 ]; then $function_to_call $item return $? else - error "invalid action: $action (not implemented ?)" + error "invalid action: $action => ${CALLBACK_PREFIX}${action} (not implemented ?)" return 1 fi } # EOF diff --git a/lib/bash/debugging.sh b/lib/bash/debugging.sh new file mode 100644 index 0000000..8c1b1e2 --- /dev/null +++ b/lib/bash/debugging.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +function error() { + error_echo $@ +} + +function debug() { + is_set debug + if [ $? -eq 1 ]; then debug_echo $@; fi +} + +function verbose() { + is_set verbose + if [ $? -eq 1 ]; then color_echo $@; fi +} + +# EOF diff --git a/lib/bash/io.sh b/lib/bash/io.sh index 6556579..f455ede 100644 --- a/lib/bash/io.sh +++ b/lib/bash/io.sh @@ -1,70 +1,70 @@ #!/bin/bash function color_echo() { echo -e "$@" } function color_echo_n() { echo -en "$@" } function debug_echo() { color_echo "${White}DEBUG:${NoColor} $@" } function warning_echo() { color_echo "${Yellow}WARING:${NoColor} $@" 1>&2 } function error_echo() { color_echo "${Red}ERROR:${NoColor} $@" 1>&2 } function info_echo() { color_echo "${Green}INFO:${NoColor} $@" } function OK_echo() { color_echo "${Green}OK${NoColor}" } function KO_echo() { color_echo "${Red}KO${NoColor}" } function check_rc_echo { if [ $1 -eq 0 ]; then OK_echo; return 0; else KO_echo; return 1; fi } function function_exists() { function_to_test=$1 function_exists=$(type "$function_to_test" 2>&1 | grep -c "$function_to_test"' is a function'); if [ $function_exists -eq 1 ]; then return 1; else return 0; fi } function confirm() { function_exists get_parameter if [ $? -eq 1 ]; then forced=$(get_parameter 'force'); if [ "$forced" == "set" ]; then return 1 fi fi color_echo "${White}Confirmation requested:${NoColor}" color_echo "$@" - color_echo_n "Press ${Green}Y${NoColor}(es) to confirm or ${Red}CTRL-z${NoColor} to cancel. >>> " + color_echo_n "Press ${Green}Y${NoColor}(es) to confirm or ${Red}ENTER${NoColor} to cancel. >>> " local ans read ans case $ans in Y|y|Yes|YES|yes) color_echo "${Green}Confirmed.${NoColor}" return 1 break;; *) color_echo "${Red}Cancelled.${NoColor}" return 0 break;; esac } # EOF