Updated dependencies.

This commit is contained in:
Klaus Silveira
2017-08-22 11:09:48 -04:00
parent 9f77f50e79
commit cc1dc5af14
37 changed files with 2797 additions and 1637 deletions

1
.gitignore vendored
View File

@@ -32,3 +32,4 @@ config.ini
cache.properties cache.properties
composer.phar composer.phar
phpunit.xml phpunit.xml
.php_cs.cache

29
.php_cs Normal file
View File

@@ -0,0 +1,29 @@
<?php
$finder = PhpCsFixer\Finder::create()
->in(__DIR__ . '/src')
->in(__DIR__ . '/tests');
return PhpCsFixer\Config::create()
->setRules([
'@Symfony' => true,
'array_syntax' => ['syntax' => 'short'],
'blank_line_after_opening_tag' => true,
'concat_space' => ['spacing' => 'one'],
'method_argument_space' => ['ensure_fully_multiline' => true],
'modernize_types_casting' => true,
'no_multiline_whitespace_before_semicolons' => true,
'no_useless_else' => true,
'no_useless_return' => true,
'ordered_class_elements' => true,
'ordered_imports' => true,
'phpdoc_align' => false,
'phpdoc_order' => true,
'php_unit_construct' => true,
'php_unit_dedicate_assert' => true,
'pre_increment' => false,
'single_line_comment_style' => true,
])
->setFinder($finder)
->setUsingCache(true)
->setRiskyAllowed(true);

View File

@@ -1,11 +1,20 @@
language: php language: php
before_script:
- curl -s http://getcomposer.org/installer | php
- php composer.phar install --dev
php: php:
- 5.3
- 5.4 - 5.4
- 7.0
- 7.1
script: phpunit cache:
directories:
- vendor
install:
- travis_retry composer install --no-interaction --prefer-source
script:
- vendor/bin/php-cs-fixer fix --dry-run -v
- vendor/bin/phpunit --verbose
matrix:
fast_finish: true

View File

@@ -1,4 +1,4 @@
Copyright (c) 2012-2015, Klaus Silveira and contributors Copyright (c) 2012, Klaus Silveira and contributors
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

View File

@@ -26,7 +26,7 @@ In order to run GitList on your server, you'll need:
* git * git
* Apache with mod_rewrite enabled or nginx * Apache with mod_rewrite enabled or nginx
* PHP 5.3.3 * PHP 5.4
## Installation ## 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. * Download GitList from [gitlist.org](http://gitlist.org/) and decompress to your `/var/www/gitlist` folder, or anywhere else you want to place GitList.

View File

@@ -87,17 +87,16 @@
</target> </target>
<target name="phpcs" description="Find coding standard violations using PHP_CodeSniffer creating a log file for the continuous integration server"> <target name="phpcs" description="Find coding standard violations using PHP_CodeSniffer creating a log file for the continuous integration server">
<exec executable="${vendordir}/phpcs" output="/dev/null"> <exec executable="${vendordir}/php-cs-fixer" output="${basedir}/build/logs/cs.xml">
<arg value="--report=checkstyle" /> <arg value="fix" />
<arg value="--report-file=${basedir}/build/logs/checkstyle.xml" /> <arg value="--dry-run" />
<arg value="--standard=PSR2" /> <arg value="--format=junit" />
<arg path="${basedir}/src" />
</exec> </exec>
</target> </target>
<target name="package" description="Package the application for distribution"> <target name="package" description="Package the application for distribution">
<copy todir="${basedir}/build/gitlist/"> <copy todir="${basedir}/build/gitlist/">
<fileset dir="${basedir}" excludes="cache/**, build/**, tests/**, pkg_builder/**, phpunit.xml.dist, cache.properties, .gitignore, .travis.yml, build.xml, composer.json, composer.lock, config.ini" /> <fileset dir="${basedir}" excludes="cache/**, build/**, tests/**, pkg_builder/**, phpunit.xml.dist, cache.properties, .gitignore, .travis.yml, build.xml, composer.json, composer.lock, composer.phar, config.ini, .php_cs, .php_cs.cache" />
</copy> </copy>
<tar destfile="${basedir}/build/gitlist-master.tar.gz" <tar destfile="${basedir}/build/gitlist-master.tar.gz"

View File

