Browse Source

Removed gitlist from repo.

development
Teknikode 4 years ago
parent
commit
2d4accd684
100 changed files with 0 additions and 14127 deletions
  1. 0
    13
      git/.htaccess
  2. 0
    11
      git/.travis.yml
  3. 0
    88
      git/INSTALL.md
  4. 0
    9
      git/LICENSE.txt
  5. 0
    86
      git/README.md
  6. 0
    12
      git/boot.php
  7. 0
    27
      git/config.ini-example
  8. 0
    82
      git/index.php
  9. 0
    19
      git/phpunit.xml
  10. 0
    28
      git/phpunit.xml.dist
  11. 0
    101
      git/src/GitList/Application.php
  12. 0
    78
      git/src/GitList/Config.php
  13. 0
    74
      git/src/GitList/Controller/BlobController.php
  14. 0
    120
      git/src/GitList/Controller/CommitController.php
  15. 0
    76
      git/src/GitList/Controller/MainController.php
  16. 0
    126
      git/src/GitList/Controller/NetworkController.php
  17. 0
    124
      git/src/GitList/Controller/TreeController.php
  18. 0
    8
      git/src/GitList/Exception/BlankDataException.php
  19. 0
    8
      git/src/GitList/Exception/EmptyRepositoryException.php
  20. 0
    187
      git/src/GitList/Git/Client.php
  21. 0
    395
      git/src/GitList/Git/Repository.php
  22. 0
    33
      git/src/GitList/Provider/GitServiceProvider.php
  23. 0
    26
      git/src/GitList/Provider/RepositoryUtilServiceProvider.php
  24. 0
    26
      git/src/GitList/Provider/RoutingUtilServiceProvider.php
  25. 0
    26
      git/src/GitList/Provider/ViewUtilServiceProvider.php
  26. 0
    223
      git/src/GitList/Util/Repository.php
  27. 0
    163
      git/src/GitList/Util/Routing.php
  28. 0
    48
      git/src/GitList/Util/View.php
  29. 0
    7
      git/vendor/autoload.php
  30. 0
    7
      git/vendor/bin/pdepend
  31. 0
    3
      git/vendor/bin/pdepend.bat
  32. 0
    7
      git/vendor/bin/phploc
  33. 0
    3
      git/vendor/bin/phploc.bat
  34. 0
    7
      git/vendor/bin/phpmd
  35. 0
    3
      git/vendor/bin/phpmd.bat
  36. 0
    7
      git/vendor/bin/phpunit
  37. 0
    3
      git/vendor/bin/phpunit.bat
  38. 0
    246
      git/vendor/composer/ClassLoader.php
  39. 0
    529
      git/vendor/composer/autoload_classmap.php
  40. 0
    22
      git/vendor/composer/autoload_namespaces.php
  41. 0
    9
      git/vendor/composer/autoload_psr4.php
  42. 0
    43
      git/vendor/composer/autoload_real.php
  43. 0
    19
      git/vendor/composer/include_paths.php
  44. 0
    679
      git/vendor/composer/installed.json
  45. 0
    5
      git/vendor/klaussilveira/gitter/.gitignore
  46. 0
    11
      git/vendor/klaussilveira/gitter/.travis.yml
  47. 0
    9
      git/vendor/klaussilveira/gitter/LICENSE
  48. 0
    56
      git/vendor/klaussilveira/gitter/README.md
  49. 0
    30
      git/vendor/klaussilveira/gitter/composer.json
  50. 0
    522
      git/vendor/klaussilveira/gitter/composer.lock
  51. 0
    114
      git/vendor/klaussilveira/gitter/lib/Gitter/Client.php
  52. 0
    29
      git/vendor/klaussilveira/gitter/lib/Gitter/Model/AbstractModel.php
  53. 0
    75
      git/vendor/klaussilveira/gitter/lib/Gitter/Model/Blob.php
  54. 0
    29
      git/vendor/klaussilveira/gitter/lib/Gitter/Model/Branch.php
  55. 0
    46
      git/vendor/klaussilveira/gitter/lib/Gitter/Model/Commit/Author.php
  56. 0
    179
      git/vendor/klaussilveira/gitter/lib/Gitter/Model/Commit/Commit.php
  57. 0
    73
      git/vendor/klaussilveira/gitter/lib/Gitter/Model/Commit/Diff.php
  58. 0
    68
      git/vendor/klaussilveira/gitter/lib/Gitter/Model/Commit/DiffLine.php
  59. 0
    61
      git/vendor/klaussilveira/gitter/lib/Gitter/Model/Line.php
  60. 0
    49
      git/vendor/klaussilveira/gitter/lib/Gitter/Model/Object.php
  61. 0
    55
      git/vendor/klaussilveira/gitter/lib/Gitter/Model/Symlink.php
  62. 0
    34
      git/vendor/klaussilveira/gitter/lib/Gitter/Model/Tag.php
  63. 0
    184
      git/vendor/klaussilveira/gitter/lib/Gitter/Model/Tree.php
  64. 0
    40
      git/vendor/klaussilveira/gitter/lib/Gitter/PrettyFormat.php
  65. 0
    588
      git/vendor/klaussilveira/gitter/lib/Gitter/Repository.php
  66. 0
    66
      git/vendor/klaussilveira/gitter/lib/Gitter/Util/DateTime.php
  67. 0
    18
      git/vendor/klaussilveira/gitter/phpunit.xml.dist
  68. 0
    102
      git/vendor/klaussilveira/gitter/tests/Gitter/Tests/ClientTest.php
  69. 0
    43
      git/vendor/klaussilveira/gitter/tests/Gitter/Tests/Model/Commit/CommitTest.php
  70. 0
    49
      git/vendor/klaussilveira/gitter/tests/Gitter/Tests/PrettyFormatTest.php
  71. 0
    503
      git/vendor/klaussilveira/gitter/tests/Gitter/Tests/RepositoryTest.php
  72. 0
    32
      git/vendor/klaussilveira/gitter/tests/Gitter/Tests/Util/DateTimeTest.php
  73. 0
    10
      git/vendor/pdepend/pdepend/.gitignore
  74. 0
    3
      git/vendor/pdepend/pdepend/.gitmodules
  75. 0
    16
      git/vendor/pdepend/pdepend/.travis.yml
  76. 0
    416
      git/vendor/pdepend/pdepend/CHANGELOG
  77. 0
    31
      git/vendor/pdepend/pdepend/LICENSE
  78. 0
    17
      git/vendor/pdepend/pdepend/build.properties
  79. 0
    87
      git/vendor/pdepend/pdepend/build.xml
  80. 0
    10
      git/vendor/pdepend/pdepend/composer.json
  81. 0
    15
      git/vendor/pdepend/pdepend/pdepend.xml.dist
  82. 0
    36
      git/vendor/pdepend/pdepend/phpunit.xml.dist
  83. 0
    13
      git/vendor/pdepend/pdepend/scripts/compare.sh
  84. 0
    225
      git/vendor/pdepend/pdepend/scripts/update-manifest.php
  85. 0
    204
      git/vendor/pdepend/pdepend/scripts/update-version.php
  86. 0
    78
      git/vendor/pdepend/pdepend/src/bin/pdepend
  87. 0
    46
      git/vendor/pdepend/pdepend/src/bin/pdepend.bat
  88. 0
    78
      git/vendor/pdepend/pdepend/src/bin/pdepend.php
  89. 0
    919
      git/vendor/pdepend/pdepend/src/conf/package.xml
  90. 0
    70
      git/vendor/pdepend/pdepend/src/conf/phar_bootstrap.stub
  91. 0
    733
      git/vendor/pdepend/pdepend/src/main/php/PHP/Depend.php
  92. 0
    87
      git/vendor/pdepend/pdepend/src/main/php/PHP/Depend/Autoload.php
  93. 0
    142
      git/vendor/pdepend/pdepend/src/main/php/PHP/Depend/Builder/Context.php
  94. 0
    184
      git/vendor/pdepend/pdepend/src/main/php/PHP/Depend/Builder/Context/GlobalStatic.php
  95. 0
    2329
      git/vendor/pdepend/pdepend/src/main/php/PHP/Depend/Builder/Default.php
  96. 0
    1211
      git/vendor/pdepend/pdepend/src/main/php/PHP/Depend/BuilderI.php
  97. 0
    97
      git/vendor/pdepend/pdepend/src/main/php/PHP/Depend/Code/ASTAllocationExpression.php
  98. 0
    95
      git/vendor/pdepend/pdepend/src/main/php/PHP/Depend/Code/ASTArguments.php
  99. 0
    94
      git/vendor/pdepend/pdepend/src/main/php/PHP/Depend/Code/ASTArray.php
  100. 0
    0
      git/vendor/pdepend/pdepend/src/main/php/PHP/Depend/Code/ASTArrayElement.php

