diff --git a/boot.php b/boot.php index 5e36efe..9b84f04 100644 --- a/boot.php +++ b/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; + diff --git a/config.ini-example b/config.ini-example index 2604f89..c5f8fcb 100644 --- a/config.ini-example +++ b/config.ini-example @@ -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' diff --git a/index.php b/index.php index e6c7b6f..5d59466 100644 --- a/index.php +++ b/index.php @@ -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(); + diff --git a/src/GitList/Application.php b/src/GitList/Application.php index 9671dd6..ced3505 100644 --- a/src/GitList/Application.php +++ b/src/GitList/Application.php @@ -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 }); } } + diff --git a/src/GitList/Config.php b/src/GitList/Config.php index 60bbf5c..711133b 100644 --- a/src/GitList/Config.php +++ b/src/GitList/Config.php @@ -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"); + } } } + diff --git a/src/GitList/Controller/BlobController.php b/src/GitList/Controller/BlobController.php index a954da0..d006fe7 100644 --- a/src/GitList/Controller/BlobController.php +++ b/src/GitList/Controller/BlobController.php @@ -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; } } + diff --git a/src/GitList/Controller/CommitController.php b/src/GitList/Controller/CommitController.php index aaa6c85..e017160 100644 --- a/src/GitList/Controller/CommitController.php +++ b/src/GitList/Controller/CommitController.php @@ -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; } } + diff --git a/src/GitList/Controller/MainController.php b/src/GitList/Controller/MainController.php index f7b5a85..58cd494 100644 --- a/src/GitList/Controller/MainController.php +++ b/src/GitList/Controller/MainController.php @@ -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; } } + diff --git a/src/GitList/Controller/TreeController.php b/src/GitList/Controller/TreeController.php index f14ebf2..3a24d0d 100644 --- a/src/GitList/Controller/TreeController.php +++ b/src/GitList/Controller/TreeController.php @@ -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; } } + diff --git a/src/GitList/Git/Client.php b/src/GitList/Git/Client.php index 0034f8f..4129a7b 100644 --- a/src/GitList/Git/Client.php +++ b/src/GitList/Git/Client.php @@ -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); } } + diff --git a/src/GitList/Git/Repository.php b/src/GitList/Git/Repository.php index dc8eec3..65db976 100644 --- a/src/GitList/Git/Repository.php +++ b/src/GitList/Git/Repository.php @@ -42,7 +42,16 @@ class Repository extends BaseRepository */ public function getCommit($commitHash) { - $logs = $this->getClient()->run($this, "show --pretty=format:\"%H%h%T%P%an%ae%at%cn%ce%ct\" $commitHash"); + $logs = $this->getClient()->run($this, + "show --pretty=format:\"%H" + . "%h%T%P" + . "%an%ae" + . "%at%cn%ce" + . "%ct" + . "" + . "" + . "\" $commitHash" + ); $xmlEnd = strpos($logs, '') + 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:\"%H%h%T%P%an%ae%at%cn%ce%ct\""; + $command = + "log $pager --pretty=format:\"%H" + . "%h%T%P" + . "%an%ae" + . "%at%cn" + . "%ce" + . "%ct" + . "\""; 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:\"%H%h%T%P%an%ae%at%cn%ce%ct\""; + $command = + "log --grep={$query} --pretty=format:\"%H" + . "%h%T%P" + . "%an%ae" + . "%at%cn" + . "%ce" + . "%ct" + . "\""; try { $logs = $this->getPrettyFormat($command); @@ -366,3 +389,4 @@ class Repository extends BaseRepository return false; } } + diff --git a/src/GitList/Provider/GitServiceProvider.php b/src/GitList/Provider/GitServiceProvider.php index 825b1f8..c4e0808 100644 --- a/src/GitList/Provider/GitServiceProvider.php +++ b/src/GitList/Provider/GitServiceProvider.php @@ -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 { } } + diff --git a/src/GitList/Util/Repository.php b/src/GitList/Util/Repository.php index 1782dac..5f6c80c 100644 --- a/src/GitList/Util/Repository.php +++ b/src/GitList/Util/Repository.php @@ -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); } } + diff --git a/src/GitList/Util/Routing.php b/src/GitList/Util/Routing.php index a1e33f5..cb067b5 100644 --- a/src/GitList/Util/Routing.php +++ b/src/GitList/Util/Routing.php @@ -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 } } } + diff --git a/tests/InterfaceTest.php b/tests/InterfaceTest.php index e44e0b6..74f751f 100644 --- a/tests/InterfaceTest.php +++ b/tests/InterfaceTest.php @@ -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', "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', "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); } } + diff --git a/views/index.twig b/views/index.twig index b3f075d..db725ac 100644 --- a/views/index.twig +++ b/views/index.twig @@ -9,8 +9,8 @@ {% for repository in repositories %}
- {{ repository.name }} - + {{ repository.name }} +

{{ repository.description }}

diff --git a/views/navigation.twig b/views/navigation.twig index eef7144..6391812 100644 --- a/views/navigation.twig +++ b/views/navigation.twig @@ -10,6 +10,7 @@