@@ -2,20 +2,20 @@
"name": "klaussilveira/gitlist", "name": "klaussilveira/gitlist",
"description": "An elegant git repository viewer", "description": "An elegant git repository viewer",
"require": { "require": {
"silex/silex": "1.*", "silex/silex": "~2.2",
"twig/twig": "1.*", "twig/twig": "~2.4",
"symfony/twig-bridge": "2.4.*", "symfony/twig-bridge": "~3.3",
"symfony/filesystem": "2.4.*", "symfony/filesystem": "~3.3",
"klaussilveira/gitter": "0.2.*" "klaussilveira/gitter": "0.2.*"
}, },
"require-dev": { "require-dev": {
"symfony/browser-kit": "2.3.*", "symfony/browser-kit": "~3.3",
"symfony/css-selector": "2.3.*", "symfony/css-selector": "~3.3",
"phpunit/phpunit": "4.1.*", "phpunit/phpunit": "~5.0",
"phpmd/phpmd": "1.5.*", "phpmd/phpmd": "1.5.*",
"phploc/phploc": "2.0.*", "phploc/phploc": "2.0.*",
"sebastian/phpcpd": "2.0.*", "sebastian/phpcpd": "2.0.*",
"squizlabs/php_codesniffer": "2.0.*@dev" "friendsofphp/php-cs-fixer": "~2.4"
}, },
"minimum-stability": "stable", "minimum-stability": "stable",
"autoload": { "autoload": {

2925
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -2,13 +2,13 @@
namespace GitList; namespace GitList;
use Silex\Application as SilexApplication;
use Silex\Provider\TwigServiceProvider;
use Silex\Provider\UrlGeneratorServiceProvider;
use GitList\Provider\GitServiceProvider; use GitList\Provider\GitServiceProvider;
use GitList\Provider\RepositoryUtilServiceProvider; use GitList\Provider\RepositoryUtilServiceProvider;
use GitList\Provider\ViewUtilServiceProvider;
use GitList\Provider\RoutingUtilServiceProvider; use GitList\Provider\RoutingUtilServiceProvider;
use GitList\Provider\ViewUtilServiceProvider;
use Silex\Application as SilexApplication;
use Silex\Provider\RoutingServiceProvider;
use Silex\Provider\TwigServiceProvider;
use Symfony\Component\Filesystem\Filesystem; use Symfony\Component\Filesystem\Filesystem;
/** /**
@@ -31,74 +31,75 @@ class Application extends SilexApplication
$this->path = realpath($root); $this->path = realpath($root);
$this['debug'] = $config->get('app', 'debug'); $this['debug'] = $config->get('app', 'debug');
$this['date.format'] = $config->get('date', 'format') ? $config->get('date', 'format') : 'd/m/Y H:i:s';
$this['theme'] = $config->get('app', 'theme') ? $config->get('app', 'theme') : 'default'; $this['theme'] = $config->get('app', 'theme') ? $config->get('app', 'theme') : 'default';
$this['title'] = $config->get('app', 'title') ? $config->get('app', 'title') : 'GitList'; $this['date.format'] = $config->get('date', 'format') ? $config->get('date', 'format') : 'd/m/Y H:i:s';
$this['filetypes'] = $config->getSection('filetypes'); $this['filetypes'] = $config->getSection('filetypes');
$this['binary_filetypes'] = $config->getSection('binary_filetypes'); $this['binary_filetypes'] = $config->getSection('binary_filetypes');
$this['cache.archives'] = $this->getCachePath() . 'archives'; $this['cache.archives'] = $this->getCachePath() . 'archives';
$this['avatar.url'] = $config->get('avatar', 'url'); $this['avatar.url'] = $config->get('avatar', 'url');
$this['avatar.query'] = $config->get('avatar', 'query'); $this['avatar.query'] = $config->get('avatar', 'query');
$this['show_http_remote'] = $config->get('clone_button', 'show_http_remote');
$this['use_https'] = $config->get('clone_button', 'use_https');
$this['http_url_subdir'] = $config->get('clone_button', 'http_url_subdir');
$this['http_user'] = $config->get('clone_button', 'http_user_dynamic') ? $_SERVER['PHP_AUTH_USER'] : $config->get('clone_button', 'http_user');
$this['http_host'] = $config->get('clone_button', 'http_host');
$this['show_ssh_remote'] = $config->get('clone_button', 'show_ssh_remote');
$this['ssh_user'] = $config->get('clone_button', 'ssh_user_dynamic') ? $_SERVER['PHP_AUTH_USER'] : $config->get('clone_button', 'ssh_user');
$this['ssh_url_subdir'] = $config->get('clone_button', 'ssh_url_subdir');
$this['ssh_host'] = $config->get('clone_button', 'ssh_host');
// Register services // Register services
$this->register(new TwigServiceProvider(), array( $this->register(new TwigServiceProvider(), [
'twig.path' => array($this->getThemePath($this['theme']), $this->getThemePath('default')), 'twig.path' => [$this->getThemePath($this['theme']), $this->getThemePath('default')],
'twig.options' => $config->get('app', 'cache') ? 'twig.options' => $config->get('app', 'cache') ?
array('cache' => $this->getCachePath() . 'views') : array(), ['cache' => $this->getCachePath() . 'views'] : [],
)); ]);
$repositories = $config->get('git', 'repositories'); $repositories = $config->get('git', 'repositories');
$this['git.projects'] = $config->get('git', 'project_list') ? $this['git.projects'] = $config->get('git', 'project_list') ?
$this->parseProjectList($config->get('git', 'project_list')) : $this->parseProjectList($config->get('git', 'project_list')) :
false; false;
$this->register(new GitServiceProvider(), array( $this->register(new GitServiceProvider(), [
'git.client' => $config->get('git', 'client'), 'git.client' => $config->get('git', 'client'),
'git.repos' => $repositories, 'git.repos' => $repositories,
'ini.file' => "config.ini", 'ini.file' => 'config.ini',
'git.hidden' => $config->get('git', 'hidden') ? 'git.hidden' => $config->get('git', 'hidden') ?
$config->get('git', 'hidden') : array(), $config->get('git', 'hidden') : [],
'git.default_branch' => $config->get('git', 'default_branch') ? 'git.default_branch' => $config->get('git', 'default_branch') ?
$config->get('git', 'default_branch') : 'master', $config->get('git', 'default_branch') : 'master',
)); ]);
$this->register(new ViewUtilServiceProvider()); $this->register(new ViewUtilServiceProvider());
$this->register(new RepositoryUtilServiceProvider()); $this->register(new RepositoryUtilServiceProvider());
$this->register(new UrlGeneratorServiceProvider()); $this->register(new RoutingServiceProvider());
$this->register(new RoutingUtilServiceProvider()); $this->register(new RoutingUtilServiceProvider());
$this['twig'] = $this->share($this->extend('twig', function ($twig, $app) { $this->extend('twig', function ($twig, $app) use ($config) {
$twig->addFilter(new \Twig_SimpleFilter('htmlentities', 'htmlentities')); $twig->addFilter(new \Twig_SimpleFilter('htmlentities', 'htmlentities'));
$twig->addFilter(new \Twig_SimpleFilter('md5', 'md5')); $twig->addFilter(new \Twig_SimpleFilter('md5', 'md5'));
$twig->addFilter(new \Twig_SimpleFilter('format_date', array($app, 'formatDate'))); $twig->addFilter(new \Twig_SimpleFilter('format_date', [$app, 'formatDate']));
$twig->addFilter(new \Twig_SimpleFilter('format_size', array($app, 'formatSize'))); $twig->addFilter(new \Twig_SimpleFilter('format_size', [$app, 'formatSize']));
$twig->addFunction(new \Twig_SimpleFunction('avatar', array($app, 'getAvatar'))); $twig->addFunction(new \Twig_SimpleFunction('avatar', [$app, 'getAvatar']));
$twig->addGlobal('theme', $app['theme']);
$twig->addGlobal('title', $config->get('app', 'title') ? $config->get('app', 'title') : 'GitList');
$twig->addGlobal('show_http_remote', $config->get('clone_button', 'show_http_remote'));
$twig->addGlobal('use_https', $config->get('clone_button', 'use_https'));
$twig->addGlobal('http_url_subdir', $config->get('clone_button', 'http_url_subdir'));
$twig->addGlobal('http_user', $config->get('clone_button', 'http_user_dynamic') ? $_SERVER['PHP_AUTH_USER'] : $config->get('clone_button', 'http_user'));
$twig->addGlobal('http_host', $config->get('clone_button', 'http_host'));
$twig->addGlobal('show_ssh_remote', $config->get('clone_button', 'show_ssh_remote'));
$twig->addGlobal('ssh_user', $config->get('clone_button', 'ssh_user_dynamic') ? $_SERVER['PHP_AUTH_USER'] : $config->get('clone_button', 'ssh_user'));
$twig->addGlobal('ssh_url_subdir', $config->get('clone_button', 'ssh_url_subdir'));
$twig->addGlobal('ssh_host', $config->get('clone_button', 'ssh_host'));
return $twig; return $twig;
}));
$this['escaper.argument'] = $this->share(function() {
return new Escaper\ArgumentEscaper();
}); });
$this['escaper.argument'] = function () {
return new Escaper\ArgumentEscaper();
};
// Handle errors // Handle errors
$this->error(function (\Exception $e, $code) use ($app) { $this->error(function (\Exception $e, $code) use ($app) {
if ($app['debug']) { if ($app['debug']) {
return; return;
} }
return $app['twig']->render('error.twig', array( return $app['twig']->render('error.twig', [
'message' => $e->getMessage(), 'message' => $e->getMessage(),
)); ]);
}); });
$this->finish(function () use ($app, $config) { $this->finish(function () use ($app, $config) {
@@ -117,21 +118,26 @@ class Application extends SilexApplication
public function formatSize($size) public function formatSize($size)
{ {
$mod = 1000; $mod = 1000;
$units = array('B', 'kB', 'MB', 'GB'); $units = ['B', 'kB', 'MB', 'GB'];
for($i = 0; $size > $mod; $i++) $size /= $mod; for ($i = 0; $size > $mod; $i++) {
$size /= $mod;
}
return round($size, 2) . $units[$i]; return round($size, 2) . $units[$i];
} }
public function getAvatar($email, $size) public function getAvatar($email, $size)
{ {
$url = $this['avatar.url'] ? $this['avatar.url'] : "//gravatar.com/avatar/"; $url = $this['avatar.url'] ? $this['avatar.url'] : '//gravatar.com/avatar/';
$query = array("s=$size"); $query = ["s=$size"];
if (is_string($this['avatar.query'])) if (is_string($this['avatar.query'])) {
$query[] = $this['avatar.query']; $query[] = $this['avatar.query'];
else if (is_array($this['avatar.query'])) } elseif (is_array($this['avatar.query'])) {
$query = array_merge($query, $this['avatar.query']); $query = array_merge($query, $this['avatar.query']);
}
$id = md5(strtolower($email)); $id = md5(strtolower($email));
return $url . $id . "?" . implode('&', $query);
return $url . $id . '?' . implode('&', $query);
} }
public function getPath() public function getPath()
@@ -168,11 +174,13 @@ class Application extends SilexApplication
public function parseProjectList($project_list) public function parseProjectList($project_list)
{ {
$projects = array(); $projects = [];
$file = fopen($project_list, "r"); $file = fopen($project_list, 'r');
while ($file && !feof($file)) while ($file && !feof($file)) {
$projects[] = trim(fgets($file)); $projects[] = trim(fgets($file));
}
fclose($file); fclose($file);
return $projects; return $projects;
} }
} }

View File

@@ -6,6 +6,11 @@ class Config
{ {
protected $data; protected $data;
public function __construct($data = [])
{
$this->data = $data;
}
public static function fromFile($file) public static function fromFile($file)
{ {
if (!file_exists($file)) { if (!file_exists($file)) {
@@ -19,11 +24,6 @@ class Config
return $config; return $config;
} }
public function __construct($data = array())
{
$this->data = $data;
}
public function get($section, $option) public function get($section, $option)
{ {
if (!array_key_exists($section, $this->data)) { if (!array_key_exists($section, $this->data)) {
@@ -67,12 +67,11 @@ class Config
} }
if (!$atLeastOneOk) { if (!$atLeastOneOk) {
die("Please, edit the config file and provide your repositories directory"); die('Please, edit the config file and provide your repositories directory');
} }
if ($atLeastOneWrong) { if ($atLeastOneWrong) {
die("One or more of the supplied repository paths appears to be wrong. Please, check the config file"); die('One or more of the supplied repository paths appears to be wrong. Please, check the config file');
} }
} }
} }

View File

@@ -2,8 +2,8 @@
namespace GitList\Controller; namespace GitList\Controller;
use Silex\Api\ControllerProviderInterface;
use Silex\Application; use Silex\Application;
use Silex\ControllerProviderInterface;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
class BlobController implements ControllerProviderInterface class BlobController implements ControllerProviderInterface
@@ -25,13 +25,13 @@ class BlobController implements ControllerProviderInterface
$fileType = $app['util.repository']->getFileType($file); $fileType = $app['util.repository']->getFileType($file);
if ($fileType !== 'image' && $app['util.repository']->isBinary($file)) { if ($fileType !== 'image' && $app['util.repository']->isBinary($file)) {
return $app->redirect($app['url_generator']->generate('blob_raw', array( return $app->redirect($app['url_generator']->generate('blob_raw', [
'repo' => $repo, 'repo' => $repo,
'commitishPath' => $commitishPath, 'commitishPath' => $commitishPath,
))); ]));
} }
return $app['twig']->render('file.twig', array( return $app['twig']->render('file.twig', [
'file' => $file, 'file' => $file,
'fileType' => $fileType, 'fileType' => $fileType,
'blob' => $blob->output(), 'blob' => $blob->output(),
@@ -40,7 +40,7 @@ class BlobController implements ControllerProviderInterface
'breadcrumbs' => $breadcrumbs, 'breadcrumbs' => $breadcrumbs,
'branches' => $repository->getBranches(), 'branches' => $repository->getBranches(),
'tags' => $repository->getTags(), 'tags' => $repository->getTags(),
)); ]);
})->assert('repo', $app['util.routing']->getRepositoryRegex()) })->assert('repo', $app['util.routing']->getRepositoryRegex())
->assert('commitishPath', '.+') ->assert('commitishPath', '.+')
->convert('commitishPath', 'escaper.argument:escape') ->convert('commitishPath', 'escaper.argument:escape')
@@ -56,7 +56,7 @@ class BlobController implements ControllerProviderInterface
$blob = $repository->getBlob("$branch:\"$file\"")->output(); $blob = $repository->getBlob("$branch:\"$file\"")->output();
$headers = array(); $headers = [];
if ($app['util.repository']->isBinary($file)) { if ($app['util.repository']->isBinary($file)) {
$headers['Content-Disposition'] = 'attachment; filename="' . $file . '"'; $headers['Content-Disposition'] = 'attachment; filename="' . $file . '"';
$headers['Content-Type'] = 'application/octet-stream'; $headers['Content-Type'] = 'application/octet-stream';
@@ -79,12 +79,12 @@ class BlobController implements ControllerProviderInterface
$filePatchesLog = $repository->getCommitsLogPatch($file); $filePatchesLog = $repository->getCommitsLogPatch($file);
$breadcrumbs = $app['util.view']->getBreadcrumbs($file); $breadcrumbs = $app['util.view']->getBreadcrumbs($file);
return $app['twig']->render('logpatch.twig', array( return $app['twig']->render('logpatch.twig', [
'branch' => $branch, 'branch' => $branch,
'repo' => $repo, 'repo' => $repo,
'breadcrumbs' => $breadcrumbs, 'breadcrumbs' => $breadcrumbs,
'commits' => $filePatchesLog, 'commits' => $filePatchesLog,
)); ]);
})->assert('repo', $app['util.routing']->getRepositoryRegex()) })->assert('repo', $app['util.routing']->getRepositoryRegex())
->assert('commitishPath', '.+') ->assert('commitishPath', '.+')
->convert('commitishPath', 'escaper.argument:escape') ->convert('commitishPath', 'escaper.argument:escape')
@@ -93,4 +93,3 @@ class BlobController implements ControllerProviderInterface
return $route; return $route;
} }
} }

View File

@@ -2,8 +2,8 @@
namespace GitList\Controller; namespace GitList\Controller;
use Silex\Api\ControllerProviderInterface;
use Silex\Application; use Silex\Application;
use Silex\ControllerProviderInterface;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
class CommitController implements ControllerProviderInterface class CommitController implements ControllerProviderInterface
@@ -16,12 +16,13 @@ class CommitController implements ControllerProviderInterface
$subRequest = Request::create( $subRequest = Request::create(
'/' . $repo . '/commits/master/search', '/' . $repo . '/commits/master/search',
'POST', 'POST',
array('query' => $request->get('query')) ['query' => $request->get('query')]
); );
return $app->handle($subRequest, \Symfony\Component\HttpKernel\HttpKernelInterface::SUB_REQUEST); return $app->handle($subRequest, \Symfony\Component\HttpKernel\HttpKernelInterface::SUB_REQUEST);
})->assert('repo', $app['util.routing']->getRepositoryRegex()); })->assert('repo', $app['util.routing']->getRepositoryRegex());
$route->get('{repo}/commits/{commitishPath}', function ($repo, $commitishPath) use ($app) { $route->get('{repo}/commits/{commitishPath}', function (Request $request, $repo, $commitishPath) use ($app) {
$repository = $app['git']->getRepositoryFromName($app['git.repos'], $repo); $repository = $app['git']->getRepositoryFromName($app['git.repos'], $repo);
if ($commitishPath === null) { if ($commitishPath === null) {
@@ -34,9 +35,9 @@ class CommitController implements ControllerProviderInterface
list($branch, $file) = $app['util.repository']->extractRef($repository, $branch, $file); list($branch, $file) = $app['util.repository']->extractRef($repository, $branch, $file);
$type = $file ? "$branch -- \"$file\"" : $branch; $type = $file ? "$branch -- \"$file\"" : $branch;
$pager = $app['util.view']->getPager($app['request']->get('page'), $repository->getTotalCommits($type)); $pager = $app['util.view']->getPager($request->get('page'), $repository->getTotalCommits($type));
$commits = $repository->getPaginatedCommits($type, $pager['current']); $commits = $repository->getPaginatedCommits($type, $pager['current']);
$categorized = array(); $categorized = [];
foreach ($commits as $commit) { foreach ($commits as $commit) {
$date = $commit->getCommiterDate(); $date = $commit->getCommiterDate();
@@ -44,9 +45,9 @@ class CommitController implements ControllerProviderInterface
$categorized[$date][] = $commit; $categorized[$date][] = $commit;
} }
$template = $app['request']->isXmlHttpRequest() ? 'commits_list.twig' : 'commits.twig'; $template = $request->isXmlHttpRequest() ? 'commits_list.twig' : 'commits.twig';
return $app['twig']->render($template, array( return $app['twig']->render($template, [
'page' => 'commits', 'page' => 'commits',
'pager' => $pager, 'pager' => $pager,
'repo' => $repo, 'repo' => $repo,
@@ -55,7 +56,7 @@ class CommitController implements ControllerProviderInterface
'tags' => $repository->getTags(), 'tags' => $repository->getTags(),
'commits' => $categorized, 'commits' => $categorized,
'file' => $file, 'file' => $file,
)); ]);
})->assert('repo', $app['util.routing']->getRepositoryRegex()) })->assert('repo', $app['util.routing']->getRepositoryRegex())
->assert('commitishPath', $app['util.routing']->getCommitishPathRegex()) ->assert('commitishPath', $app['util.routing']->getCommitishPathRegex())
->value('commitishPath', null) ->value('commitishPath', null)
@@ -67,7 +68,7 @@ class CommitController implements ControllerProviderInterface
$query = $request->get('query'); $query = $request->get('query');
$commits = $repository->searchCommitLog($query, $branch); $commits = $repository->searchCommitLog($query, $branch);
$categorized = array(); $categorized = [];
foreach ($commits as $commit) { foreach ($commits as $commit) {
$date = $commit->getCommiterDate(); $date = $commit->getCommiterDate();
@@ -75,15 +76,15 @@ class CommitController implements ControllerProviderInterface
$categorized[$date][] = $commit; $categorized[$date][] = $commit;
} }
return $app['twig']->render('searchcommits.twig', array( return $app['twig']->render('searchcommits.twig', [
'repo' => $repo, 'repo' => $repo,
'branch' => $branch, 'branch' => $branch,
'file' => '', 'file' => '',
'commits' => $categorized, 'commits' => $categorized,
'branches' => $repository->getBranches(), 'branches' => $repository->getBranches(),
'tags' => $repository->getTags(), 'tags' => $repository->getTags(),
'query' => $query 'query' => $query,
)); ]);
})->assert('repo', $app['util.routing']->getRepositoryRegex()) })->assert('repo', $app['util.routing']->getRepositoryRegex())
->assert('branch', $app['util.routing']->getBranchRegex()) ->assert('branch', $app['util.routing']->getBranchRegex())
->convert('branch', 'escaper.argument:escape') ->convert('branch', 'escaper.argument:escape')
@@ -94,11 +95,11 @@ class CommitController implements ControllerProviderInterface
$commit = $repository->getCommit($commit); $commit = $repository->getCommit($commit);
$branch = $repository->getHead(); $branch = $repository->getHead();
return $app['twig']->render('commit.twig', array( return $app['twig']->render('commit.twig', [
'branch' => $branch, 'branch' => $branch,
'repo' => $repo, 'repo' => $repo,
'commit' => $commit, 'commit' => $commit,
)); ]);
})->assert('repo', $app['util.routing']->getRepositoryRegex()) })->assert('repo', $app['util.routing']->getRepositoryRegex())
->assert('commit', '[a-f0-9^]+') ->assert('commit', '[a-f0-9^]+')
->bind('commit'); ->bind('commit');
@@ -113,14 +114,14 @@ class CommitController implements ControllerProviderInterface
$blames = $repository->getBlame("$branch -- \"$file\""); $blames = $repository->getBlame("$branch -- \"$file\"");
return $app['twig']->render('blame.twig', array( return $app['twig']->render('blame.twig', [
'file' => $file, 'file' => $file,
'repo' => $repo, 'repo' => $repo,
'branch' => $branch, 'branch' => $branch,
'branches' => $repository->getBranches(), 'branches' => $repository->getBranches(),
'tags' => $repository->getTags(), 'tags' => $repository->getTags(),
'blames' => $blames, 'blames' => $blames,
)); ]);
})->assert('repo', $app['util.routing']->getRepositoryRegex()) })->assert('repo', $app['util.routing']->getRepositoryRegex())
->assert('commitishPath', $app['util.routing']->getCommitishPathRegex()) ->assert('commitishPath', $app['util.routing']->getCommitishPathRegex())
->convert('commitishPath', 'escaper.argument:escape') ->convert('commitishPath', 'escaper.argument:escape')
@@ -129,4 +130,3 @@ class CommitController implements ControllerProviderInterface
return $route; return $route;
} }
} }

View File

@@ -2,10 +2,10 @@
namespace GitList\Controller; namespace GitList\Controller;
use Silex\Api\ControllerProviderInterface;
use Silex\Application; use Silex\Application;
use Silex\ControllerProviderInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
class MainController implements ControllerProviderInterface class MainController implements ControllerProviderInterface
{ {
@@ -16,14 +16,13 @@ class MainController implements ControllerProviderInterface
$route->get('/', function () use ($app) { $route->get('/', function () use ($app) {
$repositories = $app['git']->getRepositories($app['git.repos']); $repositories = $app['git']->getRepositories($app['git.repos']);
return $app['twig']->render('index.twig', array( return $app['twig']->render('index.twig', [
'repositories' => $repositories, 'repositories' => $repositories,
)); ]);
})->bind('homepage'); })->bind('homepage');
$route->get('/refresh', function (Request $request) use ($app) { $route->get('/refresh', function (Request $request) use ($app) {
# Go back to calling page // Go back to calling page
return $app->redirect($request->headers->get('Referer')); return $app->redirect($request->headers->get('Referer'));
})->bind('refresh'); })->bind('refresh');
@@ -37,14 +36,14 @@ class MainController implements ControllerProviderInterface
$stats = $repository->getStatistics($branch); $stats = $repository->getStatistics($branch);
$authors = $repository->getAuthorStatistics($branch); $authors = $repository->getAuthorStatistics($branch);
return $app['twig']->render('stats.twig', array( return $app['twig']->render('stats.twig', [
'repo' => $repo, 'repo' => $repo,
'branch' => $branch, 'branch' => $branch,
'branches' => $repository->getBranches(), 'branches' => $repository->getBranches(),
'tags' => $repository->getTags(), 'tags' => $repository->getTags(),
'stats' => $stats, 'stats' => $stats,
'authors' => $authors, 'authors' => $authors,
)); ]);
})->assert('repo', $app['util.routing']->getRepositoryRegex()) })->assert('repo', $app['util.routing']->getRepositoryRegex())
->assert('branch', $app['util.routing']->getBranchRegex()) ->assert('branch', $app['util.routing']->getBranchRegex())
->value('branch', null) ->value('branch', null)
@@ -60,13 +59,13 @@ class MainController implements ControllerProviderInterface
$commits = $repository->getPaginatedCommits($branch); $commits = $repository->getPaginatedCommits($branch);
$html = $app['twig']->render('rss.twig', array( $html = $app['twig']->render('rss.twig', [
'repo' => $repo, 'repo' => $repo,
'branch' => $branch, 'branch' => $branch,
'commits' => $commits, 'commits' => $commits,
)); ]);
return new Response($html, 200, array('Content-Type' => 'application/rss+xml')); return new Response($html, 200, ['Content-Type' => 'application/rss+xml']);
})->assert('repo', $app['util.routing']->getRepositoryRegex()) })->assert('repo', $app['util.routing']->getRepositoryRegex())
->assert('branch', $app['util.routing']->getBranchRegex()) ->assert('branch', $app['util.routing']->getBranchRegex())
->value('branch', null) ->value('branch', null)

View File

@@ -4,9 +4,8 @@ namespace GitList\Controller;
use GitList\Git\Repository; use GitList\Git\Repository;
use Gitter\Model\Commit\Commit; use Gitter\Model\Commit\Commit;
use Silex\Api\ControllerProviderInterface;
use Silex\Application; use Silex\Application;
use Silex\ControllerProviderInterface;
use Symfony\Component\HttpFoundation\Request;
class NetworkController implements ControllerProviderInterface class NetworkController implements ControllerProviderInterface
{ {
@@ -14,7 +13,8 @@ class NetworkController implements ControllerProviderInterface
{ {
$route = $app['controllers_factory']; $route = $app['controllers_factory'];
$route->get('{repo}/network/{commitishPath}/{page}.json', $route->get(
'{repo}/network/{commitishPath}/{page}.json',
function ($repo, $commitishPath, $page) use ($app) { function ($repo, $commitishPath, $page) use ($app) {
/** @var $repository Repository */ /** @var $repository Repository */
$repository = $app['git']->getRepositoryFromName($app['git.repos'], $repo); $repository = $app['git']->getRepositoryFromName($app['git.repos'], $repo);
@@ -26,29 +26,29 @@ class NetworkController implements ControllerProviderInterface
$pager = $app['util.view']->getPager($page, $repository->getTotalCommits($commitishPath)); $pager = $app['util.view']->getPager($page, $repository->getTotalCommits($commitishPath));
$commits = $repository->getPaginatedCommits($commitishPath, $pager['current']); $commits = $repository->getPaginatedCommits($commitishPath, $pager['current']);
$jsonFormattedCommits = array(); $jsonFormattedCommits = [];
foreach ($commits as $commit) { foreach ($commits as $commit) {
$detailsUrl = $app['url_generator']->generate( $detailsUrl = $app['url_generator']->generate(
'commit', 'commit',
array( [
'repo' => $repo, 'repo' => $repo,
'commit' => $commit->getHash() 'commit' => $commit->getHash(),
) ]
); );
$jsonFormattedCommits[$commit->getHash()] = array( $jsonFormattedCommits[$commit->getHash()] = [
'hash' => $commit->getHash(), 'hash' => $commit->getHash(),
'parentsHash' => $commit->getParentsHash(), 'parentsHash' => $commit->getParentsHash(),
'date' => $commit->getDate()->format('U'), 'date' => $commit->getDate()->format('U'),
'message' => htmlentities($commit->getMessage()), 'message' => htmlentities($commit->getMessage()),
'details' => $detailsUrl, 'details' => $detailsUrl,
'author' => array( 'author' => [
'name' => $commit->getAuthor()->getName(), 'name' => $commit->getAuthor()->getName(),
'email' => $commit->getAuthor()->getEmail(), 'email' => $commit->getAuthor()->getEmail(),
'image' => $app->getAvatar($commit->getAuthor()->getEmail(), 40) 'image' => $app->getAvatar($commit->getAuthor()->getEmail(), 40),
) ],
); ];
} }
$nextPageUrl = null; $nextPageUrl = null;
@@ -56,34 +56,37 @@ class NetworkController implements ControllerProviderInterface
if ($pager['last'] !== $pager['current']) { if ($pager['last'] !== $pager['current']) {
$nextPageUrl = $app['url_generator']->generate( $nextPageUrl = $app['url_generator']->generate(
'networkData', 'networkData',
array( [
'repo' => $repo, 'repo' => $repo,
'commitishPath' => $commitishPath, 'commitishPath' => $commitishPath,
'page' => $pager['next'] 'page' => $pager['next'],
) ]
); );
} }
// when no commits are given, return an empty response - issue #369 // when no commits are given, return an empty response - issue #369
if (count($commits) === 0) { if (count($commits) === 0) {
return $app->json( return $app->json(
array( [
'repo' => $repo, 'repo' => $repo,
'commitishPath' => $commitishPath, 'commitishPath' => $commitishPath,
'nextPage' => null, 'nextPage' => null,
'start' => null, 'start' => null,
'commits' => $jsonFormattedCommits 'commits' => $jsonFormattedCommits,
), 200 ],
200
); );
} }
return $app->json( array( return $app->json(
[
'repo' => $repo, 'repo' => $repo,
'commitishPath' => $commitishPath, 'commitishPath' => $commitishPath,
'nextPage' => $nextPageUrl, 'nextPage' => $nextPageUrl,
'start' => $commits[0]->getHash(), 'start' => $commits[0]->getHash(),
'commits' => $jsonFormattedCommits 'commits' => $jsonFormattedCommits,
), 200 ],
200
); );
} }
)->assert('repo', $app['util.routing']->getRepositoryRegex()) )->assert('repo', $app['util.routing']->getRepositoryRegex())
@@ -108,11 +111,11 @@ class NetworkController implements ControllerProviderInterface
return $app['twig']->render( return $app['twig']->render(
'network.twig', 'network.twig',
array( [
'repo' => $repo, 'repo' => $repo,
'branch' => $branch, 'branch' => $branch,
'commitishPath' => $commitishPath, 'commitishPath' => $commitishPath,
) ]
); );
} }
)->assert('repo', $app['util.routing']->getRepositoryRegex()) )->assert('repo', $app['util.routing']->getRepositoryRegex())

