git.php 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. <?php
  2. /**
  3. * Gestion du téléporteur GIT.
  4. *
  5. * @plugin SVP pour SPIP
  6. * @license GPL
  7. * @package SPIP\SVP\Teleporteur
  8. */
  9. /**
  10. * Téléporter et déballer un composant GIT
  11. *
  12. * Déployer un repository GIT depuis une source et une révision données
  13. *
  14. * @param string $methode
  15. * Méthode de téléportation : http|git|svn|...
  16. * @param string $source
  17. * URL de la source GIT
  18. * @param string $dest
  19. * Chemin du répertoire de destination
  20. * @param array $options
  21. * Tableau d'options. Index possibles :
  22. * - revision => 'ae89'
  23. * - branche => 'xxx'
  24. * @return bool
  25. * True si l'opération réussie, false sinon.
  26. */
  27. function teleporter_git_dist($methode,$source,$dest,$options=array()){
  28. $branche = (isset($options['branche'])?$options['branche']:'master');
  29. if (is_dir($dest)){
  30. $infos = teleporter_git_read($dest,array('format'=>'assoc'));
  31. if (!$infos){
  32. spip_log("Suppression de $dest qui n'est pas au format GIT","teleport");
  33. $old = teleporter_nettoyer_vieille_version($dest);
  34. }
  35. elseif ($infos['source']!==$source) {
  36. spip_log("Suppression de $dest qui n'est pas sur le bon repository GIT","teleport");
  37. $old = teleporter_nettoyer_vieille_version($dest);
  38. }
  39. elseif (!isset($options['revision'])
  40. OR $options['revision']!=$infos['revision']){
  41. $command = "git checkout ".escapeshellarg($branche);
  42. teleporter_git_exec($dest,$command);
  43. $command = "git pull --all";
  44. teleporter_git_exec($dest,$command);
  45. if (isset($options['revision'])){
  46. $command = "git checkout ".escapeshellarg($options['revision']);
  47. teleporter_git_exec($dest,$command);
  48. }
  49. else {
  50. $command = "git checkout ".escapeshellarg($branche);
  51. teleporter_git_exec($dest,$command);
  52. }
  53. }
  54. else {
  55. spip_log("$dest deja sur GIT $source Revision ".$options['revision'],"teleport");
  56. }
  57. }
  58. if (!is_dir($dest)){
  59. $command = "git clone ";
  60. $command .= escapeshellarg($source)." ".escapeshellarg($dest);
  61. teleporter_git_exec($dest,$command);
  62. if (isset($options['revision'])){
  63. $command = "git checkout ".escapeshellarg($options['revision']);
  64. teleporter_git_exec($dest,$command);
  65. }
  66. }
  67. // verifier que tout a bien marche
  68. $infos = teleporter_git_read($dest);
  69. if (!$infos) return false;
  70. return true;
  71. }
  72. /**
  73. * Lire l'état GIT du repository
  74. *
  75. * Retourne les informations GIT d'un répertoire donné
  76. *
  77. * @param string $dest
  78. * Chemin du répertoire à tester
  79. * @param array $options
  80. * Tableau d'options
  81. * @return string|bool|array
  82. * - Chaîne vide si pas un dépot GIT
  83. * - False si erreur sur le dépot GIT
  84. * - array sinon. Tableau avec 3 index :
  85. * -- source : Source du dépot GIT à cette destination
  86. * -- revision : Révision du dépot
  87. * -- dest : Répertoire du dépot.
  88. */
  89. function teleporter_git_read($dest, $options=array()) {
  90. if (!is_dir("$dest/.git"))
  91. return "";
  92. $curdir = getcwd();
  93. chdir($dest);
  94. exec("git remote -v",$output);
  95. $output = implode("\n",$output);
  96. $source = "";
  97. if (preg_match(",(\w+://.*)\s+\(fetch\)$,Uims",$output,$m))
  98. $source = $m[1];
  99. elseif (preg_match(",([^@\s]+@[^:\s]+:.*)\s+\(fetch\)$,Uims",$output,$m))
  100. $source = $m[1];
  101. if (!$source){
  102. chdir($curdir);
  103. return "";
  104. }
  105. $source = $m[1];
  106. exec("git log -1",$output);
  107. $hash = explode(" ",reset($output));
  108. $hash = end($hash);
  109. // [TODO] lire la branche ?
  110. chdir($curdir);
  111. if (preg_match(",[^0-9a-f],i",$hash))
  112. return false;
  113. return array(
  114. 'source' => $source,
  115. 'revision' => substr($hash,0,7),
  116. 'dest' => $dest
  117. );
  118. }
  119. /**
  120. * Exécuter une commande GIT
  121. *
  122. * @param string $dest
  123. * Répertoire de destination
  124. * @param string $command
  125. * Commande à exécuter
  126. * @return void
  127. */
  128. function teleporter_git_exec($dest,$command) {
  129. spip_log("{$dest}:{$command}","teleport");
  130. $curdir = getcwd();
  131. chdir($dest);
  132. exec($command);
  133. chdir($curdir);
  134. }