diff --git a/bin/bamc b/bin/bamc index 09abbdf..35b32c9 100755 --- a/bin/bamc +++ b/bin/bamc @@ -1,35 +1,34 @@ #!/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/tools.sh 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_sanity.sh source $DIR_LIB/bamc_help.sh -source $DIR_LIB/bamc_actions.sh source $DIR_LIB/bamc_workspace.sh source $DIR_LIB/bamc_exams.sh source $DIR_LIB/bamc_templates.sh source $DIR_LIB/bamc_projects.sh source $DIR_LIB/bamc_amc-commands.sh DEFAULT_ITEMS=$(get_exam_list) DEFAULT_ACTIONS="help" CALLBACK_PREFIX="action_" run $@ RC=$? debug "Return code: $RC" exit $RC diff --git a/conf/bamc.conf b/conf/bamc.conf index 50b271c..9362ef2 100644 --- a/conf/bamc.conf +++ b/conf/bamc.conf @@ -1,54 +1,55 @@ #!/bin/bash # Worspace DIR_QUESTIONS='questions' DIR_EXAMS='exams' DIR_PROJECTS='projects' FILE_WORKSPACE_ROOT=".workspace_root" # Configuration dirs DIR_DATA=$(realpath $SPATH/../data) DIR_WORKSPACE_TEMPLATE=$DIR_DATA/workspace DIR_EXAM_TEMPLATES=$DIR_DATA/templates # Template DEFAULT_EXAM_TEMPLATE="default" +FILE_PROJECT_BUILD="project_build_script.sh" # Configuration files FILE_AMC_OPTIONS='options.xml' # Output dirs DIR_PROJECTS='projects' DIR_SAMPLES='pdf-samples' DIR_BLANKS='pdf-blanks' DIR_PDFS='pdf-exams' DIR_LISTS='pdf-lists' # Intput files FILE_SECTIONS='sections.conf' FILE_EXAM='exam.conf' FILE_STUDENTS='students.csv' # Variables EXTRA_STUDENTS=9 PDFLATEX_RUNS=1 return 0 FILE_SAMPLE_CSV='sample.csv' FILE_EXTRA_CSV='extra.csv' FILE_BLANK_CSV='blank.csv' FILE_AMC_MAILING='mailing.xml' FILE_LIST_MAIN='list.tex' FILE_LIST_TSTART='start_tab.tex' FILE_LIST_TEND='end_tab.tex' # OUTPUT FILES FILE_RESULTS='raw' FILE_EMAILS_SCRIPT='send_emails.sh' FILE_LIST_ROWS='rows.tex' # VARIABLES DEFAULT_EMAIL='pierre-olivier.valles@epfl.ch' LIST_ROWS_PER_PAGE=50 LIST_MAX_CHAR=30 diff --git a/lib/bash/bamc_projects.sh b/data/templates/maths/project_build_script.sh similarity index 70% copy from lib/bash/bamc_projects.sh copy to data/templates/maths/project_build_script.sh index 5848d2f..35e182f 100644 --- a/lib/bash/bamc_projects.sh +++ b/data/templates/maths/project_build_script.sh @@ -1,234 +1,225 @@ #!/bin/bash -function action_clean() { - local exams=$@ - local exam - for exam in $(echo $exams); do - assert_exam $exam - if [ $? -eq 1 ]; then return 1; fi - verbose "Cleaning '$exam' in workspace '$DIR_WORKSPACE'..." - - confirm "Clean project and outputs for exam '$exam' ?" - if [ $? -eq 0 ]; then return 0; fi - - for dir in $(echo $DIR_WORKSPACE/$DIR_PROJECTS $DIR_WORKSPACE/$DIR_SAMPLES $DIR_WORKSPACE/$DIR_BLANKS $DIR_WORKSPACE/$DIR_PDFS $DIR_WORKSPACE/$DIR_LISTS); do - if [ -d "$dir/$exam" ]; then - verbose "Removing directory: '$dir/$exam'" - rm -rf "$dir/$exam/" - else - verbose "Removing files: '$dir/$exam*'" - rm -rf $dir/$exam-* - rm -rf $dir/*-$exam* - fi - if [ -d "$dir" ]; then - if [ $(ls -1A $dir/ | wc -l) -eq 0 ]; then - verbose "Removing now empty directory: '$dir'" - rmdir $dir/ - fi - fi - done - done - return 0 -} - -function action_project() { - # Get exam template to use - assert_template - if [ $? -ne 0 ]; then return 1; fi - local exams=$@ - local exam lang - for exam in $(echo $exams); do - assert_exam $exam - lang=$(get_lang $exam) - verbose "Project '$exam' uses '$lang' language" - - if [ $? -eq 1 ]; then return 1; fi - verbose "Building AMC project for '$exam' in workspace '$DIR_WORKSPACE'..." - - # Project structure - build_amc_project $exam - if [ $? -ne 0 ]; then error "Could not build AMC project :("; return 1; fi +# This part is specific to the template. +# Entry point from bamc: build_project $exam +# $exam: name of the exam to build +# +# Useful variable +# --------------- +# DIR_WORKSPACE [current workspace dir (absolute)] +# DIR_PROJECTS [projects target directory] +# DIR_EXAMS [exams'directory in workspace] e.g. $DIR_WORKSPACE/$DIR_EXAMS/$exam +# DIR_PROJECTS [projects's directory in workspace] +# DIR_EXAM_TEMPLATE [directory of the exam template in use] +# FILE_STUDENTS +# ... +# see 'conf/bamc.conf' for full reference +# +# Useful functions +# ---------------- +# verbose "text" +# debug "text" +# get_lang $exam +# ... +# see 'lib/bash/*.sh' files for full reference + +function build_project() { + local exam=$1 lang=$(get_lang $exam) + assert_exam $exam + verbose "Project '$exam' uses '$lang' language" + + if [ $? -eq 1 ]; then return 1; fi + verbose "Building AMC project for '$exam' in workspace '$DIR_WORKSPACE'..." + + # Project structure + build_amc_project $exam + if [ $? -ne 0 ]; then error "Could not build AMC project :("; return 1; fi + + # Build LaTeX sections + build_sections $exam $lang + if [ $? -ne 0 ]; then error "Could not build project sections :("; return 1; fi + + # Import LaTeX files + import_tex_files $exam $lang + if [ $? -ne 0 ]; then error "Could not import LaTeX files :("; return 1; fi + + # Import local LaTeX files + override_tex_files $exam + if [ $? -ne 0 ]; then error "Could not override LaTeX files :("; return 1; fi + + # Customize LaTeX file + customize_tex_files $exam $lang + if [ $? -ne 0 ]; then error "Could not customize LaTeX files :("; return 1; fi + + # Import media files + add_media_files $exam + if [ $? -ne 0 ]; then error "Could not import media files :("; return 1; fi + + # Build student list file + import_student_file $exam + if [ $? -ne 0 ]; then error "Could not create student list :("; return 1; fi - # Build LaTeX sections - build_sections $exam $lang - if [ $? -ne 0 ]; then error "Could not build project sections :("; return 1; fi - - import_tex_files $exam $lang - if [ $? -ne 0 ]; then error "Could not import LaTeX files :("; return 1; fi - - override_tex_files $exam - if [ $? -ne 0 ]; then error "Could not override LaTeX files :("; return 1; fi - - customize_tex_files $exam $lang - if [ $? -ne 0 ]; then error "Could not customize LaTeX files :("; return 1; fi - - add_media_files $exam - if [ $? -ne 0 ]; then error "Could import media files :("; return 1; fi - - import_student_file $exam - done return 0 } function import_student_file() { verbose "Customizing LaTeX files" local project=$DIR_WORKSPACE/$DIR_PROJECTS/$1 local exam=$DIR_WORKSPACE/$DIR_EXAMS/$1 local lang=$2 local FILE=$exam/$FILE_STUDENTS check_file_exists $FILE if [ $? -ne 0 ]; then return 1; fi cp $FILE $project/$FILE_STUDENTS # Add extra students local nb IFS=$'\n' local id=$(tail -n 1 $project/$FILE_STUDENTS | cut -d ',' -f 1) local sample=$(head -n 1 $DIR_EXAM_TEMPLATE/csv/extra.csv) nb=0 while [ $nb -lt $EXTRA_STUDENTS ]; do ((nb++)) ((id++)) echo $sample |\ sed "s/#NB#/$nb/g" |\ sed "s/#ID#/$id/g" |\ sed "s/#SCIPER#/FAKE-$nb/g" |\ sed "s/#EMAIL#/$DEFAULT_EMAIL/g" |\ sed "s/#SEMESTER#/$SEMESTER/g" >> $project/$FILE_STUDENTS done return 0 } function add_media_files() { verbose "Importing media files" local project=$DIR_WORKSPACE/$DIR_PROJECTS/$1 cp $DIR_EXAM_TEMPLATE/media/* $project/media/ } function replace_in_file() { local pattern=$1 string=$2 filename=$3 sed "s/$pattern/$string/g" $filename > /tmp/sed.tmp.$$ mv /tmp/sed.tmp.$$ $filename return 0 } function customize_tex_files() { verbose "Customizing LaTeX files" local project=$DIR_WORKSPACE/$DIR_PROJECTS/$1 local exam=$DIR_WORKSPACE/$DIR_EXAMS/$1 local lang=$2 local replace IFS=$'\n' local FILE=$exam/$FILE_EXAM check_file_exists $FILE if [ $? -ne 0 ]; then return 1; fi # professor.tex local prof_file=$project/professor.tex check_file_exists $prof_file if [ $? -ne 0 ]; then return 1; fi for replace in $(cat $FILE); do replace_in_file "#$(echo $replace | cut -d ':' -f 1)#" "$(echo $replace | cut -d ':' -f 2-)" $prof_file done # exam.tex replace_in_file "#LANG#" $(echo $lang | tr '[a-z]' '[A-Z]') $project/exam.tex # Add extra_section.tex file if [ -r $exam/extra_section.tex ]; then sed -i 's?% #EXTRA_SECTION#?\\input{./extra_section.tex}?g' $project/exam.tex fi # Add extra_packages.tex file if [ -r $exam/extra_packages.tex ]; then sed -i 's?% #EXTRA_PACKAGES#?\\input{./extra_packages.tex}?g' $project/exam.tex fi return 0 } function override_tex_files() { verbose "Overriding LaTeX files (if needed)" local exam=$DIR_WORKSPACE/$DIR_EXAMS/$1 local project=$DIR_WORKSPACE/$DIR_PROJECTS/$1 local f for f in $(find $exam/ -type f -name '*.tex'); do verbose "- LaTeX override file found: $f" done find $exam/ -type f -name '*.tex' -exec cp {} $project/ \; } function import_tex_files() { verbose "Importing LaTeX files" local project=$DIR_WORKSPACE/$DIR_PROJECTS/$1 local lang=$2 cp $DIR_EXAM_TEMPLATE/base/* $project/ cp $DIR_EXAM_TEMPLATE/$lang/* $project/ return 0 } function build_amc_project() { local project=$DIR_WORKSPACE/$DIR_PROJECTS/$1 verbose "Creating AMC project structure" mkdir -p $project/cr/corrections/jpg mkdir -p $project/cr/corrections/pdf mkdir -p $project/cr/diagnostic mkdir -p $project/cr/zooms mkdir -p $project/data mkdir -p $project/exports mkdir -p $project/scans mkdir -p $project/copies mkdir -p $project/media cp $DIR_EXAM_TEMPLATE/config/$FILE_AMC_OPTIONS $project/$FILE_AMC_OPTIONS return $? } function get_exam_parameter() { cat $DIR_WORKSPACE/$DIR_EXAMS/$1/$FILE_EXAM | grep "^$2:" | cut -d ':' -f 2- } function get_lang() { get_exam_parameter $1 'LANG' } function build_sections() { local project=$DIR_WORKSPACE/$DIR_PROJECTS/$1 local exam=$DIR_WORKSPACE/$DIR_EXAMS/$1 local lang=$2 local question_file question section_file section local IFS=$'\n' FILE=$exam/$FILE_SECTIONS verbose "Importing questions" check_file_exists $FILE if [ $? -ne 0 ]; then return 1; fi local section_num=0 rm -f $project/sections.tex $project/random-sections.tex for section in $(cat $FILE); do ((section_num++)) section_file=$project/section_${section_num}.tex rm -f $section_file for question in $(echo $section | tr ',' '\n'); do verbose "Adding $question to section $section_file..."; question_file=$DIR_WORKSPACE/$DIR_QUESTIONS/$lang/$question check_file_exists $question_file if [ $? -ne 0 ]; then return 1; fi echo "%% From $lang/$question =======================================" >> $section_file echo '\element{section'$section_num'}{' >> $section_file cat $question_file >> $section_file echo '}' >> $section_file done echo "\input{./section_${section_num}.tex}" >> $project/sections.tex echo "\input{./header_${section_num}.tex} \melangegroupe{section${section_num}} \restituegroupe{section${section_num}} " >> $project/random-sections.tex done return 0 } - # EOF diff --git a/lib/bash/bamc_actions.sh b/lib/bash/bamc_actions.sh deleted file mode 100644 index a96bc3e..0000000 --- a/lib/bash/bamc_actions.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/bash - -function check_action() { - local action=$1 - 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 - return 0 - else - return 1 - fi -} - -function action_switch() { - local action=$1 - local function_to_call="${CALLBACK_PREFIX}${action}" - check_action $action - if [ $? -eq 0 ]; then - debug "Calling action '$action' => '${CALLBACK_PREFIX}${action}' on item(s) '$(get_items)'" - $function_to_call $(get_items) - #rc=$((rc+$?)) - return $? - else - error "invalid action: '$action' => '${CALLBACK_PREFIX}${action}' (not implemented ?)" - return 1 - fi - return 0 -} - -# EOF diff --git a/lib/bash/bamc_projects.sh b/lib/bash/bamc_projects.sh index 5848d2f..ce90946 100644 --- a/lib/bash/bamc_projects.sh +++ b/lib/bash/bamc_projects.sh @@ -1,234 +1,61 @@ #!/bin/bash function action_clean() { local exams=$@ local exam for exam in $(echo $exams); do assert_exam $exam if [ $? -eq 1 ]; then return 1; fi - verbose "Cleaning '$exam' in workspace '$DIR_WORKSPACE'..." + perma "Cleaning '$exam'" confirm "Clean project and outputs for exam '$exam' ?" if [ $? -eq 0 ]; then return 0; fi for dir in $(echo $DIR_WORKSPACE/$DIR_PROJECTS $DIR_WORKSPACE/$DIR_SAMPLES $DIR_WORKSPACE/$DIR_BLANKS $DIR_WORKSPACE/$DIR_PDFS $DIR_WORKSPACE/$DIR_LISTS); do if [ -d "$dir/$exam" ]; then verbose "Removing directory: '$dir/$exam'" rm -rf "$dir/$exam/" else verbose "Removing files: '$dir/$exam*'" rm -rf $dir/$exam-* rm -rf $dir/*-$exam* fi if [ -d "$dir" ]; then if [ $(ls -1A $dir/ | wc -l) -eq 0 ]; then verbose "Removing now empty directory: '$dir'" rmdir $dir/ fi fi done done return 0 } function action_project() { # Get exam template to use assert_template if [ $? -ne 0 ]; then return 1; fi - local exams=$@ - local exam lang - for exam in $(echo $exams); do - assert_exam $exam - lang=$(get_lang $exam) - verbose "Project '$exam' uses '$lang' language" - - if [ $? -eq 1 ]; then return 1; fi - verbose "Building AMC project for '$exam' in workspace '$DIR_WORKSPACE'..." - - # Project structure - build_amc_project $exam - if [ $? -ne 0 ]; then error "Could not build AMC project :("; return 1; fi - - # Build LaTeX sections - build_sections $exam $lang - if [ $? -ne 0 ]; then error "Could not build project sections :("; return 1; fi - import_tex_files $exam $lang - if [ $? -ne 0 ]; then error "Could not import LaTeX files :("; return 1; fi - - override_tex_files $exam - if [ $? -ne 0 ]; then error "Could not override LaTeX files :("; return 1; fi - - customize_tex_files $exam $lang - if [ $? -ne 0 ]; then error "Could not customize LaTeX files :("; return 1; fi - - add_media_files $exam - if [ $? -ne 0 ]; then error "Could import media files :("; return 1; fi - - import_student_file $exam - done - return 0 -} - -function import_student_file() { - verbose "Customizing LaTeX files" - local project=$DIR_WORKSPACE/$DIR_PROJECTS/$1 - local exam=$DIR_WORKSPACE/$DIR_EXAMS/$1 - local lang=$2 - - local FILE=$exam/$FILE_STUDENTS - check_file_exists $FILE + # Check we have a build script for this template + check_file_exists $DIR_EXAM_TEMPLATE/$FILE_PROJECT_BUILD if [ $? -ne 0 ]; then return 1; fi - cp $FILE $project/$FILE_STUDENTS - - # Add extra students - local nb IFS=$'\n' - local id=$(tail -n 1 $project/$FILE_STUDENTS | cut -d ',' -f 1) - local sample=$(head -n 1 $DIR_EXAM_TEMPLATE/csv/extra.csv) - nb=0 - while [ $nb -lt $EXTRA_STUDENTS ]; do - ((nb++)) - ((id++)) - echo $sample |\ - sed "s/#NB#/$nb/g" |\ - sed "s/#ID#/$id/g" |\ - sed "s/#SCIPER#/FAKE-$nb/g" |\ - sed "s/#EMAIL#/$DEFAULT_EMAIL/g" |\ - sed "s/#SEMESTER#/$SEMESTER/g" >> $project/$FILE_STUDENTS - done - return 0 -} - + # Source it ! + source $DIR_EXAM_TEMPLATE/$FILE_PROJECT_BUILD -function add_media_files() { - verbose "Importing media files" - local project=$DIR_WORKSPACE/$DIR_PROJECTS/$1 - cp $DIR_EXAM_TEMPLATE/media/* $project/media/ -} + # Check we now have a 'build_project' function + function_exists 'build_project' + if [ $? -ne 0 ]; then error "This template's build script ($DIR_EXAM_TEMPLATE/$FILE_PROJECT_BUILD) is not valid (no 'build_project' function)." ; return 1; fi - -function replace_in_file() { - local pattern=$1 string=$2 filename=$3 - sed "s/$pattern/$string/g" $filename > /tmp/sed.tmp.$$ - mv /tmp/sed.tmp.$$ $filename - return 0 -} - -function customize_tex_files() { - verbose "Customizing LaTeX files" - local project=$DIR_WORKSPACE/$DIR_PROJECTS/$1 - local exam=$DIR_WORKSPACE/$DIR_EXAMS/$1 - local lang=$2 - - local replace IFS=$'\n' - local FILE=$exam/$FILE_EXAM - check_file_exists $FILE - if [ $? -ne 0 ]; then return 1; fi - - # professor.tex - local prof_file=$project/professor.tex - check_file_exists $prof_file - if [ $? -ne 0 ]; then return 1; fi - for replace in $(cat $FILE); do - replace_in_file "#$(echo $replace | cut -d ':' -f 1)#" "$(echo $replace | cut -d ':' -f 2-)" $prof_file - done - - # exam.tex - replace_in_file "#LANG#" $(echo $lang | tr '[a-z]' '[A-Z]') $project/exam.tex - - # Add extra_section.tex file - if [ -r $exam/extra_section.tex ]; then - sed -i 's?% #EXTRA_SECTION#?\\input{./extra_section.tex}?g' $project/exam.tex - fi - # Add extra_packages.tex file - if [ -r $exam/extra_packages.tex ]; then - sed -i 's?% #EXTRA_PACKAGES#?\\input{./extra_packages.tex}?g' $project/exam.tex - fi - - return 0 -} - -function override_tex_files() { - verbose "Overriding LaTeX files (if needed)" - local exam=$DIR_WORKSPACE/$DIR_EXAMS/$1 - local project=$DIR_WORKSPACE/$DIR_PROJECTS/$1 - local f - for f in $(find $exam/ -type f -name '*.tex'); do - verbose "- LaTeX override file found: $f" - done - find $exam/ -type f -name '*.tex' -exec cp {} $project/ \; -} - -function import_tex_files() { - verbose "Importing LaTeX files" - local project=$DIR_WORKSPACE/$DIR_PROJECTS/$1 - local lang=$2 - cp $DIR_EXAM_TEMPLATE/base/* $project/ - cp $DIR_EXAM_TEMPLATE/$lang/* $project/ - return 0 -} - -function build_amc_project() { - local project=$DIR_WORKSPACE/$DIR_PROJECTS/$1 - verbose "Creating AMC project structure" - mkdir -p $project/cr/corrections/jpg - mkdir -p $project/cr/corrections/pdf - mkdir -p $project/cr/diagnostic - mkdir -p $project/cr/zooms - mkdir -p $project/data - mkdir -p $project/exports - mkdir -p $project/scans - mkdir -p $project/copies - mkdir -p $project/media - cp $DIR_EXAM_TEMPLATE/config/$FILE_AMC_OPTIONS $project/$FILE_AMC_OPTIONS - return $? -} - -function get_exam_parameter() { - cat $DIR_WORKSPACE/$DIR_EXAMS/$1/$FILE_EXAM | grep "^$2:" | cut -d ':' -f 2- -} - -function get_lang() { - get_exam_parameter $1 'LANG' -} - -function build_sections() { - local project=$DIR_WORKSPACE/$DIR_PROJECTS/$1 - local exam=$DIR_WORKSPACE/$DIR_EXAMS/$1 - local lang=$2 - - local question_file question section_file section - local IFS=$'\n' FILE=$exam/$FILE_SECTIONS - - verbose "Importing questions" - check_file_exists $FILE - if [ $? -ne 0 ]; then return 1; fi - - local section_num=0 - rm -f $project/sections.tex $project/random-sections.tex - for section in $(cat $FILE); do - ((section_num++)) - section_file=$project/section_${section_num}.tex - rm -f $section_file - for question in $(echo $section | tr ',' '\n'); do - verbose "Adding $question to section $section_file..."; - question_file=$DIR_WORKSPACE/$DIR_QUESTIONS/$lang/$question - check_file_exists $question_file - if [ $? -ne 0 ]; then return 1; fi - echo "%% From $lang/$question =======================================" >> $section_file - echo '\element{section'$section_num'}{' >> $section_file - cat $question_file >> $section_file - echo '}' >> $section_file - done - echo "\input{./section_${section_num}.tex}" >> $project/sections.tex - echo "\input{./header_${section_num}.tex} -\melangegroupe{section${section_num}} -\restituegroupe{section${section_num}} -" >> $project/random-sections.tex + # Good. Proceed. + verbose "Building projects using script '$DIR_EXAM_TEMPLATE/$FILE_PROJECT_BUILD'" + local exams=$@ exam lang rc=0 + for exam in $(echo $exams); do + perma "Building project for exam '$exam'" + build_project $exam; + rc=$((rc+$?)) done - return 0 + return $rc } - # EOF diff --git a/lib/bash/cmdline_parser.sh b/lib/bash/cmdline_parser.sh index eeeafbc..3d5f146 100644 --- a/lib/bash/cmdline_parser.sh +++ b/lib/bash/cmdline_parser.sh @@ -1,109 +1,129 @@ #!/bin/bash -# Command line parser +# Reusable command line parser # USAGE: [in the calling script] -# 1) set the global variables: $DEFAULT_ITEMS and $DEFAULT_ACTIONS +# 1) set the global variables: $DEFAULT_ITEMS, $DEFAULT_PARAMS 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 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 # Source local configuration (if any) source_workspace_configuration # Compute final ITEMS if [ -z "$ITEMS" ]; then ITEMS=$(get_default_items); fi if [ -z "$ITEMS" ]; then ITEMS='~no~items~'; fi # Compute final ACTIONS if [ -z "$ACTIONS" ]; then ACTIONS=$(get_default_actions); fi if [ -z "$ACTIONS" ]; then ACTIONS='help'; fi # Compute final PARAMS PARAMS=$(echo $PARAMS,$(get_default_params) | tr "," "\n" | sort -u | grep -v '^$' | tr "\n" "," | sed 's/,$//') debug "End of command line parsing. ACTIONS: '$ACTIONS' | ITEMS: '$ITEMS' | PARAMS: '$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 debug "Running action '$action'" action_switch $action $item rc=$((rc+$?)) done return $rc } function get_default_items() { echo $DEFAULT_ITEMS } function get_default_params() { echo $DEFAULT_PARAMS } function get_default_actions() { echo $DEFAULT_ACTIONS } +function check_action() { + function_exists $1 + return $? +} + +function action_switch() { + local action=$1 + local function_to_call="${CALLBACK_PREFIX}${action}" + check_action $function_to_call + if [ $? -eq 0 ]; then + debug "Calling action '$action' => '$function_to_call' on item(s) '$(get_items)'" + $function_to_call $(get_items) + return $? + else + error "invalid action: '$action' => '${CALLBACK_PREFIX}${action}' (not implemented ?)" + return 1 + fi + return 0 +} + # EOF diff --git a/lib/bash/debugging.sh b/lib/bash/debugging.sh index f27af71..10c83e5 100644 --- a/lib/bash/debugging.sh +++ b/lib/bash/debugging.sh @@ -1,30 +1,34 @@ #!/bin/bash function error() { error_echo $@ } function warn() { warning_echo $@ } function debug() { is_set debug if [ $? -eq 1 ]; then debug_echo $@; fi } +function perma() { + color_echo "${Green}*${NoColor} "$@ +} + function verbose() { is_set verbose - if [ $? -eq 1 ]; then color_echo "${Green}*${NoColor} "$@; fi + if [ $? -eq 1 ]; then echo " "$@; fi } function check_file_exists() { if [ -r $1 ]; then return 0 else error "File not found: $1" return 1 fi } # EOF diff --git a/lib/bash/io.sh b/lib/bash/io.sh index 072afc7..8d64774 100644 --- a/lib/bash/io.sh +++ b/lib/bash/io.sh @@ -1,70 +1,64 @@ #!/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}WARNING:${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 + if [ $? -eq 0 ]; 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}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 diff --git a/lib/bash/tools.sh b/lib/bash/tools.sh index f6165c7..4043555 100644 --- a/lib/bash/tools.sh +++ b/lib/bash/tools.sh @@ -1,35 +1,43 @@ #!/bin/bash +function function_exists() { + if [ $(type "$1" 2>&1 | grep -c "$1"' is a function') -eq 1 ]; then + return 0 + else + return 1 + fi +} + function check_OS() { OS=$(uname | tr "[A-Z]" "[a-z]") if [ "$OS" == "linux" ]; then return 0; fi OS="unknown" return 1 } function check_OS_subtype() { OS_SUBTYPE="unknown" if [ -r /etc/gentoo-release ]; then OS_SUBTYPE="gentoo"; return 0; fi return 1 } function check_AMC_version() { AMC_VERSION="unknown" which auto-multiple-choice > /dev/null 2>&1 if [ $? -gt 0 ]; then AMC_VERSION="none" return 1 fi case $OS in "linux") case $OS_SUBTYPE in "gentoo") AMC_VERSION=$(eix --xml auto-multiple-choice | grep 'installed="1"' | tr " " "\n" | grep '^id' | cut -d '"' -f 2) return 0;; esac esac return 1 } # EOF