View File

@@ -2,10 +2,10 @@
namespace GitList\Controller; namespace GitList\Controller;
use Silex\Api\ControllerProviderInterface;
use Silex\Application; use Silex\Application;
use Silex\ControllerProviderInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\BinaryFileResponse; use Symfony\Component\HttpFoundation\BinaryFileResponse;
use Symfony\Component\HttpFoundation\Request;
class TreeController implements ControllerProviderInterface class TreeController implements ControllerProviderInterface
{ {
@@ -32,7 +32,7 @@ class TreeController implements ControllerProviderInterface
$parent = ''; $parent = '';
} }
return $app['twig']->render('tree.twig', array( return $app['twig']->render('tree.twig', [
'files' => $files->output(), 'files' => $files->output(),
'repo' => $repo, 'repo' => $repo,
'branch' => $branch, 'branch' => $branch,
@@ -41,8 +41,8 @@ class TreeController implements ControllerProviderInterface
'breadcrumbs' => $breadcrumbs, 'breadcrumbs' => $breadcrumbs,
'branches' => $repository->getBranches(), 'branches' => $repository->getBranches(),
'tags' => $repository->getTags(), 'tags' => $repository->getTags(),
'readme' => $app['util.repository']->getReadme($repository, $branch, $tree ? "$tree" : ""), 'readme' => $app['util.repository']->getReadme($repository, $branch, $tree ? "$tree" : ''),
)); ]);
})->assert('repo', $app['util.routing']->getRepositoryRegex()) })->assert('repo', $app['util.routing']->getRepositoryRegex())
->assert('commitishPath', $app['util.routing']->getCommitishPathRegex()) ->assert('commitishPath', $app['util.routing']->getCommitishPathRegex())
->convert('commitishPath', 'escaper.argument:escape') ->convert('commitishPath', 'escaper.argument:escape')
@@ -55,10 +55,10 @@ class TreeController implements ControllerProviderInterface
} }
$query = $request->get('query'); $query = $request->get('query');
$breadcrumbs = array(array('dir' => 'Search results for: ' . $query, 'path' => '')); $breadcrumbs = [['dir' => 'Search results for: ' . $query, 'path' => '']];
$results = $repository->searchTree($query, $branch); $results = $repository->searchTree($query, $branch);
return $app['twig']->render('search.twig', array( return $app['twig']->render('search.twig', [
'results' => $results, 'results' => $results,
'repo' => $repo, 'repo' => $repo,
'branch' => $branch, 'branch' => $branch,
@@ -66,8 +66,8 @@ class TreeController implements ControllerProviderInterface
'breadcrumbs' => $breadcrumbs, 'breadcrumbs' => $breadcrumbs,
'branches' => $repository->getBranches(), 'branches' => $repository->getBranches(),
'tags' => $repository->getTags(), 'tags' => $repository->getTags(),
'query' => $query 'query' => $query,
)); ]);
})->assert('repo', $app['util.routing']->getRepositoryRegex()) })->assert('repo', $app['util.routing']->getRepositoryRegex())
->assert('branch', $app['util.routing']->getBranchRegex()) ->assert('branch', $app['util.routing']->getBranchRegex())
->convert('branch', 'escaper.argument:escape') ->convert('branch', 'escaper.argument:escape')
@@ -95,7 +95,7 @@ class TreeController implements ControllerProviderInterface
/** /**
* Generating name for downloading, lowercasing and removing all non * Generating name for downloading, lowercasing and removing all non
* ascii and special characters * ascii and special characters.
*/ */
$filename = strtolower($repo . '_' . $branch); $filename = strtolower($repo . '_' . $branch);
$filename = preg_replace('#[^a-z0-9]+#', '_', $filename); $filename = preg_replace('#[^a-z0-9]+#', '_', $filename);
@@ -103,6 +103,7 @@ class TreeController implements ControllerProviderInterface
$response = new BinaryFileResponse($file); $response = new BinaryFileResponse($file);
$response->setContentDisposition('attachment', $filename); $response->setContentDisposition('attachment', $filename);
return $response; return $response;
})->assert('format', '(zip|tar)') })->assert('format', '(zip|tar)')
->assert('repo', $app['util.routing']->getRepositoryRegex()) ->assert('repo', $app['util.routing']->getRepositoryRegex())
@@ -110,7 +111,6 @@ class TreeController implements ControllerProviderInterface
->convert('branch', 'escaper.argument:escape') ->convert('branch', 'escaper.argument:escape')
->bind('archive'); ->bind('archive');
$route->get('{repo}/{branch}/', function ($repo, $branch) use ($app, $treeController) { $route->get('{repo}/{branch}/', function ($repo, $branch) use ($app, $treeController) {
return $treeController($repo, $branch); return $treeController($repo, $branch);
})->assert('repo', $app['util.routing']->getRepositoryRegex()) })->assert('repo', $app['util.routing']->getRepositoryRegex())
@@ -126,4 +126,3 @@ class TreeController implements ControllerProviderInterface
return $route; return $route;
} }
} }

View File

