mirror of
https://github.com/klaussilveira/gitlist.git
synced 2025-11-17 11:10:57 +01:00
Merge pull request #286 from klaussilveira/multidir
Multiple directory support
This commit is contained in:
19
boot.php
19
boot.php
@@ -4,15 +4,32 @@ if (!isset($config)) {
|
||||
die("No configuration object provided.");
|
||||
}
|
||||
|
||||
$config->set('git', 'repositories', rtrim($config->get('git', 'repositories'), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR);
|
||||
$repositories = $config->get('git', 'repositories');
|
||||
|
||||
if (!is_array($repositories)) {
|
||||
# Convert the single item to an array - this is the internal handling
|
||||
$repositories = array($repositories);
|
||||
}
|
||||
|
||||
$tmp_arr = array();
|
||||
foreach ($repositories as $repo) {
|
||||
$tmp = rtrim($repo, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
|
||||
$tmp_arr []= $tmp;
|
||||
}
|
||||
$repositories = $tmp_arr;
|
||||
|
||||
|
||||
|
||||
// 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;
|
||||
|
||||
|
||||
@@ -3,6 +3,19 @@ client = '/usr/bin/git' ; Your git executable path
|
||||
repositories = '/var/www/projects/' ; Path to your repositories
|
||||
default_branch = 'master' ; Default branch when HEAD is detached
|
||||
|
||||
|
||||
;Windows Users
|
||||
;client = '"C:\Program Files (x86)\Git\bin\git.exe"' ; Your git executable path
|
||||
;repositories = 'C:\Path\to\Repos\' ; Path to your repositories
|
||||
|
||||
|
||||
; If you want to specify multiple paths, use the array syntax instead:
|
||||
;
|
||||
;repositories[] = '/var/www/projects/'
|
||||
;repositories[] = '/var/www/subdir/more_projects/'
|
||||
;repositories[] = '/home/user/even_more_projects/'
|
||||
|
||||
|
||||
; You can hide repositories from GitList, just copy this for each repository you want to hide
|
||||
; hidden[] = '/var/www/projects/BetaTest'
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ if (!ini_get('date.timezone')) {
|
||||
date_default_timezone_set('UTC');
|
||||
}
|
||||
|
||||
if(php_sapi_name() == 'cli-server' && file_exists(substr($_SERVER['REQUEST_URI'], 1))) {
|
||||
if (php_sapi_name() == 'cli-server' && file_exists(substr($_SERVER['REQUEST_URI'], 1))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -20,4 +20,6 @@ require 'vendor/autoload.php';
|
||||
$config = GitList\Config::fromFile('config.ini');
|
||||
|
||||
$app = require 'boot.php';
|
||||
|
||||
$app->run();
|
||||
|
||||
|
||||
@@ -30,19 +30,38 @@ class Application extends SilexApplication
|
||||
|
||||
$this['debug'] = $config->get('app', 'debug');
|
||||
$this['filetypes'] = $config->getSection('filetypes');
|
||||
$this['cache.archives'] = $root . DIRECTORY_SEPARATOR . 'cache' . DIRECTORY_SEPARATOR . 'archives';
|
||||
$this['cache.archives'] = $root . DIRECTORY_SEPARATOR
|
||||
. 'cache' . DIRECTORY_SEPARATOR . 'archives';
|
||||
|
||||
// Register services
|
||||
$this->register(new TwigServiceProvider(), array(
|
||||
'twig.path' => $root . DIRECTORY_SEPARATOR . 'views',
|
||||
'twig.options' => array('cache' => $root . DIRECTORY_SEPARATOR . 'cache' . DIRECTORY_SEPARATOR . 'views'),
|
||||
'twig.options' => array('cache' => $root . DIRECTORY_SEPARATOR
|
||||
. 'cache' . DIRECTORY_SEPARATOR . 'views'),
|
||||
));
|
||||
|
||||
$repositories = $config->get('git', 'repositories');
|
||||
|
||||
$cached_repos = $config->get('app', 'cached_repos');
|
||||
if (false === $cached_repos || empty($cached_repos)) {
|
||||
$cached_repos = $root . DIRECTORY_SEPARATOR . 'cache'
|
||||
. DIRECTORY_SEPARATOR . 'repos.json';
|
||||
}
|
||||
|
||||
$this->register(new GitServiceProvider(), array(
|
||||
'git.client' => $config->get('git', 'client'),
|
||||
'git.repos' => $config->get('git', 'repositories'),
|
||||
'git.hidden' => $config->get('git', 'hidden') ? $config->get('git', 'hidden') : array(),
|
||||
'git.client' => $config->get('git', 'client'),
|
||||
'git.repos' => $repositories,
|
||||
'cache.repos' => $cached_repos,
|
||||
'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',
|
||||
));
|
||||
|
||||
$cached_repos = $root . DIRECTORY_SEPARATOR .
|
||||
'cache' . DIRECTORY_SEPARATOR . 'repos.json';
|
||||
|
||||
|
||||
$this->register(new ViewUtilServiceProvider());
|
||||
$this->register(new RepositoryUtilServiceProvider());
|
||||
$this->register(new UrlGeneratorServiceProvider());
|
||||
@@ -55,6 +74,7 @@ class Application extends SilexApplication
|
||||
return $twig;
|
||||
}));
|
||||
|
||||
|
||||
// Handle errors
|
||||
$this->error(function (\Exception $e, $code) use ($app) {
|
||||
if ($app['debug']) {
|
||||
@@ -67,3 +87,4 @@ class Application extends SilexApplication
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -51,8 +51,24 @@ class Config
|
||||
|
||||
protected function validateOptions()
|
||||
{
|
||||
if (!$this->get('git', 'repositories') || !is_dir($this->get('git', 'repositories'))) {
|
||||
$at_least_one_ok = false;
|
||||
$at_least_one_wrong = false;
|
||||
|
||||
foreach ($this->get('git', 'repositories') as $dir) {
|
||||
if (!$dir || !is_dir($dir)) {
|
||||
$at_least_one_wrong = true;
|
||||
} else {
|
||||
$at_least_one_ok = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$at_least_one_ok) {
|
||||
die("Please, edit the config file and provide your repositories directory");
|
||||
}
|
||||
|
||||
if ($at_least_one_wrong) {
|
||||
die("One or more of the supplied repository paths appears to be wrong. Please, check the config file");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ class BlobController implements ControllerProviderInterface
|
||||
$route = $app['controllers_factory'];
|
||||
|
||||
$route->get('{repo}/blob/{commitishPath}', function ($repo, $commitishPath) use ($app) {
|
||||
$repository = $app['git']->getRepository($app['git.repos'] . $repo);
|
||||
$repository = $app['git']->getRepository($app['git.repos'], $repo);
|
||||
|
||||
list($branch, $file) = $app['util.routing']
|
||||
->parseCommitishPathParam($commitishPath, $repo);
|
||||
@@ -47,7 +47,7 @@ class BlobController implements ControllerProviderInterface
|
||||
->bind('blob');
|
||||
|
||||
$route->get('{repo}/raw/{commitishPath}', function ($repo, $commitishPath) use ($app) {
|
||||
$repository = $app['git']->getRepository($app['git.repos'] . $repo);
|
||||
$repository = $app['git']->getRepository($app['git.repos'], $repo);
|
||||
|
||||
list($branch, $file) = $app['util.routing']
|
||||
->parseCommitishPathParam($commitishPath, $repo);
|
||||
@@ -73,3 +73,4 @@ class BlobController implements ControllerProviderInterface
|
||||
return $route;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ class CommitController implements ControllerProviderInterface
|
||||
$route = $app['controllers_factory'];
|
||||
|
||||
$route->get('{repo}/commits/{commitishPath}', function ($repo, $commitishPath) use ($app) {
|
||||
$repository = $app['git']->getRepository($app['git.repos'] . $repo);
|
||||
$repository = $app['git']->getRepository($app['git.repos'], $repo);
|
||||
|
||||
if ($commitishPath === null) {
|
||||
$commitishPath = $repository->getHead();
|
||||
@@ -53,9 +53,10 @@ class CommitController implements ControllerProviderInterface
|
||||
->bind('commits');
|
||||
|
||||
$route->post('{repo}/commits/{branch}/search', function (Request $request, $repo, $branch = '') use ($app) {
|
||||
$repository = $app['git']->getRepository($app['git.repos'] . $repo);
|
||||
$repository = $app['git']->getRepository($app['git.repos'], $repo);
|
||||
$query = $request->get('query');
|
||||
$commits = $repository->searchCommitLog($query);
|
||||
|
||||
$commits = $repository->searchCommitLog($request->get('query'));
|
||||
$categorized = array();
|
||||
|
||||
foreach ($commits as $commit) {
|
||||
@@ -78,7 +79,7 @@ class CommitController implements ControllerProviderInterface
|
||||
->bind('searchcommits');
|
||||
|
||||
$route->get('{repo}/commit/{commit}', function ($repo, $commit) use ($app) {
|
||||
$repository = $app['git']->getRepository($app['git.repos'] . $repo);
|
||||
$repository = $app['git']->getRepository($app['git.repos'], $repo);
|
||||
$commit = $repository->getCommit($commit);
|
||||
$branch = $repository->getHead();
|
||||
|
||||
@@ -92,7 +93,7 @@ class CommitController implements ControllerProviderInterface
|
||||
->bind('commit');
|
||||
|
||||
$route->get('{repo}/blame/{commitishPath}', function ($repo, $commitishPath) use ($app) {
|
||||
$repository = $app['git']->getRepository($app['git.repos'] . $repo);
|
||||
$repository = $app['git']->getRepository($app['git.repos'], $repo);
|
||||
|
||||
list($branch, $file) = $app['util.routing']
|
||||
->parseCommitishPathParam($commitishPath, $repo);
|
||||
@@ -116,3 +117,4 @@ class CommitController implements ControllerProviderInterface
|
||||
return $route;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace GitList\Controller;
|
||||
use Silex\Application;
|
||||
use Silex\ControllerProviderInterface;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
class MainController implements ControllerProviderInterface
|
||||
{
|
||||
@@ -12,28 +13,30 @@ class MainController implements ControllerProviderInterface
|
||||
{
|
||||
$route = $app['controllers_factory'];
|
||||
|
||||
$route->get('/', function () use ($app) {
|
||||
$repositories = array_map(
|
||||
function ($repo) use ($app) {
|
||||
$repo['relativePath'] = $app['util.routing']->getRelativePath($repo['path']);
|
||||
$repository = $app['git']->getRepository($repo['path']);
|
||||
$repo['branch'] = $repository->getHead();
|
||||
|
||||
return $repo;
|
||||
},
|
||||
$app['git']->getRepositories($app['git.repos'])
|
||||
);
|
||||
$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('{repo}/stats/{branch}', function ($repo, $branch) use ($app) {
|
||||
$repository = $app['git']->getRepository($app['git.repos'] . $repo);
|
||||
|
||||
$route->get('/refresh', function(Request $request) use ($app ) {
|
||||
$app['git']->deleteCached();
|
||||
|
||||
# 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']->getRepository($app['git.repos'], $repo);
|
||||
|
||||
if ($branch === null) {
|
||||
$branch = $repository->getHead();
|
||||
}
|
||||
|
||||
$stats = $repository->getStatistics($branch);
|
||||
$authors = $repository->getAuthorStatistics();
|
||||
|
||||
@@ -50,8 +53,8 @@ class MainController implements ControllerProviderInterface
|
||||
->value('branch', null)
|
||||
->bind('stats');
|
||||
|
||||
$route->get('{repo}/{branch}/rss/', function ($repo, $branch) use ($app) {
|
||||
$repository = $app['git']->getRepository($app['git.repos'] . $repo);
|
||||
$route->get('{repo}/{branch}/rss/', function($repo, $branch) use ($app) {
|
||||
$repository = $app['git']->getRepository($app['git.repos'], $repo);
|
||||
|
||||
if ($branch === null) {
|
||||
$branch = $repository->getHead();
|
||||
@@ -74,3 +77,4 @@ class MainController implements ControllerProviderInterface
|
||||
return $route;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ class TreeController implements ControllerProviderInterface
|
||||
$route = $app['controllers_factory'];
|
||||
|
||||
$route->get('{repo}/tree/{commitishPath}/', $treeController = function ($repo, $commitishPath = '') use ($app) {
|
||||
$repository = $app['git']->getRepository($app['git.repos'] . $repo);
|
||||
$repository = $app['git']->getRepository($app['git.repos'], $repo);
|
||||
if (!$commitishPath) {
|
||||
$commitishPath = $repository->getHead();
|
||||
}
|
||||
@@ -41,15 +41,14 @@ class TreeController implements ControllerProviderInterface
|
||||
'breadcrumbs' => $breadcrumbs,
|
||||
'branches' => $repository->getBranches(),
|
||||
'tags' => $repository->getTags(),
|
||||
'readme' => $app['util.repository']->getReadme($repo, $branch),
|
||||
'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']->getRepository($app['git.repos'] . $repo);
|
||||
|
||||
$repository = $app['git']->getRepository($app['git.repos'], $repo);
|
||||
if (!$branch) {
|
||||
$branch = $repository->getHead();
|
||||
}
|
||||
@@ -71,19 +70,12 @@ class TreeController implements ControllerProviderInterface
|
||||
->assert('branch', $app['util.routing']->getBranchRegex())
|
||||
->bind('search');
|
||||
|
||||
$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');
|
||||
# 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']->getRepository($app['git.repos'], $repo);
|
||||
|
||||
$route->get('{repo}/{format}ball/{branch}', function ($repo, $format, $branch) use ($app) {
|
||||
$repository = $app['git']->getRepository($app['git.repos'] . $repo);
|
||||
$tree = $repository->getBranchTree($branch);
|
||||
|
||||
if (false === $tree) {
|
||||
@@ -114,6 +106,19 @@ class TreeController implements ControllerProviderInterface
|
||||
->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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -57,13 +57,17 @@ class Client extends BaseClient
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a repository at the specified path
|
||||
* Opens a specified repository
|
||||
*
|
||||
* @param string $path Path where the repository is located
|
||||
* @param array $repos Array of items describing configured repositories
|
||||
* @param string $repo Name of repository we are currently handling
|
||||
* @return Repository Instance of Repository
|
||||
*/
|
||||
public function getRepository($path)
|
||||
public function getRepository($repos, $repo)
|
||||
{
|
||||
$repotmp = $this->getRepositoryCached($repos, $repo);
|
||||
$path = $repotmp->getPath();
|
||||
|
||||
if (!file_exists($path) || !file_exists($path . '/.git/HEAD') && !file_exists($path . '/HEAD')) {
|
||||
throw new \RuntimeException('There is no GIT repository at ' . $path);
|
||||
}
|
||||
@@ -75,3 +79,4 @@ class Client extends BaseClient
|
||||
return new Repository($path, $this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -42,7 +42,16 @@ class Repository extends BaseRepository
|
||||
*/
|
||||
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");
|
||||
$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);
|
||||
@@ -198,7 +207,14 @@ class Repository extends BaseRepository
|
||||
{
|
||||
$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>\"";
|
||||
$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";
|
||||
@@ -222,7 +238,14 @@ class Repository extends BaseRepository
|
||||
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>\"";
|
||||
$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);
|
||||
@@ -366,3 +389,4 @@ class Repository extends BaseRepository
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ use Silex\ServiceProviderInterface;
|
||||
|
||||
class GitServiceProvider implements ServiceProviderInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* Register the Git\Client on the Application ServiceProvider
|
||||
*
|
||||
@@ -19,6 +20,8 @@ class GitServiceProvider implements ServiceProviderInterface
|
||||
$app['git'] = function () use ($app) {
|
||||
$options['path'] = $app['git.client'];
|
||||
$options['hidden'] = $app['git.hidden'];
|
||||
$options['ini.file'] = $app['ini.file'];
|
||||
$options['cache.repos'] = $app['cache.repos'];
|
||||
$options['default_branch'] = $app['git.default_branch'];
|
||||
|
||||
return new Client($options);
|
||||
@@ -29,3 +32,4 @@ class GitServiceProvider implements ServiceProviderInterface
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -161,13 +161,12 @@ class Repository
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getReadme($repo, $branch = null)
|
||||
public function getReadme($repository, $branch = null)
|
||||
{
|
||||
$repository = $this->app['git']->getRepository($this->app['git.repos'] . $repo);
|
||||
if ($branch === null) {
|
||||
$branch = $repository->getHead();
|
||||
}
|
||||
$files = $repository->getTree($branch)->output();
|
||||
if ($branch === null) {
|
||||
$branch = $repository->getHead();
|
||||
}
|
||||
|
||||
foreach ($files as $file) {
|
||||
if (preg_match('/^readme*/i', $file['name'])) {
|
||||
@@ -220,3 +219,4 @@ class Repository
|
||||
return array($branch, $tree);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ class Routing
|
||||
public function parseCommitishPathParam($commitishPath, $repo)
|
||||
{
|
||||
$app = $this->app;
|
||||
$repository = $app['git']->getRepository($app['git.repos'] . $repo);
|
||||
$repository = $app['git']->getRepository($app['git.repos'], $repo);
|
||||
|
||||
$commitish = null;
|
||||
$path = null;
|
||||
@@ -108,9 +108,15 @@ class Routing
|
||||
|
||||
if ($regex === null) {
|
||||
$app = $this->app;
|
||||
$self = $this;
|
||||
$quotedPaths = array_map(
|
||||
function ($repo) use ($app) {
|
||||
return preg_quote($app['util.routing']->getRelativePath($repo['path']), '#');
|
||||
function ($repo) use ($app, $self) {
|
||||
$repoName = $repo['name'] ;
|
||||
//Windows
|
||||
if ($self->isWindows()){
|
||||
$repoName = str_replace('\\', '\\\\',$repoName);
|
||||
}
|
||||
return $repoName;
|
||||
},
|
||||
$this->app['git']->getRepositories($this->app['git.repos'])
|
||||
);
|
||||
@@ -128,6 +134,17 @@ class Routing
|
||||
return $regex;
|
||||
}
|
||||
|
||||
|
||||
public function isWindows()
|
||||
{
|
||||
switch(PHP_OS){
|
||||
case 'WIN32':
|
||||
case 'WINNT':
|
||||
case 'Windows': return true;
|
||||
default : return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Strips the base path from a full repository path
|
||||
*
|
||||
@@ -147,3 +164,4 @@ class Routing
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ class InterfaceTest extends WebTestCase
|
||||
{
|
||||
protected static $tmpdir;
|
||||
protected static $gitPath;
|
||||
protected static $cached_repos;
|
||||
|
||||
public static function setUpBeforeClass()
|
||||
{
|
||||
@@ -16,10 +17,10 @@ class InterfaceTest extends WebTestCase
|
||||
} elseif (getenv('TMPDIR')) {
|
||||
self::$tmpdir = getenv('TMPDIR');
|
||||
} else {
|
||||
self::$tmpdir = '/tmp';
|
||||
self::$tmpdir = DIRECTORY_SEPARATOR . 'tmp';
|
||||
}
|
||||
|
||||
self::$tmpdir .= '/gitlist_' . md5(time() . mt_rand()) . '/';
|
||||
self::$tmpdir .= DIRECTORY_SEPARATOR . 'gitlist_' . md5(time() . mt_rand()) . DIRECTORY_SEPARATOR;
|
||||
|
||||
$fs = new Filesystem();
|
||||
$fs->mkdir(self::$tmpdir);
|
||||
@@ -30,13 +31,21 @@ class InterfaceTest extends WebTestCase
|
||||
|
||||
$options['path'] = getenv('GIT_CLIENT') ?: '/usr/bin/git';
|
||||
$options['hidden'] = array(self::$tmpdir . '/hiddenrepo');
|
||||
$options['ini.file'] = "config.ini";
|
||||
|
||||
$cached_dir = self::$tmpdir . DIRECTORY_SEPARATOR . 'cache';
|
||||
$fs->mkdir($cached_dir);
|
||||
self::$cached_repos = $cached_dir . DIRECTORY_SEPARATOR . 'repos.json';
|
||||
|
||||
$options['cache.repos'] = self::$cached_repos;
|
||||
|
||||
$git = new Client($options);
|
||||
|
||||
self::$gitPath = $options['path'];
|
||||
|
||||
// GitTest repository fixture
|
||||
$git->createRepository(self::$tmpdir . 'GitTest');
|
||||
$repository = $git->getRepository(self::$tmpdir . 'GitTest');
|
||||
$repository = $git->getRepositoryCached(self::$tmpdir, 'GitTest');
|
||||
file_put_contents(self::$tmpdir . 'GitTest/README.md', "## GitTest\nGitTest is a *test* repository!");
|
||||
file_put_contents(self::$tmpdir . 'GitTest/test.php', "<?php\necho 'Hello World'; // This is a test");
|
||||
$repository->setConfig('user.name', 'Luke Skywalker');
|
||||
@@ -49,13 +58,16 @@ class InterfaceTest extends WebTestCase
|
||||
|
||||
// foobar repository fixture
|
||||
$git->createRepository(self::$tmpdir . 'foobar');
|
||||
$repository = $git->getRepository(self::$tmpdir . '/foobar');
|
||||
$repository = $git->getRepositoryCached(self::$tmpdir, 'foobar');
|
||||
|
||||
file_put_contents(self::$tmpdir . 'foobar/bar.json', "{\n\"name\": \"foobar\"\n}");
|
||||
file_put_contents(self::$tmpdir . 'foobar/.git/description', 'This is a test repo!');
|
||||
$fs->mkdir(self::$tmpdir . 'foobar/myfolder');
|
||||
$fs->mkdir(self::$tmpdir . 'foobar/testfolder');
|
||||
file_put_contents(self::$tmpdir . 'foobar/myfolder/mytest.php', "<?php\necho 'Hello World'; // This is my test");
|
||||
file_put_contents(self::$tmpdir . 'foobar/testfolder/test.php', "<?php\necho 'Hello World'; // This is a test");
|
||||
file_put_contents(self::$tmpdir . 'foobar/myfolder/mytest.php',
|
||||
"<?php\necho 'Hello World'; // This is my test");
|
||||
file_put_contents(self::$tmpdir . 'foobar/testfolder/test.php',
|
||||
"<?php\necho 'Hello World'; // This is a test");
|
||||
$repository->setConfig('user.name', 'Luke Skywalker');
|
||||
$repository->setConfig('user.email', 'luke@rebel.org');
|
||||
$repository->addAll();
|
||||
@@ -65,7 +77,7 @@ class InterfaceTest extends WebTestCase
|
||||
$nested_dir = self::$tmpdir . 'nested/';
|
||||
$fs->mkdir($nested_dir);
|
||||
$git->createRepository($nested_dir . 'NestedRepo');
|
||||
$repository = $git->getRepository($nested_dir . '/NestedRepo');
|
||||
$repository = $git->getRepositoryCached($nested_dir, 'NestedRepo');
|
||||
file_put_contents($nested_dir . 'NestedRepo/.git/description', 'This is a NESTED test repo!');
|
||||
file_put_contents($nested_dir . 'NestedRepo/README.txt', 'NESTED TEST REPO README');
|
||||
$repository->setConfig('user.name', 'Luke Skywalker');
|
||||
@@ -81,7 +93,7 @@ class InterfaceTest extends WebTestCase
|
||||
|
||||
// master-less repository fixture
|
||||
$git->createRepository(self::$tmpdir . 'develop');
|
||||
$repository = $git->getRepository(self::$tmpdir . '/develop');
|
||||
$repository = $git->getRepositoryCached(self::$tmpdir, 'develop');
|
||||
$repository->setConfig('user.name', 'Luke Skywalker');
|
||||
$repository->setConfig('user.email', 'luke@rebel.org');
|
||||
file_put_contents(self::$tmpdir . 'develop/README.md', "## develop\ndevelop is a *test* repository!");
|
||||
@@ -98,26 +110,26 @@ class InterfaceTest extends WebTestCase
|
||||
|
||||
// Detached HEAD repository fixture
|
||||
$git->createRepository(self::$tmpdir . 'detached-head');
|
||||
$repository = $git->getRepository(self::$tmpdir . '/detached-head');
|
||||
$repository = $git->getRepositoryCached(self::$tmpdir, 'detached-head');
|
||||
# $repository = $git->getRepository(self::$tmpdir . '/detached-head');
|
||||
$repository->setConfig('user.name', 'Luke Skywalker');
|
||||
$repository->setConfig('user.email', 'luke@rebel.org');
|
||||
file_put_contents(self::$tmpdir . 'detached-head/README.md', "## detached head\ndetached-head is a *test* repository!");
|
||||
$repository->addAll();
|
||||
$repository->commit("First commit");
|
||||
$repository->checkout('HEAD');
|
||||
|
||||
$git->deleteCached();
|
||||
}
|
||||
|
||||
public function createApplication()
|
||||
{
|
||||
$config = new \GitList\Config(array(
|
||||
'git' => array(
|
||||
'client' => self::$gitPath,
|
||||
'repositories' => self::$tmpdir,
|
||||
),
|
||||
'app' => array(
|
||||
'debug' => true,
|
||||
),
|
||||
));
|
||||
$config = GitList\Config::fromFile('config.ini');
|
||||
$config->set('app', 'cached_repos', self::$cached_repos);
|
||||
$config->set('git', 'repositories', self::$tmpdir);
|
||||
$config->set('app', 'debug', true);
|
||||
$config->set('git', 'client', self::$gitPath);
|
||||
|
||||
$app = require 'boot.php';
|
||||
return $app;
|
||||
}
|
||||
@@ -129,11 +141,11 @@ class InterfaceTest extends WebTestCase
|
||||
|
||||
$this->assertTrue($client->getResponse()->isOk());
|
||||
$this->assertCount(1, $crawler->filter('title:contains("GitList")'));
|
||||
$this->assertCount(1, $crawler->filter('div.repository-header:contains("GitTest")'));
|
||||
$this->assertCount(1, $crawler->filter('div.repository-header a:contains("GitTest")'));
|
||||
$this->assertEquals('/GitTest/', $crawler->filter('.repository-header a')->eq(0)->attr('href'));
|
||||
$this->assertEquals('/GitTest/master/rss/', $crawler->filter('.repository-header a')->eq(1)->attr('href'));
|
||||
$this->assertEquals('/nested/NestedRepo/', $crawler->filter('.repository-header a')->eq(2)->attr('href'));
|
||||
$this->assertEquals('/nested/NestedRepo/master/rss/', $crawler->filter('.repository-header a')->eq(3)->attr('href'));
|
||||
$this->assertEquals('/NestedRepo/', $crawler->filter('.repository-header a')->eq(2)->attr('href'));
|
||||
$this->assertEquals('/NestedRepo/master/rss/', $crawler->filter('.repository-header a')->eq(3)->attr('href'));
|
||||
$this->assertCount(1, $crawler->filter('div.repository-header:contains("foobar")'));
|
||||
$this->assertCount(1, $crawler->filter('div.repository-body:contains("This is a test repo!")'));
|
||||
$this->assertEquals('/foobar/', $crawler->filter('.repository-header a')->eq(8)->attr('href'));
|
||||
@@ -175,11 +187,15 @@ class InterfaceTest extends WebTestCase
|
||||
$client = $this->createClient();
|
||||
|
||||
$crawler = $client->request('GET', '/GitTest/blob/master/test.php');
|
||||
|
||||
$this->assertTrue($client->getResponse()->isOk());
|
||||
$this->assertCount(1, $crawler->filter('.breadcrumb .active:contains("test.php")'));
|
||||
$this->assertEquals('/GitTest/raw/master/test.php', $crawler->filter('.source-header .btn-group a')->eq(0)->attr('href'));
|
||||
$this->assertEquals('/GitTest/blame/master/test.php', $crawler->filter('.source-header .btn-group a')->eq(1)->attr('href'));
|
||||
$this->assertEquals('/GitTest/commits/master/test.php', $crawler->filter('.source-header .btn-group a')->eq(2)->attr('href'));
|
||||
$this->assertEquals('/GitTest/raw/master/test.php',
|
||||
$crawler->filter('.source-header .btn-group a')->eq(0)->attr('href'));
|
||||
$this->assertEquals('/GitTest/blame/master/test.php',
|
||||
$crawler->filter('.source-header .btn-group a')->eq(1)->attr('href'));
|
||||
$this->assertEquals('/GitTest/commits/master/test.php',
|
||||
$crawler->filter('.source-header .btn-group a')->eq(2)->attr('href'));
|
||||
}
|
||||
|
||||
public function testRawPage()
|
||||
@@ -198,12 +214,14 @@ class InterfaceTest extends WebTestCase
|
||||
$crawler = $client->request('GET', '/GitTest/blame/master/test.php');
|
||||
$this->assertTrue($client->getResponse()->isOk());
|
||||
$this->assertCount(1, $crawler->filter('.source-header .meta:contains("test.php")'));
|
||||
$this->assertRegexp('/\/GitTest\/commit\/[a-zA-Z0-9%]+/', $crawler->filter('.blame-view .commit')->eq(0)->filter('a')->attr('href'));
|
||||
$this->assertRegexp('/\/GitTest\/commit\/[a-zA-Z0-9%]+/',
|
||||
$crawler->filter('.blame-view .commit')->eq(0)->filter('a')->attr('href'));
|
||||
|
||||
$crawler = $client->request('GET', '/foobar/blame/master/bar.json');
|
||||
$this->assertTrue($client->getResponse()->isOk());
|
||||
$this->assertCount(1, $crawler->filter('.source-header .meta:contains("bar.json")'));
|
||||
$this->assertRegexp('/\/foobar\/commit\/[a-zA-Z0-9%]+/', $crawler->filter('.blame-view .commit')->eq(0)->filter('a')->attr('href'));
|
||||
$this->assertRegexp('/\/foobar\/commit\/[a-zA-Z0-9%]+/',
|
||||
$crawler->filter('.blame-view .commit')->eq(0)->filter('a')->attr('href'));
|
||||
}
|
||||
|
||||
public function testHistoryPage()
|
||||
@@ -252,8 +270,10 @@ class InterfaceTest extends WebTestCase
|
||||
{
|
||||
$client = $this->createClient();
|
||||
|
||||
$crawler = $client->request('GET', '/GitTest/master/rss/');
|
||||
$this->assertTrue($client->getResponse()->isOk());
|
||||
$client->request('GET', '/GitTest/master/rss/');
|
||||
$response = $client->getResponse();
|
||||
|
||||
$this->assertTrue($response->isOk());
|
||||
$this->assertRegexp('/Latest commits in GitTest:master/', $client->getResponse()->getContent());
|
||||
$this->assertRegexp('/Initial commit/', $client->getResponse()->getContent());
|
||||
}
|
||||
@@ -262,8 +282,10 @@ class InterfaceTest extends WebTestCase
|
||||
{
|
||||
$client = $this->createClient();
|
||||
|
||||
$crawler = $client->request('GET', '/nested/NestedRepo/');
|
||||
$this->assertTrue($client->getResponse()->isOk());
|
||||
$client->request('GET', '/NestedRepo/');
|
||||
$response = $client->getResponse();
|
||||
|
||||
$this->assertTrue($response->isOk());
|
||||
$this->assertRegexp('/NESTED TEST REPO README/', $client->getResponse()->getContent());
|
||||
}
|
||||
|
||||
@@ -279,7 +301,7 @@ class InterfaceTest extends WebTestCase
|
||||
{
|
||||
$client = $this->createClient();
|
||||
|
||||
$crawler = $client->request('GET', '/nested/NestedRepo/testing/');
|
||||
$crawler = $client->request('GET', '/NestedRepo/testing/');
|
||||
$this->assertTrue($client->getResponse()->isOk());
|
||||
$this->assertRegexp('/NESTED TEST BRANCH README/', $client->getResponse()->getContent());
|
||||
}
|
||||
@@ -290,3 +312,4 @@ class InterfaceTest extends WebTestCase
|
||||
$fs->remove(self::$tmpdir);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
{% for repository in repositories %}
|
||||
<div class="repository">
|
||||
<div class="repository-header">
|
||||
<i class="icon-folder-open icon-spaced"></i> <a href="{{ path('repository', {repo: repository.relativePath}) }}">{{ repository.name }}</a>
|
||||
<a href="{{ path('rss', {repo: repository.relativePath, branch: repository.branch }) }}"><i class="rss pull-right"></i></a>
|
||||
<i class="icon-folder-open icon-spaced"></i> <a href="{{ path('repository', {repo: repository.name}) }}">{{ repository.name }}</a>
|
||||
<a href="{{ path('rss', {repo: repository.name, branch: 'master'}) }}"><i class="rss pull-right"></i></a>
|
||||
</div>
|
||||
<div class="repository-body">
|
||||
<p>{{ repository.description }}</p>
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
<div class="nav-collapse">
|
||||
<ul class="nav pull-right">
|
||||
<li><a href="http://gitlist.org/">About</a></li>
|
||||
<li><a href="{{ path('homepage') }}refresh">Refresh</a></li>
|
||||
<li><a href="https://github.com/klaussilveira/gitlist/issues/new">Report bug</a></li>
|
||||
<li><a href="https://github.com/klaussilveira/gitlist/wiki">Help</a></li>
|
||||
</ul>
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
<tbody>
|
||||
{% for result in results %}
|
||||
<tr>
|
||||
<td><i class="icon-file icon-spaced"></i> <a href="{{ path('blob', {repo: repo, branch: branch, file: result.file}) }}#L{{ result.line }}">{{ result.file }}</a></td>
|
||||
<td><i class="icon-file icon-spaced"></i> <a href="{{ path('blob', {repo: repo, branch: branch, file: result.file, commitishPath: branch ~ '/' ~ result.file}) }}#L{{ result.line }}">{{ result.file }}</a></td>
|
||||
<td>{{ result.match }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
||||
Reference in New Issue
Block a user