bugfix
[infrastructure.git] / scripts / import-module.sh
index 6151508..121d5be 100755 (executable)
 date=$(date +%Y-%m-%d)
 
 #### REVIEW this carefully
-module=new_plc_api
-cvstag=planetlab-4_0-rc3
-previous=002-rc3-2007-05-02
-next=003-${cvstag}-${date}
+# to be provided on the command line
+#cvstag=planetlab-4_0-rc3
 
 ####
 svn="svn+ssh://thierry@svn.one-lab.org/svn"
 cvs=":pserver:anon@cvs.planet-lab.org:/cvs"
-import=$HOME/import-$module-$date
-
 
 function message () {
-  echo -n '-------------------- '
-  echo $@
-  echo -n 'Enter return to proceed .. '
-  read x
+    echo '===' $@
 }
 
 function run () {
-  echo -n '-------------------- '
-  message="$1" ; shift
-  echo $message
-  
-  echo -n 'PWD=' ; pwd
-  echo RUNNING $@
-  $@
+    message="$1" ; shift
+    echo '===' $message
+    
+    echo "= In $(pwd)"
+    echo RUNNING $@
+    $@
 }
 
+# returns 1 for true and 0 for no
+function my_prompt () {
+    default="$1" ; shift
+    question="$@" ; shift
+    case "$default" in
+       y|Y) label="[y]/n" ; retcod=1 ;;
+       n|N) label="y/[n]" ; retcod=0 ;;
+       *) label="y/n (no default)" ;;
+    esac
+    
+    while true; do
+       echo "= In $(pwd)"
+       echo -n "$question $label ? "
+       read answer
+       case $answer in 
+           y|Y)
+               return 1 ; break ;;
+           n|N) 
+               return 0 ; break ;;
+           '')
+               return $retcod ; break ;;
+           *)
+               echo 'Please enter y or n' ;;
+       esac
+    done
+}
+               
 function run_prompt () {
-  default="$1" ; shift
-  message="$1" ; shift
-  case "$default" in
-    y|Y) label="[y]/n" ;;
-    n|N) label="y/[n]" ;;
-    *) label="y/n (no default)" ;;
-  esac
-
-  echo -n '-------------------- '
-  echo $message
-  
-  echo -n 'PWD= ' ; pwd 
-  echo -n "want to run $@ $label ? "
-  read answer
-  [ -z "$answer" ] && answer=$default
-  while true; do
-    case $answer in
-      y|Y)
+    default="$1" ; shift
+    message="$1" ; shift
+    prompt_message="want to run $@" 
+
+    echo "===" $message
+    my_prompt "$default" "$prompt_message"
+    if [ "$?" == 1 ] ; then
        $@
-       break
-       ;;
-      n|N)
+    else
        echo 'Skipped'
-       break
-       ;;
-      *)
-       echo 'Please enter y or n'
-       ;;
-    esac
-  done
+    fi
 }
 
 function run_loop () {
-  message="$1" ; shift
-  while true; do
-    echo -n '-------------------- '
-    echo $message
-    echo -n PWD= ; pwd
-    echo Running $@
-    $@
-    echo -n 'OK ? y/[n] '
-    read answer
-    [ -z "$answer" ] && answer=n
-    case $answer in
-      y|Y)
-       break ;;
-      *) ;;
-  esac
-done
+    default=$1; shift
+    message="$1" ; shift
+    while true; do
+       echo '===' $message
+       echo "= In $(pwd)"
+       echo Running $@
+       $@
+       my_prompt $default "OK"
+       if [ "$?" == 1 ] ; then
+           break
+       fi
+    done
 }
 
 ### echoes OK on stdout if url exists
 function svn_url_check () {
-   url=$1; shift
-   svn list $url &> /dev/null && echo OK
+    url=$1; shift
+    svn list $url &> /dev/null && echo OK
 }
 
 ### return 'y' or 'n' for being used as prompt
 function svn_url_needs_creation () {
-   url=$1; shift
-   if [ -n "$(svn_url_check $url)" ] ; then echo n ; else echo y ; fi
+    url=$1; shift
+    if [ -n "$(svn_url_check $url)" ] ; then echo n ; else echo y ; fi
 }
 
 function dir_needs_creation () {
-   dir=$1; shift
-   if [ -d "$dir" ] ; then echo n ; else echo y ; fi
+    dir=$1; shift
+    if [ -d "$dir" ] ; then echo n ; else echo y ; fi
+}
+
+function svn_dir_needs_revert () {
+    dir=$1; shift
+    output=$(svn status $dir 2>&1)
+    if [ -n "$output" ] ; then echo y ; else echo n ; fi
+}
+
+function svn_file_needs_commit () {
+    dir=$1; shift
+    output=$(svn status $dir 2>&1)
+    if [ -n "$output" ] ; then echo y ; else echo n ; fi
 }
 
 ##############################