@@ -2,9 +2,8 @@
namespace GitList\Controller; namespace GitList\Controller;
use Silex\Api\ControllerProviderInterface;
use Silex\Application; use Silex\Application;
use Silex\ControllerProviderInterface;
use Symfony\Component\HttpFoundation\Request;
class TreeGraphController implements ControllerProviderInterface class TreeGraphController implements ControllerProviderInterface
{ {
@@ -22,26 +21,26 @@ class TreeGraphController implements ControllerProviderInterface
'--pretty=format:"B[%d] C[%H] D[%ad] A[%an] E[%ae] H[%h] S[%s]"'; '--pretty=format:"B[%d] C[%H] D[%ad] A[%an] E[%ae] H[%h] S[%s]"';
$rawRows = $repository->getClient()->run($repository, $command); $rawRows = $repository->getClient()->run($repository, $command);
$rawRows = explode("\n", $rawRows); $rawRows = explode("\n", $rawRows);
$graphItems = array(); $graphItems = [];
foreach ($rawRows as $row) { foreach ($rawRows as $row) {
if (preg_match("/^(.+?)(\s(B\[(.*?)\])? C\[(.+?)\] D\[(.+?)\] A\[(.+?)\] E\[(.+?)\] H\[(.+?)\] S\[(.+?)\])?$/", $row, $output)) { if (preg_match("/^(.+?)(\s(B\[(.*?)\])? C\[(.+?)\] D\[(.+?)\] A\[(.+?)\] E\[(.+?)\] H\[(.+?)\] S\[(.+?)\])?$/", $row, $output)) {
if (!isset($output[4])) { if (!isset($output[4])) {
$graphItems[] = array( $graphItems[] = [
"relation"=>$output[1] 'relation' => $output[1],
); ];
continue; continue;
} }
$graphItems[] = array( $graphItems[] = [
"relation"=>$output[1], 'relation' => $output[1],
"branch"=>$output[4], 'branch' => $output[4],
"rev"=>$output[5], 'rev' => $output[5],
"date"=>$output[6], 'date' => $output[6],
"author"=>$output[7], 'author' => $output[7],
"author_email"=>$output[8], 'author_email' => $output[8],
"short_rev"=>$output[9], 'short_rev' => $output[9],
"subject"=>preg_replace('/(^|\s)(#[[:xdigit:]]+)(\s|$)/', '$1<a href="$2">$2</a>$3', $output[10]) 'subject' => preg_replace('/(^|\s)(#[[:xdigit:]]+)(\s|$)/', '$1<a href="$2">$2</a>$3', $output[10]),
); ];
} }
} }
@@ -54,12 +53,12 @@ class TreeGraphController implements ControllerProviderInterface
return $app['twig']->render( return $app['twig']->render(
'treegraph.twig', 'treegraph.twig',
array( [
'repo' => $repo, 'repo' => $repo,
'branch' => $branch, 'branch' => $branch,
'commitishPath' => $commitishPath, 'commitishPath' => $commitishPath,
'graphItems' => $graphItems, 'graphItems' => $graphItems,
) ]
); );
} }
)->assert('repo', $app['util.routing']->getRepositoryRegex()) )->assert('repo', $app['util.routing']->getRepositoryRegex())

View File

@@ -4,5 +4,4 @@ namespace GitList\Exception;
class BlankDataException extends \RuntimeException class BlankDataException extends \RuntimeException
{ {
} }

View File

@@ -4,5 +4,4 @@ namespace GitList\Exception;
class EmptyRepositoryException extends \RuntimeException class EmptyRepositoryException extends \RuntimeException
{ {
} }

View File

@@ -27,15 +27,16 @@ class Client extends BaseClient
} }
/** /**
* Searches for valid repositories on the specified path * Searches for valid repositories on the specified path.
* *
* @param array $paths Array of paths where repositories will be searched * @param array $paths Array of paths where repositories will be searched
*
* @return array Found repositories, containing their name, path and description sorted * @return array Found repositories, containing their name, path and description sorted
* by repository name * by repository name
*/ */
public function getRepositories($paths) public function getRepositories($paths)
{ {
$allRepositories = array(); $allRepositories = [];
foreach ($paths as $path) { foreach ($paths as $path) {
$repositories = $this->recurseDirectory($path); $repositories = $this->recurseDirectory($path);
@@ -45,7 +46,7 @@ class Client extends BaseClient
} }
/** /**
* Use "+" to preserve keys, only a problem with numeric repos * Use "+" to preserve keys, only a problem with numeric repos.
*/ */
$allRepositories = $allRepositories + $repositories; $allRepositories = $allRepositories + $repositories;
} }
@@ -58,11 +59,109 @@ class Client extends BaseClient
return $allRepositories; return $allRepositories;
} }
/**
* Return name of default branch as a string.
*/
public function getDefaultBranch()
{
return $this->defaultBranch;
}
/**
* 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);
}
/**
* Set default branch as a string.
*
* @param string $branch name of branch to use when repo's HEAD is detached
*
* @return object
*/
protected function setDefaultBranch($branch)
{
$this->defaultBranch = $branch;
return $this;
}
/**
* 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
*
* @return object
*/
protected function setHidden($hidden)
{
$this->hidden = $hidden;
return $this;
}
/**
* Get project list.
*
* @return array List of repositories to show
*/
protected function getProjects()
{
return $this->projects;
}
/**
* Set the shown repository list.
*
* @param array $projects List of repositories to show
*/
protected function setProjects($projects)
{
$this->projects = $projects;
return $this;
}
private function recurseDirectory($path, $topLevel = true) private function recurseDirectory($path, $topLevel = true)
{ {
$dir = new \DirectoryIterator($path); $dir = new \DirectoryIterator($path);
$repositories = array(); $repositories = [];
foreach ($dir as $file) { foreach ($dir as $file) {
if ($file->isDot()) { if ($file->isDot()) {
@@ -82,9 +181,7 @@ class Client extends BaseClient
$isRepository = file_exists($file->getPathname() . '/.git/HEAD'); $isRepository = file_exists($file->getPathname() . '/.git/HEAD');
if ($isRepository || $isBare) { if ($isRepository || $isBare) {
$hidden = function ($path, $hide) { $hidden = function ($path, $hide) {
$return = false; $return = false;
array_walk($hide, function ($value, $key) use ($path, &$return) { array_walk($hide, function ($value, $key) use ($path, &$return) {
@@ -92,6 +189,7 @@ class Client extends BaseClient
$return = true; $return = true;
} }
}); });
return $return; return $return;
}; };
@@ -121,116 +219,18 @@ class Client extends BaseClient
continue; continue;
} }
$repositories[$repoName] = array( $repositories[$repoName] = [
'name' => $repoName, 'name' => $repoName,
'path' => $file->getPathname(), 'path' => $file->getPathname(),
'description' => $description 'description' => $description,
); ];
continue; continue;
} else {
$repositories = array_merge($repositories, $this->recurseDirectory($file->getPathname(), false));
} }
$repositories = array_merge($repositories, $this->recurseDirectory($file->getPathname(), false));
} }
} }
return $repositories; return $repositories;
} }
/**
* Set default branch as a string.
*
* @param string $branch Name of branch to use when repo's HEAD is detached.
* @return object
*/
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
* @return object
*/
protected function setHidden($hidden)
{
$this->hidden = $hidden;
return $this;
}
/**
* Get project list
*
* @return array List of repositories to show
*/
protected function getProjects()
{
return $this->projects;
}
/**
* Set the shown repository list
*
* @param array $projects List of repositories to show
*/
protected function setProjects($projects)
{
$this->projects = $projects;
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);
}
}

View File