+ 0
- 13
git/.htaccess View File

@@ -1,13 +0,0 @@
<IfModule mod_rewrite.c>
Options -MultiViews

RewriteEngine On
#RewriteBase /path/to/gitlist/

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [L,NC]
</IfModule>
<Files config.ini>
order allow,deny
deny from all
</Files>

+ 0
- 11
git/.travis.yml View File

@@ -1,11 +0,0 @@
language: php

before_script:
- curl -s http://getcomposer.org/installer | php
- php composer.phar install --dev

php:
- 5.3
- 5.4

script: phpunit

+ 0
- 88
git/INSTALL.md View File

@@ -1,88 +0,0 @@
# GitList Installation
* Download GitList from [gitlist.org](http://gitlist.org/) and decompress to your `/var/www/gitlist` folder, or anywhere else you want to place GitList.
* Rename the `config.ini-example` file to `config.ini`.
* Open up the `config.ini` and configure your installation. You'll have to provide where your repositories are located and the base GitList URL (in our case, http://localhost/gitlist).
* Create the cache folder and give read/write permissions to your web server user:

```
cd /var/www/gitlist
mkdir cache
chmod 777 cache
```

That's it, installation complete!

## Webserver configuration
Apache is the "default" webserver for GitList. You will find the configuration inside the `.htaccess` file. However, nginx and lighttpd are also supported.

### nginx server.conf

```
server {
server_name MYSERVER;
access_log /var/log/nginx/MYSERVER.access_log main;
error_log /var/log/nginx/MYSERVER.error_log debug_http;

root /var/www/DIR;
index index.php;

# auth_basic "Restricted";
# auth_basic_user_file rhtpasswd;

location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}

location ~* ^/index.php.*$ {
fastcgi_pass 127.0.0.1:9000;
include fastcgi.conf;
}

location / {
try_files $uri @gitlist;
}

location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
add_header Vary "Accept-Encoding";
expires max;
try_files $uri @gitlist;
tcp_nodelay off;
tcp_nopush on;
}

# location ~* \.(git|svn|patch|htaccess|log|route|plist|inc|json|pl|po|sh|ini|sample|kdev4)$ {
# deny all;
# }

location @gitlist {
rewrite ^/.*$ /index.php;
}
}
```

### lighttpd

```
# GitList is located in /var/www/gitlist
server.document-root = "/var/www"

url.rewrite-once = (
"^/gitlist/web/.+" => "$0",
"^/gitlist/favicon\.ico$" => "$0",
"^/gitlist(/[^\?]*)(\?.*)?" => "/gitlist/index.php$1$2"
)
```

### hiawatha

```
UrlToolkit {
ToolkitID = gitlist
RequestURI isfile Return
# If you have example.com/gitlist/ ; Otherwise remove "/gitlist" below
Match ^/gitlist/.* Rewrite /gitlist/index.php
Match ^/gitlist/.*\.ini DenyAccess
}
```

+ 0
- 9
git/LICENSE.txt View File

@@ -1,9 +0,0 @@
Copyright (c) 2012, Klaus Silveira and contributors
All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
Neither the name of GitList nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ 0
- 86
git/README.md View File

@@ -1,86 +0,0 @@
# GitList: an elegant and modern git repository viewer
[![Build Status](https://secure.travis-ci.org/klaussilveira/gitlist.png)](http://travis-ci.org/klaussilveira/gitlist)

GitList is an elegant and modern web interface for interacting with multiple git repositories. It allows you to browse repositories using your favorite browser, viewing files under different revisions, commit history, diffs. It also generates RSS feeds for each repository, allowing you to stay up-to-date with the latest changes anytime, anywhere. GitList was written in PHP, on top of the [Silex](http://silex.sensiolabs.org/) microframework and powered by the Twig template engine. This means that GitList is easy to install and easy to customize. Also, the GitList gorgeous interface was made possible due to [Bootstrap](http://twitter.github.com/bootstrap/).

## Features
* Multiple repository support
* Multiple branch support
* Multiple tag support
* Commit history, blame, diff
* RSS feeds
* Syntax highlighting
* Repository statistics

## Screenshots
[![GitList Screenshot](http://dl.dropbox.com/u/62064441/th1.jpg)](http://cloud.github.com/downloads/klaussilveira/gitlist/1.jpg)
[![GitList Screenshot](http://dl.dropbox.com/u/62064441/th2.jpg)](http://cloud.github.com/downloads/klaussilveira/gitlist/2.jpg)
[![GitList Screenshot](http://dl.dropbox.com/u/62064441/th3.jpg)](http://cloud.github.com/downloads/klaussilveira/gitlist/3.jpg)
[![GitList Screenshot](http://dl.dropbox.com/u/62064441/th4.jpg)](http://cloud.github.com/downloads/klaussilveira/gitlist/4.jpg)
[![GitList Screenshot](http://dl.dropbox.com/u/62064441/th5.jpg)](http://cloud.github.com/downloads/klaussilveira/gitlist/5.jpg)

You can also see a live demo [here](http://git.gofedora.com).

## Authors and contributors
* [Klaus Silveira](http://www.klaussilveira.com) (Creator, developer)

## License
[New BSD license](http://www.opensource.org/licenses/bsd-license.php)

## Todo
* improve the current test code coverage
* test the interface
* error handling can be greatly improved during parsing
* submodule support
* multilanguage support

## Requirements
In order to run GitList on your server, you'll need:

* git
* Apache with mod_rewrite enabled or nginx
* PHP 5.3.3

## Installing
* Download GitList from [gitlist.org](http://gitlist.org/) and decompress to your `/var/www/gitlist` folder, or anywhere else you want to place GitList.
* Rename the `config.ini-example` file to `config.ini`.
* Open up the `config.ini` and configure your installation. You'll have to provide where your repositories are located and the base GitList URL (in our case, http://localhost/gitlist).
* Create the cache folder and give read/write permissions to your web server user:

```
cd /var/www/gitlist
mkdir cache
chmod 777 cache
```

That's it, installation complete! If you're having problems, check this [tutorial](http://gofedora.com/insanely-awesome-web-interface-git-repos/) by Kulbir Saini or the [Troubleshooting](https://github.com/klaussilveira/gitlist/wiki/Troubleshooting) page.

## Building
GitList uses [Composer](http://getcomposer.org/) to manage dependencies and [Ant](http://ant.apache.org/) to build the project. In order to run all the targets in the build script, you will need [PHPUnit](http://www.phpunit.de/), [phpcpd](https://github.com/sebastianbergmann/phpcpd), [phploc](https://github.com/sebastianbergmann/phploc), [PHPMD](http://phpmd.org/) and [PHP_Depend](http://pdepend.org).

Once you have all the dependencies set, you can clone the repository and run Ant:

```
git clone https://github.com/klaussilveira/gitlist.git
ant
```

If you just want to get the project dependencies, instead of building everything:

```
git clone https://github.com/klaussilveira/gitlist.git
curl -s http://getcomposer.org/installer | php
php composer.phar install
```

If you have Composer in your path, things get easier. But you know the drill.

## Contributing
If you are a developer, we need your help. GitList is a young project and we have lot's of stuff to do. Some developers are contributing with new features, others with bug fixes. But you can also dedicate yourself to refactoring the current codebase and improving what we already have. This is very important, we want GitList to be a state-of-the-art application, and we need your help for that.

* Stay tuned to possible bugs, suboptimal code, duplicated code, overcomplicated expressions and unused code with [PHPMD](http://ci.gitlist.org:8080/job/GitList%20\(master\)/9/pmdResult/?) in our CI server
* Try to fix any [violations](http://ci.gitlist.org:8080/job/GitList%20\(master\)/violations/) reported
* Improve the [test coverage](http://ci.gitlist.org:8080/job/GitList%20\(master\)/9/cloverphp-report/) by creating unit and functional tests

## Further information
If you want to know more about customizing GitList, check the [Customization](https://github.com/klaussilveira/gitlist/wiki/Customizing) page on the wiki. Also, if you're having problems with GitList, check the [Troubleshooting](https://github.com/klaussilveira/gitlist/wiki/Troubleshooting) page. Don't forget to report issues and suggest new features! :)

+ 0
- 12
git/boot.php View File

@@ -1,12 +0,0 @@
<?php

// Startup and configure Silex application
$app = new GitList\Application($config, __DIR__);

// Mount the controllers
$app->mount('', new GitList\Controller\MainController());
$app->mount('', new GitList\Controller\BlobController());
$app->mount('', new GitList\Controller\CommitController());
$app->mount('', new GitList\Controller\TreeController());

return $app;

+ 0
- 27
git/config.ini-example View File

@@ -1,27 +0,0 @@
[git]
client = '/usr/bin/git' ; Your git executable path
default_branch = 'master' ; Default branch when HEAD is detached
repositories[] = '/home/git/repositories/' ; Path to your repositories
; If you wish to add more repositories, just add a new line

; WINDOWS USERS
;client = '"C:\Program Files (x86)\Git\bin\git.exe"' ; Your git executable path
;repositories[] = 'C:\Path\to\Repos\' ; Path to your repositories

; You can hide repositories from GitList, just copy this for each repository you want to hide
; hidden[] = '/home/git/repositories/BetaTest'

[app]
debug = false
cache = true

; If you need to specify custom filetypes for certain extensions, do this here
[filetypes]
; extension = type
; dist = xml

; If you need to set file types as binary or not, do this here
[binary_filetypes]
; extension = true
; svh = false
; map = true

+ 0
- 82
git/index.php View File

@@ -1,82 +0,0 @@
<?php

/**
* GitList 0.3
* https://github.com/klaussilveira/gitlist
*/

// Set the default timezone for systems without date.timezone set in php.ini
if (!ini_get('date.timezone')) {
date_default_timezone_set('UTC');
}

require_once('../includes/config.php');

$url = curPageURL();
$pattern = "/^(.*)((\/zipball\/)|(\/tarball\/)|(\/raw\/))(.*)$/";
if(!preg_match($pattern, $url))
{
include('../templates/'.$CONF['template'].'/header.php');

set_page_title("Teknik Git");
}

if (php_sapi_name() == 'cli-server' && file_exists(substr($_SERVER['REQUEST_URI'], 1))) {
return false;
}

if (!is_writable(__DIR__ . DIRECTORY_SEPARATOR . 'cache')) {
die(sprintf('The "%s" folder must be writable for GitList to run.', __DIR__ . DIRECTORY_SEPARATOR . 'cache'));
}

require 'vendor/autoload.php';

$config = GitList\Config::fromFile('config.ini');
$config->set('app', 'clone_url', 'git://teknik.io/');
if ($_GET['user'])
{
if ($userTools->checkUsernameExists($_GET['user']))
{
if (is_dir($CONF['git_repo_path'][0]."\\u\\".$_GET['user']) && !is_dir_empty($CONF['git_repo_path'][0]."\\u\\".$_GET['user']))
{
$_SERVER['HTTP_X_ORIGINAL_URL'] = str_replace("/u/".$_GET['user'], "", $_SERVER['HTTP_X_ORIGINAL_URL']);
$config->set('git', 'repositories', array($CONF['git_repo_path'][0].'\\u\\'.$_GET['user']));
$config->set('git', 'hidden', array(''));
$config->set('app', 'path_prefix', '/u/'.$_GET['user']);
$config->set('app', 'clone_url', 'git://teknik.io/u/'.$_GET['user'].'/');
$app = require 'boot.php';
$app->run();
}
else
{
?>
<div class="row">
<div class="col-sm-12 text-center">
<h2>That user has no repositories</h2>
</div>
</div>
<?php
}
}
else
{
?>
<div class="row">
<div class="col-sm-12 text-center">
<h2>That user doesn't exist</h2>
</div>
</div>
<?php
}
}
else
{
$app = require 'boot.php';
$app->run();
}

if(!preg_match($pattern, $url))
{
include('../templates/'.$CONF['template'].'/footer.php');
}
?>

+ 0
- 19
git/phpunit.xml View File

@@ -1,19 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>

<phpunit backupGlobals="false"
backupStaticAttributes="false"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="true"
syntaxCheck="true"
bootstrap="./vendor/autoload.php"
>
<testsuites>
<testsuite name="GitList Test Suite">
<directory>./tests/</directory>
</testsuite>
</testsuites>
</phpunit>

+ 0
- 28
git/phpunit.xml.dist View File

@@ -1,28 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>

<phpunit backupGlobals="false"
backupStaticAttributes="false"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="true"
syntaxCheck="true"
bootstrap="./vendor/autoload.php"
>
<testsuites>
<testsuite name="GitList Test Suite">
<directory>./tests/</directory>
</testsuite>
</testsuites>
<filter>
<whitelist processUncoveredFilesFromWhitelist="true">
<directory suffix=".php">src</directory>
</whitelist>
</filter>
<logging>
<log type="coverage-clover" target="build/logs/clover.xml" />
<log type="junit" target="build/logs/junit.xml" logIncompleteSkipped="false" />
</logging>
</phpunit>

+ 0
- 101
git/src/GitList/Application.php View File

@@ -1,101 +0,0 @@
<?php

namespace GitList;

use Silex\Application as SilexApplication;
use Silex\Provider\TwigServiceProvider;
use Silex\Provider\UrlGeneratorServiceProvider;
use GitList\Provider\GitServiceProvider;
use GitList\Provider\RepositoryUtilServiceProvider;
use GitList\Provider\ViewUtilServiceProvider;
use GitList\Provider\RoutingUtilServiceProvider;

/**
* GitList application.
*/
class Application extends SilexApplication
{
protected $path;

/**
* Constructor initialize services.
*
* @param Config $config
* @param string $root Base path of the application files (views, cache)
*/
public function __construct(Config $config, $root = null)
{
parent::__construct();
$app = $this;
$this->path = realpath($root);

$this['debug'] = $config->get('app', 'debug');
$this['filetypes'] = $config->getSection('filetypes');
$this['cache.archives'] = $this->getCachePath() . 'archives';
$this['path_prefix'] = $config->get('app', 'path_prefix');
$this['clone_url'] = $config->get('app', 'clone_url');

// Register services
$this->register(new TwigServiceProvider(), array(
'twig.path' => $this->getViewPath(),
'twig.options' => $config->get('app', 'cache') ?
array('cache' => $this->getCachePath() . 'views') : array(),
));

$repositories = $config->get('git', 'repositories');

$this->register(new GitServiceProvider(), array(
'git.client' => $config->get('git', 'client'),
'git.repos' => $repositories,
'ini.file' => "config.ini",
'git.hidden' => $config->get('git', 'hidden') ?
$config->get('git', 'hidden') : array(),
'git.default_branch' => $config->get('git', 'default_branch') ?
$config->get('git', 'default_branch') : 'master',
));

$this->register(new ViewUtilServiceProvider());
$this->register(new RepositoryUtilServiceProvider());
$this->register(new UrlGeneratorServiceProvider());
$this->register(new RoutingUtilServiceProvider());

$this['twig'] = $this->share($this->extend('twig', function ($twig, $app) {
$twig->addFilter('htmlentities', new \Twig_Filter_Function('htmlentities'));
$twig->addFilter('md5', new \Twig_Filter_Function('md5'));

return $twig;
}));

// Handle errors
$this->error(function (\Exception $e, $code) use ($app) {
if ($app['debug']) {
return;
}

return $app['twig']->render('error.twig', array(
'message' => $e->getMessage(),
));
});
}

public function getPath()
{
return $this->path . DIRECTORY_SEPARATOR;
}
public function setPath($path)
{
$this->path = $path;
return $this;
}

public function getCachePath()
{
return $this->path . DIRECTORY_SEPARATOR . 'cache' . DIRECTORY_SEPARATOR;
}

public function getViewPath()
{
return $this->path . DIRECTORY_SEPARATOR . 'views' . DIRECTORY_SEPARATOR;
}
}

+ 0
- 78
git/src/GitList/Config.php View File

@@ -1,78 +0,0 @@
<?php

namespace GitList;

class Config
{
protected $data;

public static function fromFile($file)
{
if (!file_exists($file)) {
die(sprintf('Please, create the %1$s file.', $file));
}

$data = parse_ini_file($file, true);
$config = new static($data);
$config->validateOptions();

return $config;
}

public function __construct($data = array())
{
$this->data = $data;
}

public function get($section, $option)
{
if (!array_key_exists($section, $this->data)) {
return false;
}

if (!array_key_exists($option, $this->data[$section])) {
return false;
}

return $this->data[$section][$option];
}

public function getSection($section)
{
if (!array_key_exists($section, $this->data)) {
return false;
}

return $this->data[$section];
}

public function set($section, $option, $value)
{
$this->data[$section][$option] = $value;
}

protected function validateOptions()
{
$repositories = $this->get('git', 'repositories');

$atLeastOneOk = false;
$atLeastOneWrong = false;

foreach ($repositories as $directory) {
if (!$directory || !is_dir($directory)) {
$atLeastOneWrong = true;
} else {
$atLeastOneOk = true;
}
}

if (!$atLeastOneOk) {
die("Please, edit the config file and provide your repositories directory");
}

if ($atLeastOneWrong) {
die("One or more of the supplied repository paths appears to be wrong. Please, check the config file");
}
}
}


+ 0
- 74
git/src/GitList/Controller/BlobController.php View File

@@ -1,74 +0,0 @@
<?php

namespace GitList\Controller;

use Silex\Application;
use Silex\ControllerProviderInterface;
use Symfony\Component\HttpFoundation\Response;

class BlobController implements ControllerProviderInterface
{
public function connect(Application $app)
{
$route = $app['controllers_factory'];

$route->get('{repo}/blob/{commitishPath}', function ($repo, $commitishPath) use ($app) {
$repository = $app['git']->getRepositoryFromName($app['git.repos'], $repo);

list($branch, $file) = $app['util.routing']
->parseCommitishPathParam($commitishPath, $repo);

list($branch, $file) = $app['util.repository']->extractRef($repository, $branch, $file);

$blob = $repository->getBlob("$branch:\"$file\"");
$breadcrumbs = $app['util.view']->getBreadcrumbs($file);
$fileType = $app['util.repository']->getFileType($file);

if ($fileType !== 'image' && $app['util.repository']->isBinary($file)) {
return $app->redirect($app['url_generator']->generate('blob_raw', array(
'repo' => $repo,
'commitishPath' => $commitishPath,
)));
}

return $app['twig']->render('file.twig', array(
'file' => $file,
'fileType' => $fileType,
'blob' => $blob->output(),
'repo' => $repo,
'branch' => $branch,
'breadcrumbs' => $breadcrumbs,
'branches' => $repository->getBranches(),
'tags' => $repository->getTags(),
));
})->assert('repo', $app['util.routing']->getRepositoryRegex())
->assert('commitishPath', '.+')
->bind('blob');

$route->get('{repo}/raw/{commitishPath}', function ($repo, $commitishPath) use ($app) {
$repository = $app['git']->getRepositoryFromName($app['git.repos'], $repo);

list($branch, $file) = $app['util.routing']
->parseCommitishPathParam($commitishPath, $repo);

list($branch, $file) = $app['util.repository']->extractRef($repository, $branch, $file);

$blob = $repository->getBlob("$branch:\"$file\"")->output();

$headers = array();
if ($app['util.repository']->isBinary($file)) {
$headers['Content-Disposition'] = 'attachment; filename="' . $file . '"';
$headers['Content-Type'] = 'application/octet-stream';
} else {
$headers['Content-Type'] = 'text/plain';
}

return new Response($blob, 200, $headers);
})->assert('repo', $app['util.routing']->getRepositoryRegex())
->assert('commitishPath', $app['util.routing']->getCommitishPathRegex())
->bind('blob_raw');

return $route;
}
}


+ 0
- 120
git/src/GitList/Controller/CommitController.php View File

@@ -1,120 +0,0 @@
<?php

namespace GitList\Controller;

use Silex\Application;
use Silex\ControllerProviderInterface;
use Symfony\Component\HttpFoundation\Request;

class CommitController implements ControllerProviderInterface
{
public function connect(Application $app)
{
$route = $app['controllers_factory'];

$route->get('{repo}/commits/{commitishPath}', function ($repo, $commitishPath) use ($app) {
$repository = $app['git']->getRepositoryFromName($app['git.repos'], $repo);

if ($commitishPath === null) {
$commitishPath = $repository->getHead();
}

list($branch, $file) = $app['util.routing']
->parseCommitishPathParam($commitishPath, $repo);

list($branch, $file) = $app['util.repository']->extractRef($repository, $branch, $file);

$type = $file ? "$branch -- \"$file\"" : $branch;
$pager = $app['util.view']->getPager($app['request']->get('page'), $repository->getTotalCommits($type));
$commits = $repository->getPaginatedCommits($type, $pager['current']);
$categorized = array();

foreach ($commits as $commit) {
$date = $commit->getDate();
$date = $date->format('m/d/Y');
$categorized[$date][] = $commit;
}

$template = $app['request']->isXmlHttpRequest() ? 'commits_list.twig' : 'commits.twig';

return $app['twig']->render($template, array(
'page' => 'commits',
'pager' => $pager,
'repo' => $repo,
'branch' => $branch,
'branches' => $repository->getBranches(),
'tags' => $repository->getTags(),
'commits' => $categorized,
'file' => $file,
));
})->assert('repo', $app['util.routing']->getRepositoryRegex())
->assert('commitishPath', $app['util.routing']->getCommitishPathRegex())
->value('commitishPath', null)
->bind('commits');

$route->post('{repo}/commits/{branch}/search', function (Request $request, $repo, $branch = '') use ($app) {
$repository = $app['git']->getRepositoryFromName($app['git.repos'], $repo);
$query = $request->get('query');

$commits = $repository->searchCommitLog($request->get('query'));
$categorized = array();

foreach ($commits as $commit) {
$date = $commit->getDate();
$date = $date->format('m/d/Y');
$categorized[$date][] = $commit;
}

return $app['twig']->render('searchcommits.twig', array(
'repo' => $repo,
'branch' => $branch,
'file' => '',
'commits' => $categorized,
'branches' => $repository->getBranches(),
'tags' => $repository->getTags(),
'query' => $query
));
})->assert('repo', $app['util.routing']->getRepositoryRegex())
->assert('branch', $app['util.routing']->getBranchRegex())
->bind('searchcommits');

$route->get('{repo}/commit/{commit}', function ($repo, $commit) use ($app) {
$repository = $app['git']->getRepositoryFromName($app['git.repos'], $repo);
$commit = $repository->getCommit($commit);
$branch = $repository->getHead();

return $app['twig']->render('commit.twig', array(
'branch' => $branch,
'repo' => $repo,
'commit' => $commit,
));
})->assert('repo', $app['util.routing']->getRepositoryRegex())
->assert('commit', '[a-f0-9^]+')
->bind('commit');

$route->get('{repo}/blame/{commitishPath}', function ($repo, $commitishPath) use ($app) {
$repository = $app['git']->getRepositoryFromName($app['git.repos'], $repo);

list($branch, $file) = $app['util.routing']
->parseCommitishPathParam($commitishPath, $repo);

list($branch, $file) = $app['util.repository']->extractRef($repository, $branch, $file);

$blames = $repository->getBlame("$branch -- \"$file\"");

return $app['twig']->render('blame.twig', array(
'file' => $file,
'repo' => $repo,
'branch' => $branch,
'branches' => $repository->getBranches(),
'tags' => $repository->getTags(),
'blames' => $blames,
));
})->assert('repo', $app['util.routing']->getRepositoryRegex())
->assert('commitishPath', $app['util.routing']->getCommitishPathRegex())
->bind('blame');

return $route;
}
}


+ 0
- 76
git/src/GitList/Controller/MainController.php View File

@@ -1,76 +0,0 @@
<?php

namespace GitList\Controller;

use Silex\Application;
use Silex\ControllerProviderInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;

class MainController implements ControllerProviderInterface
{
public function connect(Application $app)
{
$route = $app['controllers_factory'];

$route->get('/', function() use ($app) {
$repositories = $app['git']->getRepositories($app['git.repos']);

return $app['twig']->render('index.twig', array(
'repositories' => $repositories,
));
})->bind('homepage');


$route->get('/refresh', function(Request $request) use ($app ) {
# Go back to calling page
return $app->redirect($request->headers->get('Referer'));
})->bind('refresh');

$route->get('{repo}/stats/{branch}', function($repo, $branch) use ($app) {
$repository = $app['git']->getRepositoryFromName($app['git.repos'], $repo);

if ($branch === null) {
$branch = $repository->getHead();
}

$stats = $repository->getStatistics($branch);
$authors = $repository->getAuthorStatistics($branch);

return $app['twig']->render('stats.twig', array(
'repo' => $repo,
'branch' => $branch,
'branches' => $repository->getBranches(),
'tags' => $repository->getTags(),
'stats' => $stats,
'authors' => $authors,
));
})->assert('repo', $app['util.routing']->getRepositoryRegex())
->assert('branch', $app['util.routing']->getBranchRegex())
->value('branch', null)
->bind('stats');

$route->get('{repo}/{branch}/rss/', function($repo, $branch) use ($app) {
$repository = $app['git']->getRepositoryFromName($app['git.repos'], $repo);

if ($branch === null) {
$branch = $repository->getHead();
}

$commits = $repository->getPaginatedCommits($branch);

$html = $app['twig']->render('rss.twig', array(
'repo' => $repo,
'branch' => $branch,
'commits' => $commits,
));

return new Response($html, 200, array('Content-Type' => 'application/rss+xml'));
})->assert('repo', $app['util.routing']->getRepositoryRegex())
->assert('branch', $app['util.routing']->getBranchRegex())
->value('branch', null)
->bind('rss');

return $route;
}
}

+ 0
- 126
git/src/GitList/Controller/NetworkController.php View File

@@ -1,126 +0,0 @@
<?php

namespace GitList\Controller;

use GitList\Git\Repository;
use Gitter\Model\Commit\Commit;
use Silex\Application;
use Silex\ControllerProviderInterface;
use Symfony\Component\HttpFoundation\Request;

class NetworkController implements ControllerProviderInterface
{
public function connect(Application $app)
{
$route = $app['controllers_factory'];

$route->get('{repo}/network/{commitishPath}/{page}.json',
function ($repo, $commitishPath, $page) use ($app) {
/** @var $repository Repository */
$repository = $app['git']->getRepositoryFromName($app['git.repos'], $repo);

if ($commitishPath === null) {
$commitishPath = $repository->getHead();
}

$pager = $app['util.view']->getPager($page, $repository->getTotalCommits($commitishPath));
$commits = $repository->getPaginatedCommits($commitishPath, $pager['current']);

$jsonFormattedCommits = array();

foreach ($commits as $commit) {
$detailsUrl = $app['url_generator']->generate(
'commit',
array(
'repo' => $repo,
'commit' => $commit->getHash()
)
);

$jsonFormattedCommits[$commit->getHash()] = array(
'hash' => $commit->getHash(),
'parentsHash' => $commit->getParentsHash(),
'date' => $commit->getDate()->format('U'),
'message' => htmlentities($commit->getMessage()),
'details' => $detailsUrl,
'author' => array(
'name' => $commit->getAuthor()->getName(),
'email' => $commit->getAuthor()->getEmail(),
// due to the lack of a inbuilt javascript md5 mechanism, build the full avatar url on the php side
'image' => 'http://gravatar.com/avatar/' . md5(
strtolower($commit->getAuthor()->getEmail())
) . '?s=40'
)
);
}

$nextPageUrl = null;
if ($pager['last'] !== $pager['current']) {
$nextPageUrl = $app['url_generator']->generate(
'networkData',
array(
'repo' => $repo,
'commitishPath' => $commitishPath,
'page' => $pager['next']
)
);
}
// when no commits are given, return an empty response - issue #369
if( count($commits) === 0 ) {
return $app->json( array(
'repo' => $repo,
'commitishPath' => $commitishPath,
'nextPage' => null,
'start' => null,
'commits' => $jsonFormattedCommits
), 200
);
}

return $app->json( array(
'repo' => $repo,
'commitishPath' => $commitishPath,
'nextPage' => $nextPageUrl,
'start' => $commits[0]->getHash(),
'commits' => $jsonFormattedCommits
), 200
);
}
)->assert('repo', $app['util.routing']->getRepositoryRegex())
->assert('commitishPath', $app['util.routing']->getCommitishPathRegex())
->value('commitishPath', null)
->assert('page', '\d+')
->value('page', '0')
->bind('networkData');

$route->get(
'{repo}/network/{commitishPath}',
function ($repo, $commitishPath) use ($app) {
$repository = $app['git']->getRepositoryFromName($app['git.repos'], $repo);

if ($commitishPath === null) {
$commitishPath = $repository->getHead();
}

list($branch, $file) = $app['util.routing']->parseCommitishPathParam($commitishPath, $repo);
list($branch, $file) = $app['util.repository']->extractRef($repository, $branch, $file);

return $app['twig']->render(
'network.twig',
array(
'repo' => $repo,
'branch' => $branch,
'commitishPath' => $commitishPath,
)
);
}
)->assert('repo', $app['util.routing']->getRepositoryRegex())
->assert('commitishPath', $app['util.routing']->getCommitishPathRegex())
->value('commitishPath', null)
->bind('network');

return $route;
}
}

+ 0
- 124
git/src/GitList/Controller/TreeController.php View File

@@ -1,124 +0,0 @@
<?php

namespace GitList\Controller;

use Silex\Application;
use Silex\ControllerProviderInterface;
use Symfony\Component\HttpFoundation\StreamedResponse;
use Symfony\Component\HttpFoundation\Request;

class TreeController implements ControllerProviderInterface
{
public function connect(Application $app)
{
$route = $app['controllers_factory'];

$route->get('{repo}/tree/{commitishPath}/', $treeController = function ($repo, $commitishPath = '') use ($app) {
$repository = $app['git']->getRepositoryFromName($app['git.repos'], $repo);
if (!$commitishPath) {
$commitishPath = $repository->getHead();
}

list($branch, $tree) = $app['util.routing']->parseCommitishPathParam($commitishPath, $repo);

list($branch, $tree) = $app['util.repository']->extractRef($repository, $branch, $tree);
$files = $repository->getTree($tree ? "$branch:\"$tree\"/" : $branch);
$breadcrumbs = $app['util.view']->getBreadcrumbs($tree);

$parent = null;
if (($slash = strrpos($tree, '/')) !== false) {
$parent = substr($tree, 0, $slash);
} elseif (!empty($tree)) {
$parent = '';
}

return $app['twig']->render('tree.twig', array(
'files' => $files->output(),
'repo' => $repo,
'branch' => $branch,
'path' => $tree ? $tree . '/' : $tree,
'parent' => $parent,
'breadcrumbs' => $breadcrumbs,
'branches' => $repository->getBranches(),
'tags' => $repository->getTags(),
'readme' => $app['util.repository']->getReadme($repository, $branch),
));
})->assert('repo', $app['util.routing']->getRepositoryRegex())
->assert('commitishPath', $app['util.routing']->getCommitishPathRegex())
->bind('tree');

$route->post('{repo}/tree/{branch}/search', function (Request $request, $repo, $branch = '', $tree = '') use ($app) {
$repository = $app['git']->getRepositoryFromName($app['git.repos'], $repo);
if (!$branch) {
$branch = $repository->getHead();
}

$query = $request->get('query');
$breadcrumbs = array(array('dir' => 'Search results for: ' . $query, 'path' => ''));
$results = $repository->searchTree($query, $branch);

return $app['twig']->render('search.twig', array(
'results' => $results,
'repo' => $repo,
'branch' => $branch,
'path' => $tree,
'breadcrumbs' => $breadcrumbs,
'branches' => $repository->getBranches(),
'tags' => $repository->getTags(),
));
})->assert('repo', $app['util.routing']->getRepositoryRegex())
->assert('branch', $app['util.routing']->getBranchRegex())
->bind('search');


# Intentionally before next statement, because order appears
# to be important, and the other statement got precedence previously.
$route->get('{repo}/{format}ball/{branch}', function($repo, $format, $branch) use ($app) {
$repository = $app['git']->getRepositoryFromName($app['git.repos'], $repo);

$tree = $repository->getBranchTree($branch);

if (false === $tree) {
return $app->abort(404, 'Invalid commit or tree reference: ' . $branch);
}

$file = $app['cache.archives'] . DIRECTORY_SEPARATOR
. $repo . DIRECTORY_SEPARATOR
. substr($tree, 0, 2) . DIRECTORY_SEPARATOR
. substr($tree, 2)
. '.'
. $format;

if (!file_exists($file)) {
$repository->createArchive($tree, $file, $format);
}

return new StreamedResponse(function () use ($file) {
readfile($file);
}, 200, array(
'Content-type' => ('zip' === $format) ? 'application/zip' : 'application/x-tar',
'Content-Description' => 'File Transfer',
'Content-Disposition' => 'attachment; filename="'.$repo.'-'.substr($tree, 0, 6).'.'.$format.'"',
'Content-Transfer-Encoding' => 'binary',
));
})->assert('format', '(zip|tar)')
->assert('repo', $app['util.routing']->getRepositoryRegex())
->assert('branch', $app['util.routing']->getBranchRegex())
->bind('archive');


$route->get('{repo}/{branch}/', function($repo, $branch) use ($app, $treeController) {
return $treeController($repo, $branch);
})->assert('repo', $app['util.routing']->getRepositoryRegex())
->assert('branch', $app['util.routing']->getBranchRegex())
->bind('branch');

$route->get('{repo}/', function($repo) use ($app, $treeController) {
return $treeController($repo);
})->assert('repo', $app['util.routing']->getRepositoryRegex())
->bind('repository');

return $route;
}
}


+ 0
- 8
git/src/GitList/Exception/BlankDataException.php View File

@@ -1,8 +0,0 @@
<?php

namespace GitList\Exception;

class BlankDataException extends \RuntimeException
{
}

+ 0
- 8
git/src/GitList/Exception/EmptyRepositoryException.php View File

@@ -1,8 +0,0 @@
<?php

namespace GitList\Exception;

class EmptyRepositoryException extends \RuntimeException
{
}

+ 0
- 187
git/src/GitList/Git/Client.php View File

@@ -1,187 +0,0 @@
<?php

namespace GitList\Git;

use Gitter\Client as BaseClient;

class Client extends BaseClient
{
protected $defaultBranch;
protected $hidden;

public function __construct($options = null)
{
parent::__construct($options['path']);
$this->setDefaultBranch($options['default_branch']);
$this->setHidden($options['hidden']);
}

public function getRepositoryFromName($paths, $repo)
{
$repositories = $this->getRepositories($paths);
$path = $repositories[$repo]['path'];

return $this->getRepository($path);
}

/**
* Searches for valid repositories on the specified path
*
* @param array $paths Array of paths where repositories will be searched
* @return array Found repositories, containing their name, path and description
*/
public function getRepositories($paths)
{
$allRepositories = array();

foreach ($paths as $path) {
$repositories = $this->recurseDirectory($path);

if (empty($repositories)) {
throw new \RuntimeException('There are no GIT repositories in ' . $path);
}

$allRepositories = array_merge($allRepositories, $repositories);
}

$allRepositories = array_unique($allRepositories, SORT_REGULAR);
asort($allRepositories);

return $allRepositories;
}

private function recurseDirectory($path, $topLevel = true)
{
$dir = new \DirectoryIterator($path);

$repositories = array();

foreach ($dir as $file) {
if ($file->isDot()) {
continue;
}

if (strrpos($file->getFilename(), '.') === 0) {
continue;
}

if (!$file->isReadable()) {
continue;
}

if ($file->isDir()) {
$isBare = file_exists($file->getPathname() . '/HEAD');
$isRepository = file_exists($file->getPathname() . '/.git/HEAD');

if ($isRepository || $isBare) {
if (in_array($file->getPathname(), $this->getHidden())) {
continue;
}

if ($isBare) {
$description = $file->getPathname() . '/description';
} else {
$description = $file->getPathname() . '/.git/description';
}

if (file_exists($description)) {
$description = file_get_contents($description);
} else {
$description = null;
}

if (!$topLevel) {
$repoName = $file->getPathInfo()->getFilename() . '/' . $file->getFilename();
} else {
$repoName = $file->getFilename();
}

$repositories[$repoName] = array(
'name' => $repoName,
'path' => $file->getPathname(),
'description' => $description
);

continue;
} else {
$repositories = array_merge($repositories, $this->recurseDirectory($file->getPathname(), false));
}
}
}

return $repositories;
}

/**
* Set default branch as a string.
*
* @param string $branch Name of branch to use when repo's HEAD is detached.
*/
protected function setDefaultBranch($branch)
{
$this->defaultBranch = $branch;

return $this;
}

/**
* Return name of default branch as a string.
*/
public function getDefaultBranch()
{
return $this->defaultBranch;
}

/**
* Get hidden repository list
*
* @return array List of repositories to hide
*/
protected function getHidden()
{
return $this->hidden;
}

/**
* Set the hidden repository list
*
* @param array $hidden List of repositories to hide
*/
protected function setHidden($hidden)
{
$this->hidden = $hidden;

return $this;
}

/**
* Overloads the parent::createRepository method for the correct Repository class instance
*
* {@inheritdoc}
*/
public function createRepository($path, $bare = null)
{
if (file_exists($path . '/.git/HEAD') && !file_exists($path . '/HEAD')) {
throw new \RuntimeException('A GIT repository already exists at ' . $path);
}

$repository = new Repository($path, $this);

return $repository->create($bare);
}

/**
* Overloads the parent::getRepository method for the correct Repository class instance
*
* {@inheritdoc}
*/
public function getRepository($path)
{
if (!file_exists($path) || !file_exists($path . '/.git/HEAD') && !file_exists($path . '/HEAD')) {
throw new \RuntimeException('There is no GIT repository at ' . $path);
}

return new Repository($path, $this);
}
}


+ 0
- 395
git/src/GitList/Git/Repository.php View File

@@ -1,395 +0,0 @@
<?php

namespace GitList\Git;

use Gitter\Repository as BaseRepository;
use Gitter\Model\Commit\Commit;
use Gitter\Model\Commit\Diff;
use Gitter\PrettyFormat;
use Symfony\Component\Filesystem\Filesystem;

class Repository extends BaseRepository
{
/**
* Return true if the repo contains this commit.
*
* @param $commitHash Hash of commit whose existence we want to check
* @return boolean Whether or not the commit exists in this repo
*/
public function hasCommit($commitHash)
{
$logs = $this->getClient()->run($this, "show $commitHash");
$logs = explode("\n", $logs);

return strpos($logs[0], 'commit') === 0;
}

/**
* Get the current branch, returning a default value when HEAD is detached.
*/
public function getHead($default = null)
{
$client = $this->getClient();

return parent::getHead($client->getDefaultBranch());
}

/**
* Show the data from a specific commit
*
* @param string $commitHash Hash of the specific commit to read data
* @return array Commit data
*/
public function getCommit($commitHash)
{
$logs = $this->getClient()->run($this,
"show --pretty=format:\"<item><hash>%H</hash>"
. "<short_hash>%h</short_hash><tree>%T</tree><parents>%P</parents>"
. "<author>%an</author><author_email>%ae</author_email>"
. "<date>%at</date><commiter>%cn</commiter><commiter_email>%ce</commiter_email>"
. "<commiter_date>%ct</commiter_date>"
. "<message><![CDATA[%s]]></message>"
. "<body><![CDATA[%b]]></body>"
. "</item>\" $commitHash"
);

$xmlEnd = strpos($logs, '</item>') + 7;
$commitInfo = substr($logs, 0, $xmlEnd);
$commitData = substr($logs, $xmlEnd);
$logs = explode("\n", $commitData);

// Read commit metadata
$format = new PrettyFormat;
$data = $format->parse($commitInfo);
$commit = new Commit;
$commit->importData($data[0]);

if ($commit->getParentsHash()) {
$command = 'diff ' . $commitHash . '~1..' . $commitHash;
$logs = explode("\n", $this->getClient()->run($this, $command));
}

$commit->setDiffs($this->readDiffLogs($logs));

return $commit;
}

/**
* Blames the provided file and parses the output
*
* @param string $file File that will be blamed
* @return array Commits hashes containing the lines
*/
public function getBlame($file)
{
$blame = array();
$logs = $this->getClient()->run($this, "blame --root -sl $file");
$logs = explode("\n", $logs);

$i = 0;
$previousCommit = '';
foreach ($logs as $log) {
if ($log == '') {
continue;
}

preg_match_all("/([a-zA-Z0-9]{40})\s+.*?([0-9]+)\)(.+)/", $log, $match);

$currentCommit = $match[1][0];
if ($currentCommit != $previousCommit) {
++$i;
$blame[$i] = array(
'line' => '',
'commit' => $currentCommit,
'commitShort' => substr($currentCommit, 0, 8)
);
}

$blame[$i]['line'] .= PHP_EOL . $match[3][0];
$previousCommit = $currentCommit;
}

return $blame;
}

/**
* Read diff logs and generate a collection of diffs
*
* @param array $logs Array of log rows
* @return array Array of diffs
*/
public function readDiffLogs(array $logs)
{
$diffs = array();
$lineNumOld = 0;
$lineNumNew = 0;
foreach ($logs as $log) {
# Skip empty lines
if ($log == "") {
continue;
}

if ('diff' === substr($log, 0, 4)) {
if (isset($diff)) {
$diffs[] = $diff;
}

$diff = new Diff;
if (preg_match('/^diff --[\S]+ a\/?(.+) b\/?/', $log, $name)) {
$diff->setFile($name[1]);
}
continue;
}

if ('index' === substr($log, 0, 5)) {
$diff->setIndex($log);
continue;
}

if ('---' === substr($log, 0, 3)) {
$diff->setOld($log);
continue;
}

if ('+++' === substr($log, 0, 3)) {
$diff->setNew($log);
continue;
}

// Handle binary files properly.
if ('Binary' === substr($log, 0, 6)) {
$m = array();
if (preg_match('/Binary files (.+) and (.+) differ/', $log, $m)) {
$diff->setOld($m[1]);
$diff->setNew(" {$m[2]}");
}
}

if (!empty($log)) {
switch ($log[0]) {
case "@":
// Set the line numbers
preg_match('/@@ -([0-9]+)/', $log, $matches);
$lineNumOld = $matches[1] - 1;
$lineNumNew = $matches[1] - 1;
break;
case "-":
$lineNumOld++;
break;
case "+":
$lineNumNew++;
break;
default:
$lineNumOld++;
$lineNumNew++;
}
} else {
$lineNumOld++;
$lineNumNew++;
}

if (isset($diff)) {
$diff->addLine($log, $lineNumOld, $lineNumNew);
}
}

if (isset($diff)) {
$diffs[] = $diff;
}

return $diffs;
}

/**
* Show the repository commit log with pagination
*
* @access public
* @return array Commit log
*/
public function getPaginatedCommits($file = null, $page = 0)
{
$page = 15 * $page;
$pager = "--skip=$page --max-count=15";
$command =
"log $pager --pretty=format:\"<item><hash>%H</hash>"
. "<short_hash>%h</short_hash><tree>%T</tree><parent>%P</parent>"
. "<author>%an</author><author_email>%ae</author_email>"
. "<date>%at</date><commiter>%cn</commiter>"
. "<commiter_email>%ce</commiter_email>"
. "<commiter_date>%ct</commiter_date>"
. "<message><![CDATA[%s]]></message></item>\"";

if ($file) {
$command .= " $file";
}

try {
$logs = $this->getPrettyFormat($command);
} catch (\RuntimeException $e) {
return array();
}

foreach ($logs as $log) {
$commit = new Commit;
$commit->importData($log);
$commits[] = $commit;
}

return $commits;
}

public function searchCommitLog($query)
{
$query = escapeshellarg($query);
$command =
"log --grep={$query} --pretty=format:\"<item><hash>%H</hash>"
. "<short_hash>%h</short_hash><tree>%T</tree><parent>%P</parent>"
. "<author>%an</author><author_email>%ae</author_email>"
. "<date>%at</date><commiter>%cn</commiter>"
. "<commiter_email>%ce</commiter_email>"
. "<commiter_date>%ct</commiter_date>"
. "<message><![CDATA[%s]]></message></item>\"";

try {
$logs = $this->getPrettyFormat($command);
} catch (\RuntimeException $e) {
return array();
}

foreach ($logs as $log) {
$commit = new Commit;
$commit->importData($log);
$commits[] = $commit;
}

return $commits;
}

public function searchTree($query, $branch)
{
$query = escapeshellarg($query);

try {
$results = $this->getClient()->run($this, "grep -I --line-number {$query} $branch");
} catch (\RuntimeException $e) {
return false;
}

$results = explode("\n", $results);

foreach ($results as $result) {
if ($result == '') {
continue;
}

preg_match_all('/([\w-._]+):([^:]+):([0-9]+):(.+)/', $result, $matches, PREG_SET_ORDER);

$data['branch'] = $matches[0][1];
$data['file'] = $matches[0][2];
$data['line'] = $matches[0][3];
$data['match'] = $matches[0][4];

$searchResults[] = $data;
}

return $searchResults;
}

public function getAuthorStatistics($branch)
{
$logs = $this->getClient()->run($this, 'log --pretty=format:"%an||%ae" ' . $branch);

if (empty($logs)) {
throw new \RuntimeException('No statistics available');
}

$logs = explode("\n", $logs);
$logs = array_count_values($logs);
arsort($logs);

foreach ($logs as $user => $count) {
$user = explode('||', $user);
$data[] = array('name' => $user[0], 'email' => $user[1], 'commits' => $count);
}

return $data;
}

public function getStatistics($branch)
{
// Calculate amount of files, extensions and file size
$logs = $this->getClient()->run($this, 'ls-tree -r -l ' . $branch);
$lines = explode("\n", $logs);
$files = array();
$data['extensions'] = array();
$data['size'] = 0;
$data['files'] = 0;

foreach ($lines as $key => $line) {
if (empty($line)) {
unset($lines[$key]);
continue;
}

$files[] = preg_split("/[\s]+/", $line);
}

foreach ($files as $file) {
if ($file[1] == 'blob') {
$data['files']++;
}

if (is_numeric($file[3])) {
$data['size'] += $file[3];
}

if (($pos = strrpos($file[4], '.')) !== false) {
$extension = substr($file[4], $pos);

if (($pos = strrpos($extension, '/')) === false) {
$data['extensions'][] = $extension;
}
}
}

$data['extensions'] = array_count_values($data['extensions']);
arsort($data['extensions']);

return $data;
}

/**
* Create a TAR or ZIP archive of a git tree
*
* @param string $tree Tree-ish reference
* @param string $output Output File name
* @param string $format Archive format
*/
public function createArchive($tree, $output, $format = 'zip')
{
$fs = new Filesystem;
$fs->mkdir(dirname($output));
$this->getClient()->run($this, "archive --format=$format --output=$output $tree");
}

/**
* Return true if $path exists in $branch; return false otherwise.
*
* @param string $commitish Commitish reference; branch, tag, SHA1, etc.
* @param string $path Path whose existence we want to verify.
*
* GRIPE Arguably belongs in Gitter, as it's generally useful functionality.
* Also, this really may not be the best way to do this.
*/
public function pathExists($commitish, $path)
{
$output = $this->getClient()->run($this, "ls-tree $commitish '$path'");

if (strlen($output) > 0) {
return true;
}

return false;
}
}


+ 0
- 33
git/src/GitList/Provider/GitServiceProvider.php View File

@@ -1,33 +0,0 @@
<?php

namespace GitList\Provider;

use GitList\Git\Client;
use Silex\Application;
use Silex\ServiceProviderInterface;

class GitServiceProvider implements ServiceProviderInterface
{

/**
* Register the Git\Client on the Application ServiceProvider
*
* @param Application $app Silex Application
* @return Git\Client Instance of the Git\Client
*/
public function register(Application $app)
{
$app['git'] = function () use ($app) {
$options['path'] = $app['git.client'];
$options['hidden'] = $app['git.hidden'];
$options['ini.file'] = $app['ini.file'];
$options['default_branch'] = $app['git.default_branch'];

return new Client($options);
};
}

public function boot(Application $app)
{
}
}

+ 0
- 26
git/src/GitList/Provider/RepositoryUtilServiceProvider.php View File

@@ -1,26 +0,0 @@
<?php

namespace GitList\Provider;

use GitList\Util\Repository;
use Silex\Application;
use Silex\ServiceProviderInterface;

class RepositoryUtilServiceProvider implements ServiceProviderInterface
{
/**
* Register the Util\Repository class on the Application ServiceProvider
*
* @param Application $app Silex Application
*/
public function register(Application $app)
{
$app['util.repository'] = $app->share(function () use ($app) {
return new Repository($app);
});
}

public function boot(Application $app)
{
}
}

+ 0
- 26
git/src/GitList/Provider/RoutingUtilServiceProvider.php View File

@@ -1,26 +0,0 @@
<?php

namespace GitList\Provider;

use GitList\Util\Routing;
use Silex\Application;
use Silex\ServiceProviderInterface;

class RoutingUtilServiceProvider implements ServiceProviderInterface
{
/**
* Register the Util\Repository class on the Application ServiceProvider
*
* @param Application $app Silex Application
*/
public function register(Application $app)
{
$app['util.routing'] = $app->share(function () use ($app) {
return new Routing($app);
});
}

public function boot(Application $app)
{
}
}

+ 0
- 26
git/src/GitList/Provider/ViewUtilServiceProvider.php View File

@@ -1,26 +0,0 @@
<?php

namespace GitList\Provider;

use GitList\Util\View;
use Silex\Application;
use Silex\ServiceProviderInterface;

class ViewUtilServiceProvider implements ServiceProviderInterface
{
/**
* Register the Util\Interface class on the Application ServiceProvider
*
* @param Application $app Silex Application
*/
public function register(Application $app)
{
$app['util.view'] = $app->share(function () {
return new View;
});
}

public function boot(Application $app)
{
}
}

+ 0
- 223
git/src/GitList/Util/Repository.php View File

@@ -1,223 +0,0 @@
<?php

namespace GitList\Util;

use Silex\Application;

class Repository
{
protected $app;

protected $defaultFileTypes = array(
'php' => 'php',
'c' => 'clike',
'h' => 'clike',
'cpp' => 'clike',
'm' => 'clike',
'mm' => 'clike',
'ino' => 'clike',
'cs' => 'text/x-csharp',
'csproj' => 'xml',
'java' => 'text/x-java',
'clj' => 'clojure',
'coffee' => 'coffeescript',
'css' => 'css',
'diff' => 'diff',
'ecl' => 'ecl',
'el' => 'erlang',
'go' => 'go',
'groovy' => 'groovy',
'hs' => 'haskell',
'lhs' => 'haskell',
'jsp' => 'htmlembedded',
'asp' => 'htmlembedded',
'aspx' => 'htmlembedded',
'html' => 'htmlmixed',
'tpl' => 'htmlmixed',
'js' => 'javascript',
'json' => 'javascript',
'less' => 'less',
'lua' => 'lua',
'md' => 'markdown',
'markdown' => 'markdown',
'sql' => 'mysql',
'pl' => 'perl',
'pm' => 'perl',
'pas' => 'pascal',
'ini' => 'properties',
'cfg' => 'properties',
'nt' => 'ntriples',
'py' => 'python',
'rb' => 'ruby',
'rst' => 'rst',
'r' => 'r',
'sh' => 'shell',
'ss' => 'scheme',
'scala' => 'text/x-scala',
'scm' => 'scheme',
'sln' => 'xml',
'sls' => 'scheme',
'sps' => 'scheme',
'rs' => 'rust',
'st' => 'smalltalk',
'tex' => 'stex',
'vbs' => 'vbscript',
'v' => 'verilog',
'xml' => 'xml',
'xsd' => 'xml',
'xsl' => 'xml',
'xul' => 'xml',
'xlf' => 'xml',
'xliff' => 'xml',
'xaml' => 'xml',
'wxs' => 'xml',
'wxl' => 'xml',
'wxi' => 'xml',
'wsdl' => 'xml',
'svg' => 'xml',
'rss' => 'xml',
'rdf' => 'xml',
'plist' => 'xml',
'mxml' => 'xml',
'kml' => 'xml',
'glade' => 'xml',
'xq' => 'xquery',
'xqm' => 'xquery',
'xquery' => 'xquery',
'xqy' => 'xquery',
'yml' => 'yaml',
'yaml' => 'yaml',
'png' => 'image',
'jpg' => 'image',
'gif' => 'image',
'jpeg' => 'image',
'bmp' => 'image'
);

protected static $binaryTypes = array(
'exe', 'com', 'so', 'la', 'o', 'dll', 'pyc',
'jpg', 'jpeg', 'bmp', 'gif', 'png', 'xmp', 'pcx', 'svgz', 'ttf', 'tiff', 'oet',
'gz', 'tar', 'rar', 'zip', '7z', 'jar', 'class',
'odt', 'ods', 'pdf', 'doc', 'docx', 'dot', 'xls', 'xlsx',
);

public function __construct(Application $app)
{
$this->app = $app;
}

/**
* Returns the file type based on filename by treating the extension
*
* The file type is used by CodeMirror, a Javascript-based IDE implemented in
* GitList, to properly highlight the blob syntax (if it's a source-code)
*
* @param string $file File name
* @return mixed File type
*/
public function getFileType($file)
{
if (($pos = strrpos($file, '.')) !== false) {
$fileType = substr($file, $pos + 1);
} else {
return 'text';
}

if (isset($this->defaultFileTypes[$fileType])) {
return $this->defaultFileTypes[$fileType];
}

if (!empty($this->app['filetypes'])) {
if (isset($this->app['filetypes'][$fileType])) {
return $this->app['filetypes'][$fileType];
}
}

return 'text';
}

/**
* Returns whether the file is binary.
*
* @param string $file
*
* @return boolean
*/
public function isBinary($file)
{
if (($pos = strrpos($file, '.')) !== false) {
$fileType = substr($file, $pos + 1);
} else {
return false;
}

if (in_array($fileType, self::$binaryTypes)) {
return true;
}

if (!empty($this->app['binary_filetypes']) && array_key_exists($fileType, $this->app['binary_filetypes'])) {
return $this->app['binary_filetypes'][$fileType];
}

return false;
}

public function getReadme($repository, $branch = null)
{
$files = $repository->getTree($branch)->output();
if ($branch === null) {
$branch = $repository->getHead();
}