+# guess spec files and extract from there
+# search for <module.spec> otherwise expects a single *.spec file
+function figure_module_spec () {
+    src=$1; shift
+    module=$1; shift
+    if [ -f $src/$module.spec ] ; then
+        echo $src/$module.spec
+    else
+        nbspecs=$(ls $src/*.spec | wc -l)
+       if [ $nbspecs = 1 ] ; then
+             echo $(ls $src/*.spec)
+         else
+             echo "$0: could not guess spec file in $src"
+             exit 1
+         fi
+    fi
+}
+
+function extract_from_spec () {
+    specfile=$1; shift
+    varname=$1; shift
+    if [ ! -f $specfile ] ; then
+       echo "Could not locate $specfile -- exiting"
+       exit 1
+    fi
+    line=$(grep "^%define[ \t][ \t]*$varname" $specfile)
+    value=$(echo $line | sed -e "s,%define[ \t][ \t]*$varname[ \t][ \t]*,,")
+    echo $value
+}
+
+function patch_in_spec () {
+    specfile=$1; shift
+    varname=$1; shift
+    value=$1; shift
+
+    ### sed -i unsupported on MACOS
+    sed -e "s,^%define[ \t][ \t]*$varname[ \t].*$,%define $varname $value," $specfile > ${specfile}.new
+    mv ${specfile}.new $specfile
+}
+
 ##############################
 ##############################
+##############################
+
+function print_warning () {
 
-cat <<EOF
+    cat <<EOF
 ####### WARNING
 
  this script is quite rough and should be used with care
@@ -116,94 +167,284 @@ cat <<EOF
 
  so again : USE WITH CARE
 
+========== Your input :
 module=$module
-previous=$previous
-next=$next
 cvstag=$cvstag
+========== Hard-wired :
 svn=$svn
 cvs=$cvs
+========== Computed :
+previous=$previous
+next=$next
 date=$date
 import=$import
 ####### WARNING
 
 EOF
+}
 
 function run_test () {
-  message Hi there
-  run_prompt n "going to /etc" cd /etc
-  run_prompt y "going to /etc" cd /etc
-  run_prompt y "Cleaning up /foobar" rmdir /foobar
-  run_prompt $(dir_needs_creation /foobar) "create unexisting dir /foobar" mkdir /foobar
-  run_prompt $(dir_needs_creation /var) "create existing dir /var" mkdir /var
-  run_prompt y "Cleaning up /foobar" rmdir /foobar
-  
-  run_loop "Check this and that" ls -ls passwd
-  run "Listing passwd" ls -ls passwd
-  exit 0
-}
-
-# checks current status
-echo "------------------------------ Checking $module/imports/import-$previous"
-[ -z "$(svn_url_check $svn/$module/imports/import-$previous)" ] && echo WARNING : import-$previous not found
-
-echo ''
-
-# snapshot current status
-prompt=$(svn_url_needs_creation $svn/$module/imports/before-$next)
-run_prompt $prompt "Creating snapshot of current status" \
-   svn copy $svn/$module/trunk $svn/$module/imports/before-$next
-
-# init import dir from previous import
-prompt=$(svn_url_needs_creation $svn/$module/imports/import-$next)
-run_prompt $prompt "Preparing import-$next from import-$previous" \
-   svn copy $svn/$module/imports/import-$previous $svn/$module/imports/import-$next
+    message Hi there
+    run_prompt n "going to /etc" cd /etc
+    run_prompt y "going to /etc" cd /etc
+    run_prompt y "Cleaning up /foobar" rmdir /foobar
+    run_prompt $(dir_needs_creation /foobar) "create unexisting dir /foobar" mkdir /foobar
+    run_prompt $(dir_needs_creation /var) "create existing dir /var" mkdir /var
+    run_prompt y "Cleaning up /foobar" rmdir /foobar
+    
+    run_loop y "Check this and that" ls -ls passwd
+    run "Listing passwd" ls -ls passwd
+    exit 0
+}
 
-####
-run_prompt $(dir_needs_creation $import/$module/imports) "Creating working dir " \
-    mkdir -p $import/$module/imports
+function figure_last_import () {
+    module=$1; shift
+    last_import=$(svn list $svn/$module/imports | grep '^import-' | sort | tail -1 | sed -e s,import-,, -e s,/,,g )
+    echo $last_import
+}
+
+function figure_next_import () {
+    last_import=$1; shift
+    current_index=$(echo $last_import | sed -e 's,-.*,,')
+    # remove leading 0 that confuse printf (takes it as octal)
+    decimal_index=$(echo  $current_index | sed 's,^0*,,' )
+    next_index=$(printf "%03d" $(($decimal_index+1)))
+    echo ${next_index}-${cvstag}-${date}
+}
+
+function import_usage () {
+   echo "Usage: $0 module tag"
+   echo "All other parameters to be entered in the source file for now - sorry"
+   exit 1
+}
+
+function import_module () {
+
+    [[ -z "$@" ]] && import_usage
+    module=$1; shift
+    [[ -z "$@" ]] && import_usage
+    cvstag=$1; shift
+    [[ -n "$@" ]] && import_usage
+    import=$HOME/import-$module-$date
+
+    echo -n 'Figuring previous import ..'
+    previous=$(figure_last_import $module)
+    next=$(figure_next_import $previous)
+    echo " found $previous - next=$next"
+
+    print_warning
+
+    # checks current status
+    echo -n "-------------------- Checking $module/imports/import-$previous "
+    if [ -z "$(svn_url_check $svn/$module/imports/import-$previous)" ] ; then
+       echo FATAL : import-$previous not found
+       exit 1
+    fi
+    echo 'OK'
 
-###
-run_prompt $(dir_needs_creation $import/$module/imports/import-$next) "Checking out import-$next for applying changes" \
-    svn co $svn/$module/imports/import-$next $import/$module/imports/import-$next
+    # snapshot current status
+    prompt=$(svn_url_needs_creation $svn/$module/imports/before-$next)
+    run_prompt $prompt "Creating snapshot of current status" \
+        svn copy -mBefore-${next} $svn/$module/trunk $svn/$module/imports/before-$next
 
-run "Going there" \
-    cd $import/$module/imports
+    # init import dir from previous import
+    prompt=$(svn_url_needs_creation $svn/$module/imports/import-$next)
+    run_prompt $prompt "Preparing import-$next from import-$previous" \
+        svn copy -mCreation-from-import-${previous} $svn/$module/imports/import-$previous $svn/$module/imports/import-$next
 
-message 'NOTE: the way we merge changes right below might need to be tested/improved'
+    ####
+    run_prompt $(dir_needs_creation $import/$module/imports) "Creating working dir " \
+        mkdir -p $import/$module/imports
 
-run_prompt n "Incorporating changes since import-$previous in import-$next" \
-    cvs -d $cvs export -r $cvstag -d import-$next $module
+    ###
+    run_prompt $(dir_needs_creation $import/$module/imports/import-$next) \
+        "Checking out import-$next for applying changes" \
+        svn co $svn/$module/imports/import-$next $import/$module/imports/import-$next
 
-run "Going to import-$next" \
-    cd $import/$module/imports/import-$next
+    run "Going there" \
+        cd $import/$module/imports
 
-run_loop "Check the changes in import-$next -- no conflict expected" svn status $import/$module/imports/import-$next
+    message 'NOTE: the way we merge changes right below might need to be tested/improved'
 
-run_prompt n "CHECKING IN changes in import-$next" \
-    svn ci -m "Changes since $previous"
+    run_prompt n "Incorporating changes since import-$previous in import-$next" \
+        cvs -d $cvs export -r $cvstag -d import-$next $module
 
-###
-run "Going to $import/$module" \
-    cd $import/$module
+    run "Going to import-$next" \
+        cd $import/$module/imports/import-$next
 
-run_prompt $(dir_needs_creation $svn/$module/trunk) "Checking out trunk for applying changes" \
-    svn co $svn/$module/trunk 
+    run_loop n "Check the changes in import-$next -- no conflict expected" \
+        svn status $import/$module/imports/import-$next
 
-run_prompt n "Merging changes from import-$previous to import-$next into trunk" \
-    svn merge $svn/$module/imports/import-$previous $svn/$module/imports/import-$next trunk
+    run_prompt n "CHECKING IN imported changes in import-$next" \
+        svn ci -mApplied-changes-since-$previous
 
-run_loop "Check the changes in trunk -- conflicts should get resolved" svn status trunk
+    ###
+    run "Going to $import/$module" \
+        cd $import/$module
 
-run_prompt n "CHECKING IN changes in trunk" \
-    svn ci -m "Merged changes from import-$previous to import-$next"
+    run_prompt $(dir_needs_creation $svn/$module/trunk) "Checking out trunk for applying changes" \
+        svn co $svn/$module/trunk 
 
-prompt=$(svn_url_needs_creation $svn/$module/imports/after-$next)
-run_prompt $prompt "Backing up into after-$next" \
-    svn copy $svn/$module/$trunk $svn/$module/imports/after-$next
+    run_prompt n "Merging changes from import-$previous to import-$next into trunk" \
+        svn merge $svn/$module/imports/import-$previous $svn/$module/imports/import-$next trunk
 
-run_prompt n "Want to rename $import as $import-to-trash" \
-    mv $import $import-totrash
+    run_loop n "CHECK CHANGES in $import/$module/trunk -- conflicts should get resolved" \
+        svn status trunk
+
+    run_prompt n "CHECKING IN changes in trunk" \
+        svn ci -m "Merged changes from import-$previous to import-$next"
+
+    prompt=$(svn_url_needs_creation $svn/$module/imports/after-$next)
+    run_prompt $prompt "Backing up into after-$next" \
+       svn copy $svn/$module/$trunk $svn/$module/imports/after-$next
+
+    run_prompt n "Want to rename $import as $import-to-trash" \
+        mv $import $import-totrash
+
+    echo 'Done'
+}
+
+##############################
+function tag_usage () {
+   echo "Usage: $0 module"
+   exit 1
+}
+
+function tag_module () {
+
+    [[ -z "$@" ]] && tag_usage
+    module=$1; shift
+    tagwork=$HOME/tags/$module
+    tagtrunk=$HOME/tags/$module/trunk
+    [[ -n "$@" ]] && tag_usage
+
+    echo 'Tagging' $module
+
+    run_prompt $(dir_needs_creation $tagtrunk) "Checking out $tagtrunk" \
+        svn co $svn/$module/trunk $tagtrunk
+
+    run_prompt y "Updating $tagtrunk" \
+        svn up $tagtrunk
+
+    run_prompt $(svn_dir_needs_revert $tagtrunk) "Reverting $tagtrunk for safety " \
+        svn revert -R $tagtrunk
+
+    run "cd $tagtrunk" \
+       cd $tagtrunk
+
+    ### extracting current version info
+    spec=$(figure_module_spec $tagtrunk $module)
+    version=$(extract_from_spec $spec version)
+    subversion=$(extract_from_spec $spec subversion)
+    newsubversion=$(($subversion+1))
+
+    message "FOUND spec=$spec version=$version subversion=$subversion"
+
+    # check that the tags relating to subversion and newsubversion does (resp. does not) exist
+    oldtag=$svn/$module/tags/$module-${version}.${subversion}
+    newtag=$svn/$module/tags/$module-${version}.${newsubversion}
+
+    echo -n "Checking tags status ..."
+    old_check=$(svn_url_check $oldtag)
+    if [ -z "$old_check" ] ; then
+       echo "Former tag does not exist -- exiting"
+       echo "URL was $oldtag"
+       exit 1
+    fi
+    echo -n " old tag OK ... "
+    
+    new_check=$(svn_url_check $newtag)
+    if [ -n "$new_check" ] ; then
+       echo "New tag does exist -- exiting"
+       echo "URL was $newtag"
+       exit 1
+    fi
+    echo " new tag OK"
+    
+    patch_in_spec $spec subversion $newsubversion
+
+    run_loop y "Checking differences" \
+       svn diff $tagtrunk
+
+    run_prompt n "Display differences from previous tag" \
+       svn diff $oldtag $svn/$module/trunk
+    
+    run_prompt y "Committing changes in $tagtrunk" \
+       svn ci --editor-cmd=vi $tagtrunk
+       
+    # putting spaces in the message does not work 
+    run_prompt y "Creating tag $newtag" \
+       svn copy --message "$module-${version}.${newsubversion}" $svn/$module/trunk $newtag
+
+    # make changes in build/*-tags.mk
+    tagbuild=$HOME/tags/build/trunk
+    oldname=$module-${version}.${subversion}
+    newname=$module-${version}.${newsubversion}
+
+    run_prompt $(dir_needs_creation $tagbuild) "Checking out $tagbuild" \
+        svn co $svn/$module/build $tagbuild
+
+    run_prompt y "Updating $tagbuild" \
+        svn up $tagbuild
+
+    run_prompt $(svn_dir_needs_revert $tagbuild) "Reverting $tagbuild for safety " \
+        svn revert -R $tagbuild
+
+    run "cd $tagbuild" \
+       cd $tagbuild
+
+    # committing tags files
+    files_to_commit=""
+    for tagsmk in *-tags.mk; do
+       echo "=== Managing $tagsmk"
+       sed -i -e "s,$oldname,$newname,g" $tagsmk
+       if [ $(svn_file_needs_commit $tagsmk) = "y" ] ; then
+          echo "Changes in $tagsmk"
+          svn diff $tagsmk
+          my_prompt y "Adopt $newname in $tagsmk"
+          if [ "$?" == 1 ] ; then
+              files_to_commit="$files_to_commit $tagsmk"
+          fi
+       fi
+    done    
+    if [ -n "$files_to_commit" ] ; then
+       command="svn commit -mAdopting-$newname $files_to_commit"
+       run "Committing selected tags files" $command
+    fi
+}
+
+####################
+function diff_modules () {
+    for module in "$@" ; do
+       tagtrunk=$HOME/tags/$module/trunk
+       echo "--------------------Checking $module"
+       run_prompt y "Updating $tagwork" svn update $tagtrunk
+        ### extracting current version info
+       spec=$(figure_module_spec $tagtrunk $module)
+       version=$(extract_from_spec $spec version)
+       subversion=$(extract_from_spec $spec subversion)
+
+       echo "FOUND spec=$spec version=$version subversion=$subversion"
+
+       lasttag=$svn/$module/tags/$module-${version}.${subversion}
+       trunk=$svn/$module/trunk
+       
+       run_prompt y "Diffing : < last tag -- trunk >" svn diff $lasttag $trunk
+       
+    done
+}
 
-echo 'Done'
-exit 0
+####################
+case $0 in
+    *import-module*)
+       import_module $@;;
+    *tag-module*)
+       tag_module $@;;
+    *diff-module*)
+       diff_modules $@ ;;
+    *test*)
+#      my_prompt $@ ; echo "result=$?";;
+       run_test ;;
+    *)
+       echo "Unsupported command $0" ; exit 0
+esac