@@ -2,10 +2,10 @@
namespace GitList\Git; namespace GitList\Git;
use Gitter\Repository as BaseRepository;
use Gitter\Model\Commit\Commit; use Gitter\Model\Commit\Commit;
use Gitter\Model\Commit\Diff; use Gitter\Model\Commit\Diff;
use Gitter\PrettyFormat; use Gitter\PrettyFormat;
use Gitter\Repository as BaseRepository;
use Symfony\Component\Filesystem\Filesystem; use Symfony\Component\Filesystem\Filesystem;
class Repository extends BaseRepository class Repository extends BaseRepository
@@ -14,7 +14,8 @@ class Repository extends BaseRepository
* Return true if the repo contains this commit. * Return true if the repo contains this commit.
* *
* @param $commitHash Hash of commit whose existence we want to check * @param $commitHash Hash of commit whose existence we want to check
* @return boolean Whether or not the commit exists in this repo *
* @return bool Whether or not the commit exists in this repo
*/ */
public function hasCommit($commitHash) public function hasCommit($commitHash)
{ {
@@ -27,7 +28,7 @@ class Repository extends BaseRepository
/** /**
* Get the current branch, returning a default value when HEAD is detached. * Get the current branch, returning a default value when HEAD is detached.
*/ */
public function getHead($default = NULL) public function getHead($default = null)
{ {
$client = $this->getClient(); $client = $this->getClient();
@@ -35,26 +36,28 @@ class Repository extends BaseRepository
} }
/** /**
* Show Patches that where apllied to the selected file * Show Patches that where apllied to the selected file.
* *
* @param string $file File path for which we will retrieve a list of patch logs * @param string $file File path for which we will retrieve a list of patch logs
*
* @return array Collection of Commits data * @return array Collection of Commits data
*/ */
public function getCommitsLogPatch($file) public function getCommitsLogPatch($file)
{ {
$record_delimiter = chr(hexdec("0x1e")); $record_delimiter = chr(hexdec('0x1e'));
$file_patches = $this->getClient()->run($this, $file_patches = $this->getClient()->run(
"log -p --pretty=format:\"".$record_delimiter."<item><hash>%H</hash>" $this,
. "<short_hash>%h</short_hash><tree>%T</tree><parents>%P</parents>" 'log -p --pretty=format:"' . $record_delimiter . '<item><hash>%H</hash>'
. "<author>%aN</author><author_email>%aE</author_email>" . '<short_hash>%h</short_hash><tree>%T</tree><parents>%P</parents>'
. "<date>%at</date><commiter>%cN</commiter><commiter_email>%cE</commiter_email>" . '<author>%aN</author><author_email>%aE</author_email>'
. "<commiter_date>%ct</commiter_date>" . '<date>%at</date><commiter>%cN</commiter><commiter_email>%cE</commiter_email>'
. "<message><![CDATA[%s]]></message>" . '<commiter_date>%ct</commiter_date>'
. "<body><![CDATA[%b]]></body>" . '<message><![CDATA[%s]]></message>'
. '<body><![CDATA[%b]]></body>'
. "</item>\" $file" . "</item>\" $file"
); );
$patch_collection = array(); $patch_collection = [];
foreach (preg_split('/(' . $record_delimiter . '\<item\>)/', $file_patches, null, PREG_SPLIT_NO_EMPTY) as $patches) { foreach (preg_split('/(' . $record_delimiter . '\<item\>)/', $file_patches, null, PREG_SPLIT_NO_EMPTY) as $patches) {
$patches = '<item>' . $patches; $patches = '<item>' . $patches;
$xmlEnd = strpos($patches, '</item>') + 7; $xmlEnd = strpos($patches, '</item>') + 7;
@@ -63,9 +66,9 @@ class Repository extends BaseRepository
$logs = explode("\n", $commitData); $logs = explode("\n", $commitData);
// Read commit metadata // Read commit metadata
$format = new PrettyFormat; $format = new PrettyFormat();
$data = $format->parse($commitInfo); $data = $format->parse($commitInfo);
$commit = new Commit; $commit = new Commit();
$commit->importData($data[0]); $commit->importData($data[0]);
$commit->setDiffs($this->readDiffLogs($logs)); $commit->setDiffs($this->readDiffLogs($logs));
$patch_collection[] = $commit; $patch_collection[] = $commit;
@@ -75,21 +78,23 @@ class Repository extends BaseRepository
} }
/** /**
* Show the data from a specific commit * Show the data from a specific commit.
* *
* @param string $commitHash Hash of the specific commit to read data * @param string $commitHash Hash of the specific commit to read data
*
* @return array Commit data * @return array Commit data
*/ */
public function getCommit($commitHash) public function getCommit($commitHash)
{ {
$logs = $this->getClient()->run($this, $logs = $this->getClient()->run(
"show --pretty=format:\"<item><hash>%H</hash>" $this,
. "<short_hash>%h</short_hash><tree>%T</tree><parents>%P</parents>" 'show --pretty=format:"<item><hash>%H</hash>'
. "<author>%aN</author><author_email>%aE</author_email>" . '<short_hash>%h</short_hash><tree>%T</tree><parents>%P</parents>'
. "<date>%at</date><commiter>%cN</commiter><commiter_email>%cE</commiter_email>" . '<author>%aN</author><author_email>%aE</author_email>'
. "<commiter_date>%ct</commiter_date>" . '<date>%at</date><commiter>%cN</commiter><commiter_email>%cE</commiter_email>'
. "<message><![CDATA[%s]]></message>" . '<commiter_date>%ct</commiter_date>'
. "<body><![CDATA[%b]]></body>" . '<message><![CDATA[%s]]></message>'
. '<body><![CDATA[%b]]></body>'
. "</item>\" $commitHash" . "</item>\" $commitHash"
); );
@@ -99,9 +104,9 @@ class Repository extends BaseRepository
$logs = explode("\n", $commitData); $logs = explode("\n", $commitData);
// Read commit metadata // Read commit metadata
$format = new PrettyFormat; $format = new PrettyFormat();
$data = $format->parse($commitInfo); $data = $format->parse($commitInfo);
$commit = new Commit; $commit = new Commit();
$commit->importData($data[0]); $commit->importData($data[0]);
if ($commit->getParentsHash()) { if ($commit->getParentsHash()) {
@@ -115,14 +120,15 @@ class Repository extends BaseRepository
} }
/** /**
* Blames the provided file and parses the output * Blames the provided file and parses the output.
* *
* @param string $file File that will be blamed * @param string $file File that will be blamed
*
* @return array Commits hashes containing the lines * @return array Commits hashes containing the lines
*/ */
public function getBlame($file) public function getBlame($file)
{ {
$blame = array(); $blame = [];
$logs = $this->getClient()->run($this, "blame --root -sl $file"); $logs = $this->getClient()->run($this, "blame --root -sl $file");
$logs = explode("\n", $logs); $logs = explode("\n", $logs);
@@ -138,11 +144,11 @@ class Repository extends BaseRepository
$currentCommit = $match[1][0]; $currentCommit = $match[1][0];
if ($currentCommit != $previousCommit) { if ($currentCommit != $previousCommit) {
++$i; ++$i;
$blame[$i] = array( $blame[$i] = [
'line' => '', 'line' => '',
'commit' => $currentCommit, 'commit' => $currentCommit,
'commitShort' => substr($currentCommit, 0, 8) 'commitShort' => substr($currentCommit, 0, 8),
); ];
} }
$blame[$i]['line'] .= $match[3][0] . PHP_EOL; $blame[$i]['line'] .= $match[3][0] . PHP_EOL;
@@ -153,19 +159,20 @@ class Repository extends BaseRepository
} }
/** /**
* Read diff logs and generate a collection of diffs * Read diff logs and generate a collection of diffs.
* *
* @param array $logs Array of log rows * @param array $logs Array of log rows
*
* @return array Array of diffs * @return array Array of diffs
*/ */
public function readDiffLogs(array $logs) public function readDiffLogs(array $logs)
{ {
$diffs = array(); $diffs = [];
$lineNumOld = 0; $lineNumOld = 0;
$lineNumNew = 0; $lineNumNew = 0;
foreach ($logs as $log) { foreach ($logs as $log) {
# Skip empty lines // Skip empty lines
if ($log == "") { if ($log == '') {
continue; continue;
} }
@@ -174,7 +181,7 @@ class Repository extends BaseRepository
$diffs[] = $diff; $diffs[] = $diff;
} }
$diff = new Diff; $diff = new Diff();
if (preg_match('/^diff --[\S]+ a\/?(.+) b\/?/', $log, $name)) { if (preg_match('/^diff --[\S]+ a\/?(.+) b\/?/', $log, $name)) {
$diff->setFile($name[1]); $diff->setFile($name[1]);
} }
@@ -198,7 +205,7 @@ class Repository extends BaseRepository
// Handle binary files properly. // Handle binary files properly.
if ('Binary' === substr($log, 0, 6)) { if ('Binary' === substr($log, 0, 6)) {
$m = array(); $m = [];
if (preg_match('/Binary files (.+) and (.+) differ/', $log, $m)) { if (preg_match('/Binary files (.+) and (.+) differ/', $log, $m)) {
$diff->setOld($m[1]); $diff->setOld($m[1]);
$diff->setNew(" {$m[2]}"); $diff->setNew(" {$m[2]}");
@@ -207,16 +214,16 @@ class Repository extends BaseRepository
if (!empty($log)) { if (!empty($log)) {
switch ($log[0]) { switch ($log[0]) {
case "@": case '@':
// Set the line numbers // Set the line numbers
preg_match('/@@ -([0-9]+)(?:,[0-9]+)? \+([0-9]+)/', $log, $matches); preg_match('/@@ -([0-9]+)(?:,[0-9]+)? \+([0-9]+)/', $log, $matches);
$lineNumOld = $matches[1] - 1; $lineNumOld = $matches[1] - 1;
$lineNumNew = $matches[2] - 1; $lineNumNew = $matches[2] - 1;
break; break;
case "-": case '-':
$lineNumOld++; $lineNumOld++;
break; break;
case "+": case '+':
$lineNumNew++; $lineNumNew++;
break; break;
default: default:
@@ -241,11 +248,11 @@ class Repository extends BaseRepository
} }
/** /**
* Show the repository commit log with pagination * Show the repository commit log with pagination.
* *
* @access public
* @param string $file * @param string $file
* @param int page * @param int page
*
* @return array Commit log * @return array Commit log
*/ */
public function getPaginatedCommits($file = null, $page = 0) public function getPaginatedCommits($file = null, $page = 0)
@@ -254,12 +261,12 @@ class Repository extends BaseRepository
$pager = "--skip=$page --max-count=15"; $pager = "--skip=$page --max-count=15";
$command = $command =
"log $pager --pretty=format:\"<item><hash>%H</hash>" "log $pager --pretty=format:\"<item><hash>%H</hash>"
. "<short_hash>%h</short_hash><tree>%T</tree><parents>%P</parents>" . '<short_hash>%h</short_hash><tree>%T</tree><parents>%P</parents>'
. "<author>%aN</author><author_email>%aE</author_email>" . '<author>%aN</author><author_email>%aE</author_email>'
. "<date>%at</date><commiter>%cN</commiter>" . '<date>%at</date><commiter>%cN</commiter>'
. "<commiter_email>%cE</commiter_email>" . '<commiter_email>%cE</commiter_email>'
. "<commiter_date>%ct</commiter_date>" . '<commiter_date>%ct</commiter_date>'
. "<message><![CDATA[%s]]></message></item>\""; . '<message><![CDATA[%s]]></message></item>"';
if ($file) { if ($file) {
$command .= " $file"; $command .= " $file";
@@ -268,11 +275,11 @@ class Repository extends BaseRepository
try { try {
$logs = $this->getPrettyFormat($command); $logs = $this->getPrettyFormat($command);
} catch (\RuntimeException $e) { } catch (\RuntimeException $e) {
return array(); return [];
} }
foreach ($logs as $log) { foreach ($logs as $log) {
$commit = new Commit; $commit = new Commit();
$commit->importData($log); $commit->importData($log);
$commits[] = $commit; $commits[] = $commit;
} }
@@ -283,25 +290,25 @@ class Repository extends BaseRepository
public function searchCommitLog($query, $branch) public function searchCommitLog($query, $branch)
{ {
$query = escapeshellarg($query); $query = escapeshellarg($query);
$query = strtr($query, array('[' => '\\[', ']' => '\\]')); $query = strtr($query, ['[' => '\\[', ']' => '\\]']);
$command = $command =
"log --grep={$query} -i --pretty=format:\"<item><hash>%H</hash>" "log --grep={$query} -i --pretty=format:\"<item><hash>%H</hash>"
. "<short_hash>%h</short_hash><tree>%T</tree><parents>%P</parents>" . '<short_hash>%h</short_hash><tree>%T</tree><parents>%P</parents>'
. "<author>%aN</author><author_email>%aE</author_email>" . '<author>%aN</author><author_email>%aE</author_email>'
. "<date>%at</date><commiter>%cN</commiter>" . '<date>%at</date><commiter>%cN</commiter>'
. "<commiter_email>%cE</commiter_email>" . '<commiter_email>%cE</commiter_email>'
. "<commiter_date>%ct</commiter_date>" . '<commiter_date>%ct</commiter_date>'
. "<message><![CDATA[%s]]></message></item>\"" . '<message><![CDATA[%s]]></message></item>"'
. " $branch"; . " $branch";
try { try {
$logs = $this->getPrettyFormat($command); $logs = $this->getPrettyFormat($command);
} catch (\RuntimeException $e) { } catch (\RuntimeException $e) {
return array(); return [];
} }
foreach ($logs as $log) { foreach ($logs as $log) {
$commit = new Commit; $commit = new Commit();
$commit->importData($log); $commit->importData($log);
$commits[] = $commit; $commits[] = $commit;
} }
@@ -357,7 +364,7 @@ class Repository extends BaseRepository
foreach ($logs as $user => $count) { foreach ($logs as $user => $count) {
$user = explode('||', $user); $user = explode('||', $user);
$data[] = array('name' => $user[0], 'email' => $user[1], 'commits' => $count); $data[] = ['name' => $user[0], 'email' => $user[1], 'commits' => $count];
} }
return $data; return $data;
@@ -368,8 +375,8 @@ class Repository extends BaseRepository
// Calculate amount of files, extensions and file size // Calculate amount of files, extensions and file size
$logs = $this->getClient()->run($this, 'ls-tree -r -l ' . $branch); $logs = $this->getClient()->run($this, 'ls-tree -r -l ' . $branch);
$lines = explode("\n", $logs); $lines = explode("\n", $logs);
$files = array(); $files = [];
$data['extensions'] = array(); $data['extensions'] = [];
$data['size'] = 0; $data['size'] = 0;
$data['files'] = 0; $data['files'] = 0;
@@ -411,7 +418,7 @@ class Repository extends BaseRepository
} }
/** /**
* Create a TAR or ZIP archive of a git tree * Create a TAR or ZIP archive of a git tree.
* *
* @param string $tree Tree-ish reference * @param string $tree Tree-ish reference
* @param string $output Output File name * @param string $output Output File name
@@ -419,7 +426,7 @@ class Repository extends BaseRepository
*/ */
public function createArchive($tree, $output, $format = 'zip') public function createArchive($tree, $output, $format = 'zip')
{ {
$fs = new Filesystem; $fs = new Filesystem();
$fs->mkdir(dirname($output)); $fs->mkdir(dirname($output));
$this->getClient()->run($this, "archive --format=$format --output='$output' $tree"); $this->getClient()->run($this, "archive --format=$format --output='$output' $tree");
} }
@@ -427,8 +434,9 @@ class Repository extends BaseRepository
/** /**
* Return true if $path exists in $branch; return false otherwise. * Return true if $path exists in $branch; return false otherwise.
* *
* @param string $commitish Commitish reference; branch, tag, SHA1, etc. * @param string $commitish commitish reference; branch, tag, SHA1, etc
* @param string $path Path whose existence we want to verify. * @param string $path path whose existence we want to verify
*
* @return bool * @return bool
* *
* GRIPE Arguably belongs in Gitter, as it's generally useful functionality. * GRIPE Arguably belongs in Gitter, as it's generally useful functionality.
@@ -445,4 +453,3 @@ class Repository extends BaseRepository
return false; return false;
} }
} }

View File

@@ -3,32 +3,21 @@
namespace GitList\Provider; namespace GitList\Provider;
use GitList\Git\Client; use GitList\Git\Client;
use Silex\Application; use Pimple\Container;
use Silex\ServiceProviderInterface; use Pimple\ServiceProviderInterface;
class GitServiceProvider implements ServiceProviderInterface class GitServiceProvider implements ServiceProviderInterface
{ {
public function register(Container $container)
/**
* 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) { $container['git'] = function () use ($container) {
$options['path'] = $app['git.client']; $options['path'] = $container['git.client'];
$options['hidden'] = $app['git.hidden']; $options['hidden'] = $container['git.hidden'];
$options['projects'] = $app['git.projects']; $options['projects'] = $container['git.projects'];
$options['ini.file'] = $app['ini.file']; $options['ini.file'] = $container['ini.file'];
$options['default_branch'] = $app['git.default_branch']; $options['default_branch'] = $container['git.default_branch'];
return new Client($options); return new Client($options);
}; };
} }
public function boot(Application $app)
{
}
} }

View File

@@ -3,24 +3,15 @@
namespace GitList\Provider; namespace GitList\Provider;
use GitList\Util\Repository; use GitList\Util\Repository;
use Silex\Application; use Pimple\Container;
use Silex\ServiceProviderInterface; use Pimple\ServiceProviderInterface;
class RepositoryUtilServiceProvider implements ServiceProviderInterface class RepositoryUtilServiceProvider implements ServiceProviderInterface
{ {
/** public function register(Container $container)
* 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)
{ {
$container['util.repository'] = function () use ($container) {
return new Repository($container);
};
} }
} }

View File

@@ -3,24 +3,15 @@
namespace GitList\Provider; namespace GitList\Provider;
use GitList\Util\Routing; use GitList\Util\Routing;
use Silex\Application; use Pimple\Container;
use Silex\ServiceProviderInterface; use Pimple\ServiceProviderInterface;
class RoutingUtilServiceProvider implements ServiceProviderInterface class RoutingUtilServiceProvider implements ServiceProviderInterface
{ {
/** public function register(Container $container)
* 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)
{ {
$container['util.routing'] = function () use ($container) {
return new Routing($container);
};
} }
} }

View File

@@ -3,24 +3,15 @@
namespace GitList\Provider; namespace GitList\Provider;
use GitList\Util\View; use GitList\Util\View;
use Silex\Application; use Pimple\Container;
use Silex\ServiceProviderInterface; use Pimple\ServiceProviderInterface;
class ViewUtilServiceProvider implements ServiceProviderInterface class ViewUtilServiceProvider implements ServiceProviderInterface
{ {
/** public function register(Container $container)
* 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)
{ {
$container['util.view'] = function () {
return new View();
};
} }
} }

View File

@@ -8,7 +8,7 @@ class Repository
{ {
protected $app; protected $app;
protected $defaultFileTypes = array( protected $defaultFileTypes = [
'php' => 'php', 'php' => 'php',
'c' => 'clike', 'c' => 'clike',
'h' => 'clike', 'h' => 'clike',
@@ -94,14 +94,14 @@ class Repository
'jpeg' => 'image', 'jpeg' => 'image',
'bmp' => 'image', 'bmp' => 'image',
'csproj' => 'xml', 'csproj' => 'xml',
); ];
protected static $binaryTypes = array( protected static $binaryTypes = [
'exe', 'com', 'so', 'la', 'o', 'dll', 'pyc', 'exe', 'com', 'so', 'la', 'o', 'dll', 'pyc',
'jpg', 'jpeg', 'bmp', 'gif', 'png', 'xmp', 'pcx', 'svgz', 'ttf', 'tiff', 'oet', 'jpg', 'jpeg', 'bmp', 'gif', 'png', 'xmp', 'pcx', 'svgz', 'ttf', 'tiff', 'oet',
'gz', 'tar', 'rar', 'zip', '7z', 'jar', 'class', 'gz', 'tar', 'rar', 'zip', '7z', 'jar', 'class',
'odt', 'ods', 'pdf', 'doc', 'docx', 'dot', 'xls', 'xlsx', 'odt', 'ods', 'pdf', 'doc', 'docx', 'dot', 'xls', 'xlsx',
); ];
public function __construct(Application $app) public function __construct(Application $app)
{ {
@@ -109,12 +109,13 @@ class Repository
} }
/** /**
* Returns the file type based on filename by treating the extension * Returns the file type based on filename by treating the extension.
* *
* The file type is used by CodeMirror, a Javascript-based IDE implemented in * 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) * GitList, to properly highlight the blob syntax (if it's a source-code)
* *
* @param string $file File name * @param string $file File name
*
* @return mixed File type * @return mixed File type
*/ */
public function getFileType($file) public function getFileType($file)
@@ -143,7 +144,7 @@ class Repository
* *
* @param string $file * @param string $file
* *
* @return boolean * @return bool
*/ */
public function isBinary($file) public function isBinary($file)
{ {
@@ -164,35 +165,41 @@ class Repository
return false; return false;
} }
public function getReadme($repository, $branch = null, $path = "") public function getReadme($repository, $branch = null, $path = '')
{ {
if ($branch === null) { if ($branch === null) {
$branch = $repository->getHead(); $branch = $repository->getHead();
} }
if ($path != "") $path = "$path/"; if ($path != '') {
$path = "$path/";
}
$files = $repository->getTree($path != "" ? "$branch:\"$path\"" : $branch)->output(); $files = $repository->getTree($path != '' ? "$branch:\"$path\"" : $branch)->output();
foreach ($files as $file) { foreach ($files as $file) {
if (preg_match('/^readme*/i', $file['name'])) { if (preg_match('/^readme*/i', $file['name'])) {
return array( return [
'filename' => $file['name'], 'filename' => $file['name'],
'content' => $repository->getBlob("$branch:\"$path{$file['name']}\"")->output() 'content' => $repository->getBlob("$branch:\"$path{$file['name']}\"")->output(),
); ];
} }
} }
// No contextual readme, try to catch the main one if we are in deeper context // No contextual readme, try to catch the main one if we are in deeper context
if ($path != "") return $this->getReadme($repository, $branch, ""); if ($path != '') {
return array(); return $this->getReadme($repository, $branch, '');
}
return [];
} }
/** /**
* Returns an Array where the first value is the tree-ish and the second is the path * Returns an Array where the first value is the tree-ish and the second is the path.
* *
* @param \GitList\Git\Repository $repository * @param \GitList\Git\Repository $repository
* @param string $branch * @param string $branch
* @param string $tree * @param string $tree
*
* @return array * @return array
*/ */
public function extractRef($repository, $branch = '', $tree = '') public function extractRef($repository, $branch = '', $tree = '')
@@ -202,13 +209,13 @@ class Repository
$input = $branch . '/' . $tree; $input = $branch . '/' . $tree;
// If the ref appears to be a SHA, just split the string // If the ref appears to be a SHA, just split the string
if (preg_match("/^([[:alnum:]]{40})(.+)/", $input, $matches)) { if (preg_match('/^([[:alnum:]]{40})(.+)/', $input, $matches)) {
$branch = $matches[1]; $branch = $matches[1];
} else { } else {
// Otherwise, attempt to detect the ref using a list of the project's branches and tags // Otherwise, attempt to detect the ref using a list of the project's branches and tags
$validRefs = array_merge((array) $repository->getBranches(), (array) $repository->getTags()); $validRefs = array_merge((array) $repository->getBranches(), (array) $repository->getTags());
foreach ($validRefs as $key => $ref) { foreach ($validRefs as $key => $ref) {
if (!preg_match(sprintf("#^%s/#", preg_quote($ref, '#')), $input)) { if (!preg_match(sprintf('#^%s/#', preg_quote($ref, '#')), $input)) {
unset($validRefs[$key]); unset($validRefs[$key]);
} }
} }
@@ -223,7 +230,6 @@ class Repository
} }
} }
return array($branch, $tree); return [$branch, $tree];
} }
} }

View File

@@ -2,8 +2,8 @@
namespace GitList\Util; namespace GitList\Util;
use Silex\Application;
use GitList\Exception\EmptyRepositoryException; use GitList\Exception\EmptyRepositoryException;
use Silex\Application;
class Routing class Routing
{ {
@@ -84,7 +84,7 @@ class Routing
$path = substr($path, 1); $path = substr($path, 1);
} }
return array($commitish, $path); return [$commitish, $path];
} }
public function getBranchRegex() public function getBranchRegex()
@@ -127,6 +127,7 @@ class Routing
); );
$regex = implode('|', $quotedPaths); $regex = implode('|', $quotedPaths);
} }
return $regex; return $regex;
} }
@@ -143,9 +144,10 @@ class Routing
} }
/** /**
* Strips the base path from a full repository path * Strips the base path from a full repository path.
* *
* @param string $repoPath Full path to the repository * @param string $repoPath Full path to the repository
*
* @return string Relative path to the repository from git.repositories * @return string Relative path to the repository from git.repositories
*/ */
public function getRelativePath($repoPath) public function getRelativePath($repoPath)
@@ -154,11 +156,9 @@ class Routing
$relativePath = substr($repoPath, strlen($this->app['git.repos'])); $relativePath = substr($repoPath, strlen($this->app['git.repos']));
return ltrim(strtr($relativePath, '\\', '/'), '/'); return ltrim(strtr($relativePath, '\\', '/'), '/');
} else { }
throw new \InvalidArgumentException( throw new \InvalidArgumentException(
sprintf("Path '%s' does not match configured repository directory", $repoPath) sprintf("Path '%s' does not match configured repository directory", $repoPath)
); );
} }
} }
}

