Advertisement
Wyvern67

Maque

Nov 22nd, 2015
222
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 4.66 KB | None | 0 0
  1. #!/bin/sh
  2.  
  3. printUsage(){
  4.     cat <<EOL
  5. Usage: $(basename $0) [-kn] [-f path] target
  6. Options:
  7.     -f Use "path" as a makefile
  8.     -k Ignore potential errors when executing the makefile's commands
  9.     -n Print the makefile's commands instead of running them
  10. EOL
  11. }
  12.  
  13. debug(){
  14.     local DEBUG=true
  15.     $DEBUG && echo "$*"
  16. }
  17.  
  18. stringContain() {
  19.     #$1 une chaîne et $2 une recherche
  20.     if echo "$1" | grep "$2">/dev/null
  21.     then
  22.         return 0
  23.     else
  24.         return 1
  25.     fi
  26. }
  27.  
  28. getDependenciesInString(){
  29.     #dependencies=$(echo $1 | sed "s/^.*:\(.*$\)/\1/" | sed "s/[[:space:]]*$//")
  30.     local dependencies=$(echo $1 | sed "s/.*:[[:space:]]*//")
  31.     echo $dependencies
  32. }
  33.  
  34. getDependenciesForTarget(){
  35.     local dependencies=$(cat $makefile | grep -e "^$1:" | sed "s/.*:[[:space:]]*//")
  36.     echo $dependencies
  37. }
  38.  
  39. needsAnUpdate(){
  40.     local target="$1"
  41.     local dependency="$2"
  42.  
  43.     if [ -f "$dependency" ]
  44.     then
  45.         if ! [ -f "$target" ]
  46.         then
  47.             debug "'$dependency existe mais pas '$target'"
  48.             return 0 #la dépendance existe mais sa cible non: je choisis de ne pas retélécharger la dépendance
  49.         fi
  50.  
  51.         if [ $(find $dependency -newer $target | wc -l) -le 0 ] #Si cible >=récente que dépendance
  52.         then
  53.             debug "'$target' plus récent que '$dependency'"
  54.             return 1 #pas d'update
  55.         else
  56.             debug "'$target' moins récent que '$dependency'"
  57.             return 0 #besoin d'update
  58.         fi
  59.     else
  60.         debug "'$dependency' n'existe pas et pas moyen de le créer"
  61.         return 2 #dépendance manquante (pas d'update donc)
  62.     fi
  63. }
  64.  
  65. isATarget(){
  66.     local target=$1
  67.     if cat "$makefile" | grep -e "^$target\:" > /dev/null
  68.     then
  69.         return 0
  70.     else
  71.         return 1
  72.     fi
  73. }
  74.  
  75. dummy(){
  76.     #Parfois,j'ai besoin d'une fonction qui ne fait rien
  77.     return 0
  78. }
  79.  
  80. readOptions(){
  81.     ARGU=$(getopt "f:kn" $*)
  82.     set - $ARGU
  83.     for i
  84.     do
  85.             #debug "$i"
  86.             case "$i" in
  87.             -f) makefile="$2"
  88.                 shift
  89.                 shift;;
  90.             -k) runBlindly=false
  91.                 shift;;
  92.             -n) runInVain=true
  93.                 shift;;
  94.             \?) echo "Option $i was not recognized"
  95.             exit 1;;
  96.             --) shift
  97.                 break;;
  98.             esac
  99.     done
  100.     return 0
  101. }
  102.  
  103. myMake(){
  104.     debug ""
  105.     debug "myMake '$1'"
  106.     local dependencies=$(getDependenciesForTarget "$1")
  107.     debug "Dependencies:    '$dependencies'"
  108.     if ! [ -z "$dependencies" ]
  109.     then
  110.         local i
  111.         local hasUpdated=0
  112.         for i in "$dependencies"
  113.         do
  114.             debug "for '$i' do"
  115.             if isATarget "$i"
  116.             then
  117.                 debug "$i est une cible"
  118.                 if myMake "$i"
  119.                 then
  120.                     hasUpdated=$(expr $hasUpdated + 1)
  121.                 fi
  122.             else
  123.                 if needsAnUpdate "$1" "$i"
  124.                 then #besoin d'update
  125.                     hasUpdated=$(expr $hasUpdated + 1)
  126.                 else #pas besoin d'update
  127.                     dummy
  128.                 fi
  129.             fi
  130.         done
  131.  
  132.         if [ "$hasUpdated" -eq 0 ]
  133.         then
  134.             debug "Pas besoin de mettre à jour '$1'"
  135.             return 1
  136.         fi
  137.     fi
  138.  
  139.     update "$1"
  140.     ret=$?
  141.     if $runBlindly #si option -k: ignorer les erreurs
  142.     then
  143.         return 0
  144.     else #pas d'option -k: vérifier si tout a marché
  145.         if [ "$ret" -ne 0 ]
  146.         then
  147.             error "Error: couldn't update $i."
  148.             exit 1
  149.         else
  150.             return 0
  151.         fi
  152.     fi
  153. }
  154.  
  155. update(){
  156.     local currentTarget="$tmpdir/$1.tmp"
  157.     debug "J'update '$currentTarget'"
  158.     if ! [ -z "$1" ]
  159.     then
  160.         if $runInVain
  161.         then
  162.             cat "$currentTarget"
  163.             return 0
  164.         else
  165.             sh "$currentTarget"
  166.             return $?
  167.         fi
  168.     fi
  169. }
  170.  
  171. #Ici on gère les options, j'assigne à des variables des valeurs par défaut qui sont ensuite
  172. #modifiées ou pas par la fonction readOptions()
  173. runBlindly=true
  174. runInVain=false
  175. makefile=$(find . -name [mM]akefile -maxdepth 1) #Cherche un makefile
  176. readOptions $*
  177. if ! [ -z $makefile ] && ls $makefile #Si $makefile non vide et fichier trouvable
  178. then
  179.     dummy #Ne fait rien
  180. else
  181.     error "Error: 404: makefile not found"
  182.     exit 1
  183. fi
  184.  
  185. #Vrai code
  186. tmpdir="/tmp/$(basename $0)-$$" #ex: /tmp/myMake.sh-3645
  187. if $DEBUG
  188. then
  189.     rm -r /tmp/t.sh-*
  190. else
  191.     trap "rm -r $tmpdir" EXIT
  192. fi
  193. mkdir "$tmpdir"
  194.  
  195. #Ici on parse le fichier
  196. cat "$makefile" | while read -r i
  197. do
  198.     i=$(echo $i | sed "s/#.*//g") #Remplace tout ce qui est après # par rien du tout
  199.     if ! [ -z "$i" ]; then
  200.         #ici on traite toutes les lignes intéressantes du makefile par le biais de $i
  201.         #(non vides, sans les commentaires...)
  202.         #debug "    [$i]"
  203.         if stringContain "$i" ':' #ligne contenant une cible
  204.         then
  205.             currentTarget=$(echo "$i" | sed 's/:.*//g') #juste le path de la cible
  206.             debug "Target:              [$currentTarget]"
  207.             dependencies=$(getDependenciesInString "$i")
  208.             debug "Dependencies:        [$dependencies]"
  209.         else
  210.             debug "Commands:            [$i]"
  211.             echo "$i" >> "$tmpdir/$currentTarget.tmp" #ex: /tmp/myMake.sh-3645/toto.o.tmp
  212.         fi
  213.     fi
  214. done #< $makefile
  215.  
  216. if [ "$#" -ne 1 ] && ! $DEBUG
  217. then
  218.     printUsage
  219.     exit 1
  220. fi
  221.  
  222. #Code de test
  223.  
  224.  
  225. #Vrai code
  226.  
  227. if $DEBUG
  228. then
  229.     myMake "clean"
  230.     exit 0
  231. fi
  232.  
  233.  
  234. myMake "$1"
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement