MediaWiki  REL1_22
GitInfo.php
Go to the documentation of this file.
00001 <?php
00026 class GitInfo {
00027 
00031     protected static $repo = null;
00032 
00036     protected $basedir;
00037 
00041     private static $viewers = false;
00042 
00046     public function __construct( $dir ) {
00047         $this->basedir = "{$dir}/.git";
00048         if ( is_readable( $this->basedir ) && !is_dir( $this->basedir ) ) {
00049             $GITfile = file_get_contents( $this->basedir );
00050             if ( strlen( $GITfile ) > 8 && substr( $GITfile, 0, 8 ) === 'gitdir: ' ) {
00051                 $path = rtrim( substr( $GITfile, 8 ), "\r\n" );
00052                 $isAbsolute = $path[0] === '/' || substr( $path, 1, 1 ) === ':';
00053                 $this->basedir = $isAbsolute ? $path : "{$dir}/{$path}";
00054             }
00055         }
00056     }
00057 
00062     public static function repo() {
00063         global $IP;
00064         if ( is_null( self::$repo ) ) {
00065             self::$repo = new self( $IP );
00066         }
00067         return self::$repo;
00068     }
00069 
00076     public static function isSHA1( $str ) {
00077         return !!preg_match( '/^[0-9A-F]{40}$/i', $str );
00078     }
00079 
00084     public function getHead() {
00085         $HEADfile = "{$this->basedir}/HEAD";
00086 
00087         if ( !is_readable( $HEADfile ) ) {
00088             return false;
00089         }
00090 
00091         $HEAD = file_get_contents( $HEADfile );
00092 
00093         if ( preg_match( "/ref: (.*)/", $HEAD, $m ) ) {
00094             return rtrim( $m[1] );
00095         } else {
00096             return rtrim( $HEAD );
00097         }
00098     }
00099 
00104     public function getHeadSHA1() {
00105         $HEAD = $this->getHead();
00106 
00107         // If detached HEAD may be a SHA1
00108         if ( self::isSHA1( $HEAD ) ) {
00109             return $HEAD;
00110         }
00111 
00112         // If not a SHA1 it may be a ref:
00113         $REFfile = "{$this->basedir}/{$HEAD}";
00114         if ( !is_readable( $REFfile ) ) {
00115             return false;
00116         }
00117 
00118         $sha1 = rtrim( file_get_contents( $REFfile ) );
00119 
00120         return $sha1;
00121     }
00122 
00129     public function getHeadCommitDate() {
00130         global $wgGitBin;
00131 
00132         if ( !is_file( $wgGitBin ) || !is_executable( $wgGitBin ) ) {
00133             return false;
00134         }
00135 
00136         $environment = array( "GIT_DIR" => $this->basedir );
00137         $cmd = wfEscapeShellArg( $wgGitBin ) . " show -s --format=format:%ct HEAD";
00138         $retc = false;
00139         $commitDate = wfShellExec( $cmd, $retc, $environment );
00140 
00141         if ( $retc !== 0 ) {
00142             return false;
00143         } else {
00144             return (int)$commitDate;
00145         }
00146 
00147      }
00148 
00153     public function getCurrentBranch() {
00154         $HEAD = $this->getHead();
00155         if ( $HEAD && preg_match( "#^refs/heads/(.*)$#", $HEAD, $m ) ) {
00156             return $m[1];
00157         } else {
00158             return $HEAD;
00159         }
00160     }
00161 
00167     public function getHeadViewUrl() {
00168         $config = "{$this->basedir}/config";
00169         if ( !is_readable( $config ) ) {
00170             return false;
00171         }
00172 
00173         $configArray = parse_ini_file( $config, true );
00174         $remote = false;
00175 
00176         // Use the "origin" remote repo if available or any other repo if not.
00177         if ( isset( $configArray['remote origin'] ) ) {
00178             $remote = $configArray['remote origin'];
00179         } else {
00180             foreach ( $configArray as $sectionName => $sectionConf ) {
00181                 if ( substr( $sectionName, 0, 6 ) == 'remote' ) {
00182                     $remote = $sectionConf;
00183                 }
00184             }
00185         }
00186 
00187         if ( $remote === false || !isset( $remote['url'] ) ) {
00188             return false;
00189         }
00190 
00191         $url = $remote['url'];
00192         if ( substr( $url, -4 ) !== '.git' ) {
00193             $url .= '.git';
00194         }
00195         foreach ( self::getViewers() as $repo => $viewer ) {
00196             $pattern = '#^' . $repo . '$#';
00197             if ( preg_match( $pattern, $url, $matches ) ) {
00198                 $viewerUrl = preg_replace( $pattern, $viewer, $url );
00199                 $headSHA1 = $this->getHeadSHA1();
00200                 $replacements = array(
00201                     '%h' => substr( $headSHA1, 0, 7 ),
00202                     '%H' => $headSHA1,
00203                     '%r' => urlencode( $matches[1] ),
00204                 );
00205                 return strtr( $viewerUrl, $replacements );
00206             }
00207         }
00208         return false;
00209     }
00210 
00215     public static function headSHA1() {
00216         return self::repo()->getHeadSHA1();
00217     }
00218 
00223     public static function currentBranch() {
00224         return self::repo()->getCurrentBranch();
00225     }
00226 
00231     public static function headViewUrl() {
00232         return self::repo()->getHeadViewUrl();
00233     }
00234 
00239     protected static function getViewers() {
00240         global $wgGitRepositoryViewers;
00241 
00242         if ( self::$viewers === false ) {
00243             self::$viewers = $wgGitRepositoryViewers;
00244             wfRunHooks( 'GitViewers', array( &self::$viewers ) );
00245         }
00246 
00247         return self::$viewers;
00248     }
00249 }