View File

@@ -5,24 +5,25 @@ namespace GitList\Util;
class View class View
{ {
/** /**
* Builds a breadcrumb array based on a path spec * Builds a breadcrumb array based on a path spec.
* *
* @param string $spec Path spec * @param string $spec Path spec
*
* @return array Array with parts of the breadcrumb * @return array Array with parts of the breadcrumb
*/ */
public function getBreadcrumbs($spec) public function getBreadcrumbs($spec)
{ {
if (!$spec) { if (!$spec) {
return array(); return [];
} }
$paths = explode('/', $spec); $paths = explode('/', $spec);
foreach ($paths as $i => $path) { foreach ($paths as $i => $path) {
$breadcrumbs[] = array( $breadcrumbs[] = [
'dir' => $path, 'dir' => $path,
'path' => implode('/', array_slice($paths, 0, $i + 1)), 'path' => implode('/', array_slice($paths, 0, $i + 1)),
); ];
} }
return $breadcrumbs; return $breadcrumbs;
@@ -31,18 +32,18 @@ class View
public function getPager($pageNumber, $totalCommits) public function getPager($pageNumber, $totalCommits)
{ {
$pageNumber = (empty($pageNumber)) ? 0 : $pageNumber; $pageNumber = (empty($pageNumber)) ? 0 : $pageNumber;
$lastPage = intval($totalCommits / 15); $lastPage = (int) ($totalCommits / 15);
// If total commits are integral multiple of 15, the lastPage will be commits/15 - 1. // If total commits are integral multiple of 15, the lastPage will be commits/15 - 1.
$lastPage = ($lastPage * 15 == $totalCommits) ? $lastPage - 1 : $lastPage; $lastPage = ($lastPage * 15 == $totalCommits) ? $lastPage - 1 : $lastPage;
$nextPage = $pageNumber + 1; $nextPage = $pageNumber + 1;
$previousPage = $pageNumber - 1; $previousPage = $pageNumber - 1;
return array('current' => $pageNumber, return ['current' => $pageNumber,
'next' => $nextPage, 'next' => $nextPage,
'previous' => $previousPage, 'previous' => $previousPage,
'last' => $lastPage, 'last' => $lastPage,
'total' => $totalCommits, 'total' => $totalCommits,
); ];
} }
} }

View File

@@ -1,8 +1,8 @@
<?php <?php
use GitList\Git\Client;
use Silex\WebTestCase; use Silex\WebTestCase;
use Symfony\Component\Filesystem\Filesystem; use Symfony\Component\Filesystem\Filesystem;
use GitList\Git\Client;
class InterfaceTest extends WebTestCase class InterfaceTest extends WebTestCase
{ {
@@ -29,9 +29,10 @@ class InterfaceTest extends WebTestCase
} }
$options['path'] = getenv('GIT_CLIENT') ?: '/usr/bin/git'; $options['path'] = getenv('GIT_CLIENT') ?: '/usr/bin/git';
$options['hidden'] = array(self::$tmpdir . '/hiddenrepo'); $options['hidden'] = [self::$tmpdir . '/hiddenrepo'];
$options['default_branch'] = 'master'; $options['default_branch'] = 'master';
$options['ini.file'] = "config.ini"; $options['ini.file'] = 'config.ini';
$options['projects'] = false;
$cacheDir = self::$tmpdir . DIRECTORY_SEPARATOR . 'cache'; $cacheDir = self::$tmpdir . DIRECTORY_SEPARATOR . 'cache';
$fs->mkdir($cacheDir); $fs->mkdir($cacheDir);
@@ -48,7 +49,7 @@ class InterfaceTest extends WebTestCase
$repository->setConfig('user.name', 'Luke Skywalker'); $repository->setConfig('user.name', 'Luke Skywalker');
$repository->setConfig('user.email', 'luke@rebel.org'); $repository->setConfig('user.email', 'luke@rebel.org');
$repository->addAll(); $repository->addAll();
$repository->commit("Initial commit"); $repository->commit('Initial commit');
$repository->createBranch('issue12'); $repository->createBranch('issue12');
$repository->createBranch('issue42'); $repository->createBranch('issue42');
$repository->createBranch('branch/name/wiith/slashes'); $repository->createBranch('branch/name/wiith/slashes');
@@ -61,14 +62,18 @@ class InterfaceTest extends WebTestCase
file_put_contents(self::$tmpdir . 'foobar/.git/description', 'This is a test repo!'); file_put_contents(self::$tmpdir . 'foobar/.git/description', 'This is a test repo!');
$fs->mkdir(self::$tmpdir . 'foobar/myfolder'); $fs->mkdir(self::$tmpdir . 'foobar/myfolder');
$fs->mkdir(self::$tmpdir . 'foobar/testfolder'); $fs->mkdir(self::$tmpdir . 'foobar/testfolder');
file_put_contents(self::$tmpdir . 'foobar/myfolder/mytest.php', file_put_contents(
"<?php\necho 'Hello World'; // This is my test"); self::$tmpdir . 'foobar/myfolder/mytest.php',
file_put_contents(self::$tmpdir . 'foobar/testfolder/test.php', "<?php\necho 'Hello World'; // This is my test"
"<?php\necho 'Hello World'; // This is a 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.name', 'Luke Skywalker');
$repository->setConfig('user.email', 'luke@rebel.org'); $repository->setConfig('user.email', 'luke@rebel.org');
$repository->addAll(); $repository->addAll();
$repository->commit("First commit"); $repository->commit('First commit');
// Nested repository fixture // Nested repository fixture
$nested_dir = self::$tmpdir . 'nested/'; $nested_dir = self::$tmpdir . 'nested/';
@@ -80,13 +85,13 @@ class InterfaceTest extends WebTestCase
$repository->setConfig('user.name', 'Luke Skywalker'); $repository->setConfig('user.name', 'Luke Skywalker');
$repository->setConfig('user.email', 'luke@rebel.org'); $repository->setConfig('user.email', 'luke@rebel.org');
$repository->addAll(); $repository->addAll();
$repository->commit("First commit"); $repository->commit('First commit');
$repository->createBranch("testing"); $repository->createBranch('testing');
$repository->checkout("testing"); $repository->checkout('testing');
file_put_contents($nested_dir . 'NestedRepo/README.txt', 'NESTED TEST BRANCH README'); file_put_contents($nested_dir . 'NestedRepo/README.txt', 'NESTED TEST BRANCH README');
$repository->addAll(); $repository->addAll();
$repository->commit("Changing branch"); $repository->commit('Changing branch');
$repository->checkout("master"); $repository->checkout('master');
// master-less repository fixture // master-less repository fixture
$git->createRepository(self::$tmpdir . 'develop'); $git->createRepository(self::$tmpdir . 'develop');
@@ -95,15 +100,15 @@ class InterfaceTest extends WebTestCase
$repository->setConfig('user.email', 'luke@rebel.org'); $repository->setConfig('user.email', 'luke@rebel.org');
file_put_contents(self::$tmpdir . 'develop/README.md', "## develop\ndevelop is a *test* repository!"); file_put_contents(self::$tmpdir . 'develop/README.md', "## develop\ndevelop is a *test* repository!");
$repository->addAll(); $repository->addAll();
$repository->commit("First commit"); $repository->commit('First commit');
$repository->createBranch("develop"); $repository->createBranch('develop');
$repository = $repository->checkout('develop'); $repository = $repository->checkout('develop');
file_put_contents(self::$tmpdir . 'develop/test.php', "<?php\necho 'Hello World'; // This is a test"); file_put_contents(self::$tmpdir . 'develop/test.php', "<?php\necho 'Hello World'; // This is a test");
$repository->setConfig('user.name', 'Luke Skywalker'); $repository->setConfig('user.name', 'Luke Skywalker');
$repository->setConfig('user.email', 'luke@rebel.org'); $repository->setConfig('user.email', 'luke@rebel.org');
$repository->addAll(); $repository->addAll();
$repository->commit("Initial commit"); $repository->commit('Initial commit');
// Detached HEAD repository fixture // Detached HEAD repository fixture
$git->createRepository(self::$tmpdir . 'detached-head'); $git->createRepository(self::$tmpdir . 'detached-head');
@@ -112,7 +117,7 @@ class InterfaceTest extends WebTestCase
$repository->setConfig('user.email', 'luke@rebel.org'); $repository->setConfig('user.email', 'luke@rebel.org');
file_put_contents(self::$tmpdir . 'detached-head/README.md', "## detached head\ndetached-head is a *test* repository!"); file_put_contents(self::$tmpdir . 'detached-head/README.md', "## detached head\ndetached-head is a *test* repository!");
$repository->addAll(); $repository->addAll();
$repository->commit("First commit"); $repository->commit('First commit');
$repository->checkout('HEAD'); $repository->checkout('HEAD');
// mailmap repository fixture // mailmap repository fixture
@@ -121,26 +126,33 @@ class InterfaceTest extends WebTestCase
$repository->setConfig('user.name', 'Luke Skywalker'); $repository->setConfig('user.name', 'Luke Skywalker');
$repository->setConfig('user.email', 'luke@rebel.org'); $repository->setConfig('user.email', 'luke@rebel.org');
file_put_contents(self::$tmpdir . 'mailmap/README.md', "## mailmap\nmailmap is a *test* repository!"); file_put_contents(self::$tmpdir . 'mailmap/README.md', "## mailmap\nmailmap is a *test* repository!");
file_put_contents(self::$tmpdir . 'mailmap/.mailmap', "Anakin Skywalker <darth@empire.com> Luke Skywalker <luke@rebel.org>"); file_put_contents(self::$tmpdir . 'mailmap/.mailmap', 'Anakin Skywalker <darth@empire.com> Luke Skywalker <luke@rebel.org>');
$repository->addAll(); $repository->addAll();
$repository->commit("First commit"); $repository->commit('First commit');
}
public static function tearDownAfterClass()
{
$fs = new Filesystem();
$fs->remove(self::$tmpdir);
} }
public function createApplication() public function createApplication()
{ {
$config = new GitList\Config; $config = new GitList\Config();
$config->set('app', 'debug', true); $config->set('app', 'debug', true);
$config->set('app', 'debug', false); $config->set('app', 'debug', false);
$config->set('git', 'client', self::$gitPath); $config->set('git', 'client', self::$gitPath);
$config->set('git', 'default_branch', 'master'); $config->set('git', 'default_branch', 'master');
$config->set('git', 'repositories', array(self::$tmpdir)); $config->set('git', 'repositories', [self::$tmpdir]);
$app = require 'boot.php'; $app = require 'boot.php';
return $app; return $app;
} }
/** /**
* @covers GitList\Controller\MainController::connect * @covers \GitList\Controller\MainController::connect
*/ */
public function testInitialPage() public function testInitialPage()
{ {
@@ -178,7 +190,7 @@ class InterfaceTest extends WebTestCase
} }
/** /**
* @covers GitList\Controller\TreeController::connect * @covers \GitList\Controller\TreeController::connect
*/ */
public function testRepositoryPage() public function testRepositoryPage()
{ {
@@ -211,7 +223,7 @@ class InterfaceTest extends WebTestCase
} }
/** /**
* @covers GitList\Controller\BlobController::connect * @covers \GitList\Controller\BlobController::connect
*/ */
public function testBlobPage() public function testBlobPage()
{ {
@@ -221,18 +233,26 @@ class InterfaceTest extends WebTestCase
$this->assertTrue($client->getResponse()->isOk()); $this->assertTrue($client->getResponse()->isOk());
$this->assertCount(1, $crawler->filter('.breadcrumb .active:contains("test.php")')); $this->assertCount(1, $crawler->filter('.breadcrumb .active:contains("test.php")'));
$this->assertEquals('/GitTest/raw/master/test.php', $this->assertEquals(
$crawler->filter('.source-header .btn-group a')->eq(0)->attr('href')); '/GitTest/raw/master/test.php',
$this->assertEquals('/GitTest/blame/master/test.php', $crawler->filter('.source-header .btn-group a')->eq(0)->attr('href')
$crawler->filter('.source-header .btn-group a')->eq(1)->attr('href')); );
$this->assertEquals('/GitTest/logpatch/master/test.php', $this->assertEquals(
$crawler->filter('.source-header .btn-group a')->eq(2)->attr('href')); '/GitTest/blame/master/test.php',
$this->assertEquals('/GitTest/commits/master/test.php', $crawler->filter('.source-header .btn-group a')->eq(1)->attr('href')
$crawler->filter('.source-header .btn-group a')->eq(3)->attr('href')); );
$this->assertEquals(
'/GitTest/logpatch/master/test.php',
$crawler->filter('.source-header .btn-group a')->eq(2)->attr('href')
);
$this->assertEquals(
'/GitTest/commits/master/test.php',
$crawler->filter('.source-header .btn-group a')->eq(3)->attr('href')
);
} }
/** /**
* @covers GitList\Controller\BlobController::connect * @covers \GitList\Controller\BlobController::connect
*/ */
public function testRawPage() public function testRawPage()
{ {
@@ -244,7 +264,7 @@ class InterfaceTest extends WebTestCase
} }
/** /**
* @covers GitList\Controller\CommitController::connect * @covers \GitList\Controller\CommitController::connect
*/ */
public function testBlamePage() public function testBlamePage()
{ {
@@ -253,18 +273,22 @@ class InterfaceTest extends WebTestCase
$crawler = $client->request('GET', '/GitTest/blame/master/test.php'); $crawler = $client->request('GET', '/GitTest/blame/master/test.php');
$this->assertTrue($client->getResponse()->isOk()); $this->assertTrue($client->getResponse()->isOk());
$this->assertCount(1, $crawler->filter('.source-header .meta:contains("test.php")')); $this->assertCount(1, $crawler->filter('.source-header .meta:contains("test.php")'));
$this->assertRegexp('/\/GitTest\/commit\/[a-zA-Z0-9%]+/', $this->assertRegexp(
$crawler->filter('.blame-view .commit')->eq(0)->filter('a')->attr('href')); '/\/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'); $crawler = $client->request('GET', '/foobar/blame/master/bar.json');
$this->assertTrue($client->getResponse()->isOk()); $this->assertTrue($client->getResponse()->isOk());
$this->assertCount(1, $crawler->filter('.source-header .meta:contains("bar.json")')); $this->assertCount(1, $crawler->filter('.source-header .meta:contains("bar.json")'));
$this->assertRegexp('/\/foobar\/commit\/[a-zA-Z0-9%]+/', $this->assertRegexp(
$crawler->filter('.blame-view .commit')->eq(0)->filter('a')->attr('href')); '/\/foobar\/commit\/[a-zA-Z0-9%]+/',
$crawler->filter('.blame-view .commit')->eq(0)->filter('a')->attr('href')
);
} }
/** /**
* @covers GitList\Controller\CommitController::connect * @covers \GitList\Controller\CommitController::connect
*/ */
public function testHistoryPage() public function testHistoryPage()
{ {
@@ -289,7 +313,7 @@ class InterfaceTest extends WebTestCase
} }
/** /**
* @covers GitList\Controller\CommitController::connect * @covers \GitList\Controller\CommitController::connect
*/ */
public function testCommitsPage() public function testCommitsPage()
{ {
@@ -309,7 +333,6 @@ class InterfaceTest extends WebTestCase
$this->assertEquals('mailto:darth@empire.com', $crawler->filter('.table tbody tr td span a')->eq(1)->attr('href')); $this->assertEquals('mailto:darth@empire.com', $crawler->filter('.table tbody tr td span a')->eq(1)->attr('href'));
} }
public function testPatchLogPage() public function testPatchLogPage()
{ {
$client = $this->createClient(); $client = $this->createClient();
@@ -327,9 +350,8 @@ class InterfaceTest extends WebTestCase
$this->assertEquals('First commit', $crawler->filter('.commit-header h4')->eq(0)->text()); $this->assertEquals('First commit', $crawler->filter('.commit-header h4')->eq(0)->text());
} }
/** /**
* @covers GitList\Controller\MainController::connect * @covers \GitList\Controller\MainController::connect
*/ */
public function testStatsPage() public function testStatsPage()
{ {
@@ -348,7 +370,7 @@ class InterfaceTest extends WebTestCase
} }
/** /**
* @covers GitList\Controller\MainController::connect * @covers \GitList\Controller\MainController::connect
*/ */
public function testRssPage() public function testRssPage()
{ {
@@ -363,7 +385,7 @@ class InterfaceTest extends WebTestCase
} }
/** /**
* @covers GitList\Controller\TreeController::connect * @covers \GitList\Controller\TreeController::connect
*/ */
public function testNestedRepoPage() public function testNestedRepoPage()
{ {
@@ -377,7 +399,7 @@ class InterfaceTest extends WebTestCase
} }
/** /**
* @covers GitList\Controller\TreeController::connect * @covers \GitList\Controller\TreeController::connect
*/ */
public function testDevelopRepo() public function testDevelopRepo()
{ {
@@ -388,7 +410,7 @@ class InterfaceTest extends WebTestCase
} }
/** /**
* @covers GitList\Controller\TreeController::connect * @covers \GitList\Controller\TreeController::connect
*/ */
public function testNestedRepoBranch() public function testNestedRepoBranch()
{ {
@@ -398,11 +420,4 @@ class InterfaceTest extends WebTestCase
$this->assertTrue($client->getResponse()->isOk()); $this->assertTrue($client->getResponse()->isOk());
$this->assertRegexp('/NESTED TEST BRANCH README/', $client->getResponse()->getContent()); $this->assertRegexp('/NESTED TEST BRANCH README/', $client->getResponse()->getContent());
} }
public static function tearDownAfterClass()
{
$fs = new Filesystem();
$fs->remove(self::$tmpdir);
} }
}

View File

@@ -4,28 +4,28 @@
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<title>{% block title %}Welcome!{% endblock %}</title> <title>{% block title %}Welcome!{% endblock %}</title>
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type="text/css" href="{{ app.request.basepath }}/themes/{{ app.theme }}/css/style.css"> <link rel="stylesheet" type="text/css" href="{{ global.request.basepath }}/themes/{{ theme }}/css/style.css">
<link rel="stylesheet" type="text/css" href="{{ app.request.basepath }}/themes/{{ app.theme }}/css/fontawesome.css"> <link rel="stylesheet" type="text/css" href="{{ global.request.basepath }}/themes/{{ theme }}/css/fontawesome.css">
<link rel="stylesheet" type="text/css" href="{{ app.request.basepath }}/themes/{{ app.theme }}/css/gitgraph.css"> <link rel="stylesheet" type="text/css" href="{{ global.request.basepath }}/themes/{{ theme }}/css/gitgraph.css">
<link rel="shortcut icon" type="image/png" href="{{ app.request.basepath }}/themes/{{ app.theme }}/img/favicon.png" /> <link rel="shortcut icon" type="image/png" href="{{ global.request.basepath }}/themes/{{ theme }}/img/favicon.png" />
<!--[if lt IE 9]> <!--[if lt IE 9]>
<script src="{{ app.request.basepath }}/themes/{{ app.theme }}/js/html5.js"></script> <script src="{{ global.request.basepath }}/themes/{{ theme }}/js/html5.js"></script>
<![endif]--> <![endif]-->
</head> </head>
<body> <body>
{% block body %}{% endblock %} {% block body %}{% endblock %}
{% block javascripts %} {% block javascripts %}
<script src="{{ app.request.basepath }}/themes/{{ app.theme }}/js/jquery.js"></script> <script src="{{ global.request.basepath }}/themes/{{ theme }}/js/jquery.js"></script>
<script src="{{ app.request.basepath }}/themes/{{ app.theme }}/js/raphael.js"></script> <script src="{{ global.request.basepath }}/themes/{{ theme }}/js/raphael.js"></script>
<script src="{{ app.request.basepath }}/themes/{{ app.theme }}/js/bootstrap.js"></script> <script src="{{ global.request.basepath }}/themes/{{ theme }}/js/bootstrap.js"></script>
<script src="{{ app.request.basepath }}/themes/{{ app.theme }}/js/codemirror.js"></script> <script src="{{ global.request.basepath }}/themes/{{ theme }}/js/codemirror.js"></script>
<script src="{{ app.request.basepath }}/themes/{{ app.theme }}/js/showdown.js"></script> <script src="{{ global.request.basepath }}/themes/{{ theme }}/js/showdown.js"></script>
<script src="{{ app.request.basepath }}/themes/{{ app.theme }}/js/table.js"></script> <script src="{{ global.request.basepath }}/themes/{{ theme }}/js/table.js"></script>
<script src="{{ app.request.basepath }}/themes/{{ app.theme }}/js/main.js"></script> <script src="{{ global.request.basepath }}/themes/{{ theme }}/js/main.js"></script>
<script src="{{ app.request.basepath }}/themes/{{ app.theme }}/js/networkGraph.js"></script> <script src="{{ global.request.basepath }}/themes/{{ theme }}/js/networkGraph.js"></script>
<script src="{{ app.request.basepath }}/themes/{{ app.theme }}/js/gitgraph.js"></script> <script src="{{ global.request.basepath }}/themes/{{ theme }}/js/gitgraph.js"></script>
<script src="{{ app.request.basepath }}/themes/{{ app.theme }}/js/draw.js"></script> <script src="{{ global.request.basepath }}/themes/{{ theme }}/js/draw.js"></script>
{% endblock %} {% endblock %}
</body> </body>
</html> </html>

View File

@@ -8,11 +8,11 @@
<div class="col-sm-12"> <div class="col-sm-12">
<div class="tab-border nav-tabs"> <div class="tab-border nav-tabs">
{% if page in ['commits', 'searchcommits'] %} {% if page in ['commits', 'searchcommits'] %}
<form class="pull-right" action="{{ app.request.basepath }}/{{repo}}/commits/{{branch}}/search" method="POST"> <form class="pull-right" action="{{ global.request.basepath }}/{{repo}}/commits/{{branch}}/search" method="POST">
<input type="search" name="query" class="form-control input-sm" placeholder="Search commits..."> <input type="search" name="query" class="form-control input-sm" placeholder="Search commits...">
</form> </form>
{% else %} {% else %}
<form class="pull-right" action="{{ app.request.basepath }}/{{repo}}/tree/{{branch}}/search" method="POST"> <form class="pull-right" action="{{ global.request.basepath }}/{{repo}}/tree/{{branch}}/search" method="POST">
<input type="search" name="query" class="form-control input-sm" placeholder="Search tree..."> <input type="search" name="query" class="form-control input-sm" placeholder="Search tree...">
</form> </form>
{% endif %} {% endif %}

View File

@@ -7,7 +7,7 @@
<span class="icon-bar"></span> <span class="icon-bar"></span>
<span class="icon-bar"></span> <span class="icon-bar"></span>
</button> </button>
<a class="navbar-brand" href="{{ path('homepage') }}">{{ app.title }}</a> <a class="navbar-brand" href="{{ path('homepage') }}">{{ title }}</a>
</div> </div>
<div class="navbar-collapse collapse"> <div class="navbar-collapse collapse">
<ul class="nav navbar-nav navbar-right"> <ul class="nav navbar-nav navbar-right">

View File

@@ -9,7 +9,7 @@
{% block extra %} {% block extra %}
<div class="pull-right"> <div class="pull-right">
<div class="btn-group download-buttons"> <div class="btn-group download-buttons">
{% if app.show_http_remote or app.show_ssh_remote %} {% if show_http_remote or show_ssh_remote %}
<a type="button" href="#" class="btn btn-default btn-xs" title="Show remotes to clone this repository." id="clone-button-show">Clone</a> <a type="button" href="#" class="btn btn-default btn-xs" title="Show remotes to clone this repository." id="clone-button-show">Clone</a>
{% endif %} {% endif %}
<a type="button" href="{{ path('archive', {repo: repo, branch: branch, format: 'zip'}) }}" class="btn btn-default btn-xs" title="Download '{{ branch }}' as a ZIP archive">ZIP</a> <a type="button" href="{{ path('archive', {repo: repo, branch: branch, format: 'zip'}) }}" class="btn btn-default btn-xs" title="Download '{{ branch }}' as a ZIP archive">ZIP</a>

View File

@@ -9,7 +9,7 @@
{% block extra %} {% block extra %}
<div class="pull-right"> <div class="pull-right">
<div class="btn-group download-buttons"> <div class="btn-group download-buttons">
{% if app.show_http_remote or app.show_ssh_remote %} {% if show_http_remote or show_ssh_remote %}
<a type="button" href="#" class="btn btn-default btn-xs" title="Show remotes to clone this repository." id="clone-button-show">Clone</a> <a type="button" href="#" class="btn btn-default btn-xs" title="Show remotes to clone this repository." id="clone-button-show">Clone</a>
{% endif %} {% endif %}
<a type="button" href="{{ path('archive', {repo: repo, branch: branch, format: 'zip'}) }}" class="btn btn-default btn-xs" title="Download '{{ branch }}' as a ZIP archive">ZIP</a> <a type="button" href="{{ path('archive', {repo: repo, branch: branch, format: 'zip'}) }}" class="btn btn-default btn-xs" title="Download '{{ branch }}' as a ZIP archive">ZIP</a>
@@ -19,23 +19,23 @@
<a href="{{ path('rss', {repo: repo, branch: branch}) }}"><span class="fa fa-rss rss-icon"></span></a> <a href="{{ path('rss', {repo: repo, branch: branch}) }}"><span class="fa fa-rss rss-icon"></span></a>
</div> </div>
</div> </div>
{% if app.show_http_remote or app.show_ssh_remote %} {% if show_http_remote or show_ssh_remote %}
<div id="clone-popup"> <div id="clone-popup">
<div id="clone-popup-inner-wrapper"> <div id="clone-popup-inner-wrapper">
<a class="close" href="#" id="clone-button-hide">&times;</a> <a class="close" href="#" id="clone-button-hide">&times;</a>
<div class="btn-group"> <div class="btn-group">
{% if app.show_ssh_remote %} {% if show_ssh_remote %}
<button type="button" class="btn btn-default{{ app.show_ssh_remote and app.show_http_remote ? ' active' }}" id="clone-button-ssh">SSH</button> <button type="button" class="btn btn-default{{ show_ssh_remote and show_http_remote ? ' active' }}" id="clone-button-ssh">SSH</button>
{% endif %} {% endif %}
{% if app.show_http_remote %} {% if show_http_remote %}
<button type="button" class="btn btn-default" id="clone-button-http">HTTP{{ app.use_https ? 'S' }}</button> <button type="button" class="btn btn-default" id="clone-button-http">HTTP{{ use_https ? 'S' }}</button>
{% endif %} {% endif %}
</div><br /> </div><br />
{% if app.show_ssh_remote %} {% if show_ssh_remote %}
<input type="text" class="form-control{{ app.show_ssh_remote ? ' visible' }}" id="clone-input-ssh" value="git clone {{ app.ssh_user }}{{ app.ssh_user ? '@' }}{{ app.ssh_host ? app.ssh_host : app.request.host }}:{{ app.ssh_url_subdir }}{{ repo }}"> <input type="text" class="form-control{{ show_ssh_remote ? ' visible' }}" id="clone-input-ssh" value="git clone {{ ssh_user }}{{ ssh_user ? '@' }}{{ ssh_host ? ssh_host : global.request.host }}:{{ ssh_url_subdir }}{{ repo }}">
{% endif %} {% endif %}
{% if app.show_http_remote %} {% if show_http_remote %}
<input type="text" class="form-control{{ app.show_ssh_remote is empty and app.show_http_remote ? ' visible' }}" id="clone-input-http" value="git clone http{{ app.use_https ? 's' }}://{{ app.http_user }}{{ app.http_user ? '@' }}{{ app.http_host ? app.http_host : app.request.host }}/{{ app.http_url_subdir }}{{ repo }}"> <input type="text" class="form-control{{ show_ssh_remote is empty and show_http_remote ? ' visible' }}" id="clone-input-http" value="git clone http{{ use_https ? 's' }}://{{ http_user }}{{ http_user ? '@' }}{{ http_host ? http_host : global.request.host }}/{{ http_url_subdir }}{{ repo }}">
{% endif %} {% endif %}
</div> </div>
</div> </div>

View File

@@ -2,29 +2,29 @@
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<title>{{ app.title }}{% if app.title %} - {% endif %}{% block title %}Welcome!{% endblock %}</title> <title>{{ title }}{% if title %} - {% endif %}{% block title %}Welcome!{% endblock %}</title>
<link rel="stylesheet" type="text/css" href="{{ app.request.basepath }}/themes/{{ app.theme }}/css/style.css"> <link rel="stylesheet" type="text/css" href="{{ global.request.basepath }}/themes/{{ theme }}/css/style.css">
<link rel="stylesheet" type="text/css" href="{{ app.request.basepath }}/themes/{{ app.theme }}/css/gitgraph.css"> <link rel="stylesheet" type="text/css" href="{{ global.request.basepath }}/themes/{{ theme }}/css/gitgraph.css">
<link rel="shortcut icon" type="image/png" href="{{ app.request.basepath }}/themes/{{ app.theme }}/img/favicon.png" /> <link rel="shortcut icon" type="image/png" href="{{ global.request.basepath }}/themes/{{ theme }}/img/favicon.png" />
<!--[if lt IE 9]> <!--[if lt IE 9]>
<script src="{{ app.request.basepath }}/themes/{{ app.theme }}/js/html5.js"></script> <script src="{{ global.request.basepath }}/themes/{{ theme }}/js/html5.js"></script>
<![endif]--> <![endif]-->
</head> </head>
<body> <body>
{% block body %}{% endblock %} {% block body %}{% endblock %}
{% block javascripts %} {% block javascripts %}
<script src="{{ app.request.basepath }}/themes/{{ app.theme }}/js/jquery.js"></script> <script src="{{ global.request.basepath }}/themes/{{ theme }}/js/jquery.js"></script>
<script src="{{ app.request.basepath }}/themes/{{ app.theme }}/js/raphael.js"></script> <script src="{{ global.request.basepath }}/themes/{{ theme }}/js/raphael.js"></script>
<script src="{{ app.request.basepath }}/themes/{{ app.theme }}/js/bootstrap.js"></script> <script src="{{ global.request.basepath }}/themes/{{ theme }}/js/bootstrap.js"></script>
<script src="{{ app.request.basepath }}/themes/{{ app.theme }}/js/codemirror.js"></script> <script src="{{ global.request.basepath }}/themes/{{ theme }}/js/codemirror.js"></script>
<script src="{{ app.request.basepath }}/themes/{{ app.theme }}/js/showdown.js"></script> <script src="{{ global.request.basepath }}/themes/{{ theme }}/js/showdown.js"></script>
<script src="{{ app.request.basepath }}/themes/{{ app.theme }}/js/table.js"></script> <script src="{{ global.request.basepath }}/themes/{{ theme }}/js/table.js"></script>
<script src="{{ app.request.basepath }}/themes/{{ app.theme }}/js/list.min.js"></script> <script src="{{ global.request.basepath }}/themes/{{ theme }}/js/list.min.js"></script>
<script src="{{ app.request.basepath }}/themes/{{ app.theme }}/js/main.js"></script> <script src="{{ global.request.basepath }}/themes/{{ theme }}/js/main.js"></script>
<script src="{{ app.request.basepath }}/themes/{{ app.theme }}/js/networkGraph.js"></script> <script src="{{ global.request.basepath }}/themes/{{ theme }}/js/networkGraph.js"></script>
<script src="{{ app.request.basepath }}/themes/{{ app.theme }}/js/gitgraph.js"></script> <script src="{{ global.request.basepath }}/themes/{{ theme }}/js/gitgraph.js"></script>
<script src="{{ app.request.basepath }}/themes/{{ app.theme }}/js/draw.js"></script> <script src="{{ global.request.basepath }}/themes/{{ theme }}/js/draw.js"></script>
{% endblock %} {% endblock %}
</body> </body>
</html> </html>

View File

@@ -7,11 +7,11 @@
<div class="row"> <div class="row">
<div class="span12"> <div class="span12">
{% if page in ['commits', 'searchcommits'] %} {% if page in ['commits', 'searchcommits'] %}
<form class="form-search pull-right" action="{{ app.request.basepath }}/{{repo}}/commits/{{branch}}/search" method="POST"> <form class="form-search pull-right" action="{{ global.request.basepath }}/{{repo}}/commits/{{branch}}/search" method="POST">
<input type="text" name="query" class="input-medium search-query" placeholder="Search commits..." value="{{ query | default("") }}"> <input type="text" name="query" class="input-medium search-query" placeholder="Search commits..." value="{{ query | default("") }}">
</form> </form>
{% else %} {% else %}
<form class="form-search pull-right" action="{{ app.request.basepath }}/{{repo}}/tree/{{branch}}/search" method="POST"> <form class="form-search pull-right" action="{{ global.request.basepath }}/{{repo}}/tree/{{branch}}/search" method="POST">
<input type="text" name="query" class="input-medium search-query" placeholder="Search tree..." value="{{ query | default("") }}"> <input type="text" name="query" class="input-medium search-query" placeholder="Search tree..." value="{{ query | default("") }}">
</form> </form>
{% endif %} {% endif %}

View File

@@ -6,7 +6,7 @@
<span class="icon-bar"></span> <span class="icon-bar"></span>
<span class="icon-bar"></span> <span class="icon-bar"></span>
</a> </a>
<a class="brand" href="{{ path('homepage') }}">{{ app.title }}</a> <a class="brand" href="{{ path('homepage') }}">{{ title }}</a>
<div class="nav-collapse"> <div class="nav-collapse">
<ul class="nav pull-right"> <ul class="nav pull-right">
<li><a href="http://gitlist.org/">About</a></li> <li><a href="http://gitlist.org/">About</a></li>

View File

@@ -9,7 +9,7 @@
{% block extra %} {% block extra %}
<div class="pull-right"> <div class="pull-right">
<div class="btn-group download-buttons"> <div class="btn-group download-buttons">
{% if app.show_http_remote or app.show_ssh_remote %} {% if show_http_remote or show_ssh_remote %}
<a href="#" class="btn btn-mini" title="Show remotes to clone this repository." id="clone-button-show">Clone</a> <a href="#" class="btn btn-mini" title="Show remotes to clone this repository." id="clone-button-show">Clone</a>
{% endif %} {% endif %}
<a href="{{ path('archive', {repo: repo, branch: branch, format: 'zip'}) }}" class="btn btn-mini" title="Download '{{ branch }}' as a ZIP archive">ZIP</a> <a href="{{ path('archive', {repo: repo, branch: branch, format: 'zip'}) }}" class="btn btn-mini" title="Download '{{ branch }}' as a ZIP archive">ZIP</a>
@@ -17,23 +17,23 @@
</div> </div>
<a href="{{ path('rss', {repo: repo, branch: branch}) }}" class="rss-icon"><i class="rss"></i></a> <a href="{{ path('rss', {repo: repo, branch: branch}) }}" class="rss-icon"><i class="rss"></i></a>
</div> </div>
{% if app.show_http_remote or app.show_ssh_remote %} {% if show_http_remote or show_ssh_remote %}
<div id="clone-popup"> <div id="clone-popup">
<div id="clone-popup-inner-wrapper"> <div id="clone-popup-inner-wrapper">
<a class="close" href="#" id="clone-button-hide">&times;</a> <a class="close" href="#" id="clone-button-hide">&times;</a>
<div class="btn-group"> <div class="btn-group">
{% if app.show_ssh_remote %} {% if show_ssh_remote %}
<button class="btn{{ app.show_ssh_remote and app.show_http_remote ? ' active' }}" id="clone-button-ssh">SSH</button> <button class="btn{{ show_ssh_remote and show_http_remote ? ' active' }}" id="clone-button-ssh">SSH</button>
{% endif %} {% endif %}
{% if app.show_http_remote %} {% if show_http_remote %}
<button class="btn" id="clone-button-http">HTTP{{ app.use_https ? 'S' }}</button> <button class="btn" id="clone-button-http">HTTP{{ use_https ? 'S' }}</button>
{% endif %} {% endif %}
</div><br /> </div><br />
{% if app.show_ssh_remote %} {% if show_ssh_remote %}
<input type="text" class="form-control{{ app.show_ssh_remote ? ' visible' }}" id="clone-input-ssh" value="git clone {{ app.ssh_user }}{{ app.ssh_user ? '@' }}{{ app.ssh_host ? app.ssh_host : app.request.host }}:{{ app.ssh_url_subdir }}{{ repo }}"> <input type="text" class="form-control{{ show_ssh_remote ? ' visible' }}" id="clone-input-ssh" value="git clone {{ ssh_user }}{{ ssh_user ? '@' }}{{ ssh_host ? ssh_host : global.request.host }}:{{ ssh_url_subdir }}{{ repo }}">
{% endif %} {% endif %}
{% if app.show_http_remote %} {% if show_http_remote %}
<input type="text" class="form-control{{ app.show_ssh_remote is empty and app.show_http_remote ? ' visible' }}" id="clone-input-http" value="git clone http{{ app.use_https ? 's' }}://{{ app.http_user }}{{ app.http_user ? '@' }}{{ app.http_host ? app.http_host : app.request.host }}/{{ app.http_url_subdir }}{{ repo }}"> <input type="text" class="form-control{{ show_ssh_remote is empty and show_http_remote ? ' visible' }}" id="clone-input-http" value="git clone http{{ use_https ? 's' }}://{{ http_user }}{{ http_user ? '@' }}{{ http_host ? http_host : global.request.host }}/{{ http_url_subdir }}{{ repo }}">
{% endif %} {% endif %}
</div> </div>
</div> </div>