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
composer.phar
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
before_script:
- curl -s http://getcomposer.org/installer | php
- php composer.phar install --dev
php:
- 5.3
- 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.
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
* Apache with mod_rewrite enabled or nginx
* PHP 5.3.3
* PHP 5.4
## 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.

View File

@@ -87,17 +87,16 @@
</target>
<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">
<arg value="--report=checkstyle" />
<arg value="--report-file=${basedir}/build/logs/checkstyle.xml" />
<arg value="--standard=PSR2" />
<arg path="${basedir}/src" />
<exec executable="${vendordir}/php-cs-fixer" output="${basedir}/build/logs/cs.xml">
<arg value="fix" />
<arg value="--dry-run" />
<arg value="--format=junit" />
</exec>
</target>
<target name="package" description="Package the application for distribution">
<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>
<tar destfile="${basedir}/build/gitlist-master.tar.gz"

View File

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

2925
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

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

View File

@@ -6,6 +6,11 @@ class Config
{
protected $data;
public function __construct($data = [])
{
$this->data = $data;
}
public static function fromFile($file)
{
if (!file_exists($file)) {
@@ -19,11 +24,6 @@ class Config
return $config;
}
public function __construct($data = array())
{
$this->data = $data;
}
public function get($section, $option)
{
if (!array_key_exists($section, $this->data)) {
@@ -67,12 +67,11 @@ class Config
}
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) {
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;
use Silex\Api\ControllerProviderInterface;
use Silex\Application;
use Silex\ControllerProviderInterface;
use Symfony\Component\HttpFoundation\Response;
class BlobController implements ControllerProviderInterface
@@ -25,13 +25,13 @@ class BlobController implements ControllerProviderInterface
$fileType = $app['util.repository']->getFileType($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,
'commitishPath' => $commitishPath,
)));
]));
}
return $app['twig']->render('file.twig', array(
return $app['twig']->render('file.twig', [
'file' => $file,
'fileType' => $fileType,
'blob' => $blob->output(),
@@ -40,7 +40,7 @@ class BlobController implements ControllerProviderInterface
'breadcrumbs' => $breadcrumbs,
'branches' => $repository->getBranches(),
'tags' => $repository->getTags(),
));
]);
})->assert('repo', $app['util.routing']->getRepositoryRegex())
->assert('commitishPath', '.+')
->convert('commitishPath', 'escaper.argument:escape')
@@ -56,7 +56,7 @@ class BlobController implements ControllerProviderInterface
$blob = $repository->getBlob("$branch:\"$file\"")->output();
$headers = array();
$headers = [];
if ($app['util.repository']->isBinary($file)) {
$headers['Content-Disposition'] = 'attachment; filename="' . $file . '"';
$headers['Content-Type'] = 'application/octet-stream';
@@ -79,12 +79,12 @@ class BlobController implements ControllerProviderInterface
$filePatchesLog = $repository->getCommitsLogPatch($file);
$breadcrumbs = $app['util.view']->getBreadcrumbs($file);
return $app['twig']->render('logpatch.twig', array(
return $app['twig']->render('logpatch.twig', [
'branch' => $branch,
'repo' => $repo,
'breadcrumbs' => $breadcrumbs,
'commits' => $filePatchesLog,
));
]);
})->assert('repo', $app['util.routing']->getRepositoryRegex())
->assert('commitishPath', '.+')
->convert('commitishPath', 'escaper.argument:escape')
@@ -93,4 +93,3 @@ class BlobController implements ControllerProviderInterface
return $route;
}
}

View File

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

View File

@@ -2,10 +2,10 @@
namespace GitList\Controller;
use Silex\Api\ControllerProviderInterface;
use Silex\Application;
use Silex\ControllerProviderInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
class MainController implements ControllerProviderInterface
{
@@ -16,14 +16,13 @@ class MainController implements ControllerProviderInterface
$route->get('/', function () use ($app) {
$repositories = $app['git']->getRepositories($app['git.repos']);
return $app['twig']->render('index.twig', array(
return $app['twig']->render('index.twig', [
'repositories' => $repositories,
));
]);
})->bind('homepage');
$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'));
})->bind('refresh');
@@ -37,14 +36,14 @@ class MainController implements ControllerProviderInterface
$stats = $repository->getStatistics($branch);
$authors = $repository->getAuthorStatistics($branch);
return $app['twig']->render('stats.twig', array(
return $app['twig']->render('stats.twig', [
'repo' => $repo,
'branch' => $branch,
'branches' => $repository->getBranches(),
'tags' => $repository->getTags(),
'stats' => $stats,
'authors' => $authors,
));
]);
})->assert('repo', $app['util.routing']->getRepositoryRegex())
->assert('branch', $app['util.routing']->getBranchRegex())
->value('branch', null)
@@ -60,13 +59,13 @@ class MainController implements ControllerProviderInterface
$commits = $repository->getPaginatedCommits($branch);
$html = $app['twig']->render('rss.twig', array(
$html = $app['twig']->render('rss.twig', [
'repo' => $repo,
'branch' => $branch,
'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('branch', $app['util.routing']->getBranchRegex())
->value('branch', null)

View File

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

View File

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

View File

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

View File

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

View File

@@ -4,5 +4,4 @@ namespace GitList\Exception;
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
*
* @return array Found repositories, containing their name, path and description sorted
* by repository name
*/
public function getRepositories($paths)
{
$allRepositories = array();
$allRepositories = [];
foreach ($paths as $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;
}
@@ -58,11 +59,109 @@ class Client extends BaseClient
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)
{
$dir = new \DirectoryIterator($path);
$repositories = array();
$repositories = [];
foreach ($dir as $file) {
if ($file->isDot()) {
@@ -82,9 +181,7 @@ class Client extends BaseClient
$isRepository = file_exists($file->getPathname() . '/.git/HEAD');
if ($isRepository || $isBare) {
$hidden = function ($path, $hide) {
$return = false;
array_walk($hide, function ($value, $key) use ($path, &$return) {
@@ -92,6 +189,7 @@ class Client extends BaseClient
$return = true;
}
});
return $return;
};
@@ -121,116 +219,18 @@ class Client extends BaseClient
continue;
}
$repositories[$repoName] = array(
$repositories[$repoName] = [
'name' => $repoName,
'path' => $file->getPathname(),
'description' => $description
);
'description' => $description,
];
continue;
} else {
$repositories = array_merge($repositories, $this->recurseDirectory($file->getPathname(), false));
}
$repositories = array_merge($repositories, $this->recurseDirectory($file->getPathname(), false));
}
}
return $repositories;
}
/**
* Set default branch as a string.
*
* @param string $branch Name of branch to use when repo's HEAD is detached.
* @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;
use Gitter\Repository as BaseRepository;
use Gitter\Model\Commit\Commit;
use Gitter\Model\Commit\Diff;
use Gitter\PrettyFormat;
use Gitter\Repository as BaseRepository;
use Symfony\Component\Filesystem\Filesystem;
class Repository extends BaseRepository
@@ -14,7 +14,8 @@ class Repository extends BaseRepository
* Return true if the repo contains this commit.
*
* @param $commitHash Hash of commit whose existence we want to check
* @return boolean Whether or not the commit exists in this repo
*
* @return bool Whether or not the commit exists in this repo
*/
public function hasCommit($commitHash)
{
@@ -27,7 +28,7 @@ class Repository extends BaseRepository
/**
* 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();
@@ -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
*
* @return array Collection of Commits data
*/
public function getCommitsLogPatch($file)
{
$record_delimiter = chr(hexdec("0x1e"));
$file_patches = $this->getClient()->run($this,
"log -p --pretty=format:\"".$record_delimiter."<item><hash>%H</hash>"
. "<short_hash>%h</short_hash><tree>%T</tree><parents>%P</parents>"
. "<author>%aN</author><author_email>%aE</author_email>"
. "<date>%at</date><commiter>%cN</commiter><commiter_email>%cE</commiter_email>"
. "<commiter_date>%ct</commiter_date>"
. "<message><![CDATA[%s]]></message>"
. "<body><![CDATA[%b]]></body>"
$record_delimiter = chr(hexdec('0x1e'));
$file_patches = $this->getClient()->run(
$this,
'log -p --pretty=format:"' . $record_delimiter . '<item><hash>%H</hash>'
. '<short_hash>%h</short_hash><tree>%T</tree><parents>%P</parents>'
. '<author>%aN</author><author_email>%aE</author_email>'
. '<date>%at</date><commiter>%cN</commiter><commiter_email>%cE</commiter_email>'
. '<commiter_date>%ct</commiter_date>'
. '<message><![CDATA[%s]]></message>'
. '<body><![CDATA[%b]]></body>'
. "</item>\" $file"
);
$patch_collection = array();
$patch_collection = [];
foreach (preg_split('/(' . $record_delimiter . '\<item\>)/', $file_patches, null, PREG_SPLIT_NO_EMPTY) as $patches) {
$patches = '<item>' . $patches;
$xmlEnd = strpos($patches, '</item>') + 7;
@@ -63,9 +66,9 @@ class Repository extends BaseRepository
$logs = explode("\n", $commitData);
// Read commit metadata
$format = new PrettyFormat;
$format = new PrettyFormat();
$data = $format->parse($commitInfo);
$commit = new Commit;
$commit = new Commit();
$commit->importData($data[0]);
$commit->setDiffs($this->readDiffLogs($logs));
$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
*
* @return array Commit data
*/
public function getCommit($commitHash)
{
$logs = $this->getClient()->run($this,
"show --pretty=format:\"<item><hash>%H</hash>"
. "<short_hash>%h</short_hash><tree>%T</tree><parents>%P</parents>"
. "<author>%aN</author><author_email>%aE</author_email>"
. "<date>%at</date><commiter>%cN</commiter><commiter_email>%cE</commiter_email>"
. "<commiter_date>%ct</commiter_date>"
. "<message><![CDATA[%s]]></message>"
. "<body><![CDATA[%b]]></body>"
$logs = $this->getClient()->run(
$this,
'show --pretty=format:"<item><hash>%H</hash>'
. '<short_hash>%h</short_hash><tree>%T</tree><parents>%P</parents>'
. '<author>%aN</author><author_email>%aE</author_email>'
. '<date>%at</date><commiter>%cN</commiter><commiter_email>%cE</commiter_email>'
. '<commiter_date>%ct</commiter_date>'
. '<message><![CDATA[%s]]></message>'
. '<body><![CDATA[%b]]></body>'
. "</item>\" $commitHash"
);
@@ -99,9 +104,9 @@ class Repository extends BaseRepository
$logs = explode("\n", $commitData);
// Read commit metadata
$format = new PrettyFormat;
$format = new PrettyFormat();
$data = $format->parse($commitInfo);
$commit = new Commit;
$commit = new Commit();
$commit->importData($data[0]);
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
*
* @return array Commits hashes containing the lines
*/
public function getBlame($file)
{
$blame = array();
$blame = [];
$logs = $this->getClient()->run($this, "blame --root -sl $file");
$logs = explode("\n", $logs);
@@ -138,11 +144,11 @@ class Repository extends BaseRepository
$currentCommit = $match[1][0];
if ($currentCommit != $previousCommit) {
++$i;
$blame[$i] = array(
$blame[$i] = [
'line' => '',
'commit' => $currentCommit,
'commitShort' => substr($currentCommit, 0, 8)
);
'commitShort' => substr($currentCommit, 0, 8),
];
}
$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
*
* @return array Array of diffs
*/
public function readDiffLogs(array $logs)
{
$diffs = array();
$diffs = [];
$lineNumOld = 0;
$lineNumNew = 0;
foreach ($logs as $log) {
# Skip empty lines
if ($log == "") {
// Skip empty lines
if ($log == '') {
continue;
}
@@ -174,7 +181,7 @@ class Repository extends BaseRepository
$diffs[] = $diff;
}
$diff = new Diff;
$diff = new Diff();
if (preg_match('/^diff --[\S]+ a\/?(.+) b\/?/', $log, $name)) {
$diff->setFile($name[1]);
}
@@ -198,7 +205,7 @@ class Repository extends BaseRepository
// Handle binary files properly.
if ('Binary' === substr($log, 0, 6)) {
$m = array();
$m = [];
if (preg_match('/Binary files (.+) and (.+) differ/', $log, $m)) {
$diff->setOld($m[1]);
$diff->setNew(" {$m[2]}");
@@ -207,16 +214,16 @@ class Repository extends BaseRepository
if (!empty($log)) {
switch ($log[0]) {
case "@":
case '@':
// Set the line numbers
preg_match('/@@ -([0-9]+)(?:,[0-9]+)? \+([0-9]+)/', $log, $matches);
$lineNumOld = $matches[1] - 1;
$lineNumNew = $matches[2] - 1;
break;
case "-":
case '-':
$lineNumOld++;
break;
case "+":
case '+':
$lineNumNew++;
break;
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 int page
*
* @return array Commit log
*/
public function getPaginatedCommits($file = null, $page = 0)
@@ -254,12 +261,12 @@ class Repository extends BaseRepository
$pager = "--skip=$page --max-count=15";
$command =
"log $pager --pretty=format:\"<item><hash>%H</hash>"
. "<short_hash>%h</short_hash><tree>%T</tree><parents>%P</parents>"
. "<author>%aN</author><author_email>%aE</author_email>"
. "<date>%at</date><commiter>%cN</commiter>"
. "<commiter_email>%cE</commiter_email>"
. "<commiter_date>%ct</commiter_date>"
. "<message><![CDATA[%s]]></message></item>\"";
. '<short_hash>%h</short_hash><tree>%T</tree><parents>%P</parents>'
. '<author>%aN</author><author_email>%aE</author_email>'
. '<date>%at</date><commiter>%cN</commiter>'
. '<commiter_email>%cE</commiter_email>'
. '<commiter_date>%ct</commiter_date>'
. '<message><![CDATA[%s]]></message></item>"';
if ($file) {
$command .= " $file";
@@ -268,11 +275,11 @@ class Repository extends BaseRepository
try {
$logs = $this->getPrettyFormat($command);
} catch (\RuntimeException $e) {
return array();
return [];
}
foreach ($logs as $log) {
$commit = new Commit;
$commit = new Commit();
$commit->importData($log);
$commits[] = $commit;
}
@@ -283,25 +290,25 @@ class Repository extends BaseRepository
public function searchCommitLog($query, $branch)
{
$query = escapeshellarg($query);
$query = strtr($query, array('[' => '\\[', ']' => '\\]'));
$query = strtr($query, ['[' => '\\[', ']' => '\\]']);
$command =
"log --grep={$query} -i --pretty=format:\"<item><hash>%H</hash>"
. "<short_hash>%h</short_hash><tree>%T</tree><parents>%P</parents>"
. "<author>%aN</author><author_email>%aE</author_email>"
. "<date>%at</date><commiter>%cN</commiter>"
. "<commiter_email>%cE</commiter_email>"
. "<commiter_date>%ct</commiter_date>"
. "<message><![CDATA[%s]]></message></item>\""
. '<short_hash>%h</short_hash><tree>%T</tree><parents>%P</parents>'
. '<author>%aN</author><author_email>%aE</author_email>'
. '<date>%at</date><commiter>%cN</commiter>'
. '<commiter_email>%cE</commiter_email>'
. '<commiter_date>%ct</commiter_date>'
. '<message><![CDATA[%s]]></message></item>"'
. " $branch";
try {
$logs = $this->getPrettyFormat($command);
} catch (\RuntimeException $e) {
return array();
return [];
}
foreach ($logs as $log) {
$commit = new Commit;
$commit = new Commit();
$commit->importData($log);
$commits[] = $commit;
}
@@ -357,7 +364,7 @@ class Repository extends BaseRepository
foreach ($logs as $user => $count) {
$user = explode('||', $user);
$data[] = array('name' => $user[0], 'email' => $user[1], 'commits' => $count);
$data[] = ['name' => $user[0], 'email' => $user[1], 'commits' => $count];
}
return $data;
@@ -368,8 +375,8 @@ class Repository extends BaseRepository
// Calculate amount of files, extensions and file size
$logs = $this->getClient()->run($this, 'ls-tree -r -l ' . $branch);
$lines = explode("\n", $logs);
$files = array();
$data['extensions'] = array();
$files = [];
$data['extensions'] = [];
$data['size'] = 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 $output Output File name
@@ -419,7 +426,7 @@ class Repository extends BaseRepository
*/
public function createArchive($tree, $output, $format = 'zip')
{
$fs = new Filesystem;
$fs = new Filesystem();
$fs->mkdir(dirname($output));
$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.
*
* @param string $commitish Commitish reference; branch, tag, SHA1, etc.
* @param string $path Path whose existence we want to verify.
* @param string $commitish commitish reference; branch, tag, SHA1, etc
* @param string $path path whose existence we want to verify
*
* @return bool
*
* GRIPE Arguably belongs in Gitter, as it's generally useful functionality.
@@ -445,4 +453,3 @@ class Repository extends BaseRepository
return false;
}
}

View File

@@ -3,32 +3,21 @@
namespace GitList\Provider;
use GitList\Git\Client;
use Silex\Application;
use Silex\ServiceProviderInterface;
use Pimple\Container;
use Pimple\ServiceProviderInterface;
class GitServiceProvider implements ServiceProviderInterface
{
/**
* Register the Git\Client on the Application ServiceProvider
*
* @param Application $app Silex Application
* @return Git\Client Instance of the Git\Client
*/
public function register(Application $app)
public function register(Container $container)
{
$app['git'] = function () use ($app) {
$options['path'] = $app['git.client'];
$options['hidden'] = $app['git.hidden'];
$options['projects'] = $app['git.projects'];
$options['ini.file'] = $app['ini.file'];
$options['default_branch'] = $app['git.default_branch'];
$container['git'] = function () use ($container) {
$options['path'] = $container['git.client'];
$options['hidden'] = $container['git.hidden'];
$options['projects'] = $container['git.projects'];
$options['ini.file'] = $container['ini.file'];
$options['default_branch'] = $container['git.default_branch'];
return new Client($options);
};
}
public function boot(Application $app)
{
}
}

View File

@@ -3,24 +3,15 @@
namespace GitList\Provider;
use GitList\Util\Repository;
use Silex\Application;
use Silex\ServiceProviderInterface;
use Pimple\Container;
use Pimple\ServiceProviderInterface;
class RepositoryUtilServiceProvider implements ServiceProviderInterface
{
/**
* Register the Util\Repository class on the Application ServiceProvider
*
* @param Application $app Silex Application
*/
public function register(Application $app)
{
$app['util.repository'] = $app->share(function () use ($app) {
return new Repository($app);
});
}
public function boot(Application $app)
public function register(Container $container)
{
$container['util.repository'] = function () use ($container) {
return new Repository($container);
};
}
}

View File

@@ -3,24 +3,15 @@
namespace GitList\Provider;
use GitList\Util\Routing;
use Silex\Application;
use Silex\ServiceProviderInterface;
use Pimple\Container;
use Pimple\ServiceProviderInterface;
class RoutingUtilServiceProvider implements ServiceProviderInterface
{
/**
* Register the Util\Repository class on the Application ServiceProvider
*
* @param Application $app Silex Application
*/
public function register(Application $app)
{
$app['util.routing'] = $app->share(function () use ($app) {
return new Routing($app);
});
}
public function boot(Application $app)
public function register(Container $container)
{
$container['util.routing'] = function () use ($container) {
return new Routing($container);
};
}
}

View File

@@ -3,24 +3,15 @@
namespace GitList\Provider;
use GitList\Util\View;
use Silex\Application;
use Silex\ServiceProviderInterface;
use Pimple\Container;
use Pimple\ServiceProviderInterface;
class ViewUtilServiceProvider implements ServiceProviderInterface
{
/**
* Register the Util\Interface class on the Application ServiceProvider
*
* @param Application $app Silex Application
*/
public function register(Application $app)
{
$app['util.view'] = $app->share(function () {
return new View;
});
}
public function boot(Application $app)
public function register(Container $container)
{
$container['util.view'] = function () {
return new View();
};
}
}

View File

@@ -8,7 +8,7 @@ class Repository
{
protected $app;
protected $defaultFileTypes = array(
protected $defaultFileTypes = [
'php' => 'php',
'c' => 'clike',
'h' => 'clike',
@@ -94,14 +94,14 @@ class Repository
'jpeg' => 'image',
'bmp' => 'image',
'csproj' => 'xml',
);
];
protected static $binaryTypes = array(
protected static $binaryTypes = [
'exe', 'com', 'so', 'la', 'o', 'dll', 'pyc',
'jpg', 'jpeg', 'bmp', 'gif', 'png', 'xmp', 'pcx', 'svgz', 'ttf', 'tiff', 'oet',
'gz', 'tar', 'rar', 'zip', '7z', 'jar', 'class',
'odt', 'ods', 'pdf', 'doc', 'docx', 'dot', 'xls', 'xlsx',
);
];
public function __construct(Application $app)
{
@@ -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
* GitList, to properly highlight the blob syntax (if it's a source-code)
*
* @param string $file File name
*
* @return mixed File type
*/
public function getFileType($file)
@@ -143,7 +144,7 @@ class Repository
*
* @param string $file
*
* @return boolean
* @return bool
*/
public function isBinary($file)
{
@@ -164,35 +165,41 @@ class Repository
return false;
}
public function getReadme($repository, $branch = null, $path = "")
public function getReadme($repository, $branch = null, $path = '')
{
if ($branch === null) {
$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) {
if (preg_match('/^readme*/i', $file['name'])) {
return array(
return [
'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
if ($path != "") return $this->getReadme($repository, $branch, "");
return array();
if ($path != '') {
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 string $branch
* @param string $tree
*
* @return array
*/
public function extractRef($repository, $branch = '', $tree = '')
@@ -202,13 +209,13 @@ class Repository
$input = $branch . '/' . $tree;
// 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];
} else {
// 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());
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]);
}
}
@@ -223,7 +230,6 @@ class Repository
}
}
return array($branch, $tree);
return [$branch, $tree];
}
}

View File

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

View File

@@ -5,24 +5,25 @@ namespace GitList\Util;
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
*
* @return array Array with parts of the breadcrumb
*/
public function getBreadcrumbs($spec)
{
if (!$spec) {
return array();
return [];
}
$paths = explode('/', $spec);
foreach ($paths as $i => $path) {
$breadcrumbs[] = array(
$breadcrumbs[] = [
'dir' => $path,
'path' => implode('/', array_slice($paths, 0, $i + 1)),
);
];
}
return $breadcrumbs;
@@ -31,18 +32,18 @@ class View
public function getPager($pageNumber, $totalCommits)
{
$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.
$lastPage = ($lastPage * 15 == $totalCommits) ? $lastPage - 1 : $lastPage;
$nextPage = $pageNumber + 1;
$previousPage = $pageNumber - 1;
return array('current' => $pageNumber,
return ['current' => $pageNumber,
'next' => $nextPage,
'previous' => $previousPage,
'last' => $lastPage,
'total' => $totalCommits,
);
];
}
}

View File

@@ -1,8 +1,8 @@
<?php
use GitList\Git\Client;
use Silex\WebTestCase;
use Symfony\Component\Filesystem\Filesystem;
use GitList\Git\Client;
class InterfaceTest extends WebTestCase
{
@@ -29,9 +29,10 @@ class InterfaceTest extends WebTestCase
}
$options['path'] = getenv('GIT_CLIENT') ?: '/usr/bin/git';
$options['hidden'] = array(self::$tmpdir . '/hiddenrepo');
$options['hidden'] = [self::$tmpdir . '/hiddenrepo'];
$options['default_branch'] = 'master';
$options['ini.file'] = "config.ini";
$options['ini.file'] = 'config.ini';
$options['projects'] = false;
$cacheDir = self::$tmpdir . DIRECTORY_SEPARATOR . 'cache';
$fs->mkdir($cacheDir);
@@ -48,7 +49,7 @@ class InterfaceTest extends WebTestCase
$repository->setConfig('user.name', 'Luke Skywalker');
$repository->setConfig('user.email', 'luke@rebel.org');
$repository->addAll();
$repository->commit("Initial commit");
$repository->commit('Initial commit');
$repository->createBranch('issue12');
$repository->createBranch('issue42');
$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!');
$fs->mkdir(self::$tmpdir . 'foobar/myfolder');
$fs->mkdir(self::$tmpdir . 'foobar/testfolder');
file_put_contents(self::$tmpdir . 'foobar/myfolder/mytest.php',
"<?php\necho 'Hello World'; // This is my test");
file_put_contents(self::$tmpdir . 'foobar/testfolder/test.php',
"<?php\necho 'Hello World'; // This is a test");
file_put_contents(
self::$tmpdir . 'foobar/myfolder/mytest.php',
"<?php\necho 'Hello World'; // This is my test"
);
file_put_contents(
self::$tmpdir . 'foobar/testfolder/test.php',
"<?php\necho 'Hello World'; // This is a test"
);
$repository->setConfig('user.name', 'Luke Skywalker');
$repository->setConfig('user.email', 'luke@rebel.org');
$repository->addAll();
$repository->commit("First commit");
$repository->commit('First commit');
// Nested repository fixture
$nested_dir = self::$tmpdir . 'nested/';
@@ -80,13 +85,13 @@ class InterfaceTest extends WebTestCase
$repository->setConfig('user.name', 'Luke Skywalker');
$repository->setConfig('user.email', 'luke@rebel.org');
$repository->addAll();
$repository->commit("First commit");
$repository->createBranch("testing");
$repository->checkout("testing");
$repository->commit('First commit');
$repository->createBranch('testing');
$repository->checkout('testing');
file_put_contents($nested_dir . 'NestedRepo/README.txt', 'NESTED TEST BRANCH README');
$repository->addAll();
$repository->commit("Changing branch");
$repository->checkout("master");
$repository->commit('Changing branch');
$repository->checkout('master');
// master-less repository fixture
$git->createRepository(self::$tmpdir . 'develop');
@@ -95,15 +100,15 @@ class InterfaceTest extends WebTestCase
$repository->setConfig('user.email', 'luke@rebel.org');
file_put_contents(self::$tmpdir . 'develop/README.md', "## develop\ndevelop is a *test* repository!");
$repository->addAll();
$repository->commit("First commit");
$repository->createBranch("develop");
$repository->commit('First commit');
$repository->createBranch('develop');
$repository = $repository->checkout('develop');
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.email', 'luke@rebel.org');
$repository->addAll();
$repository->commit("Initial commit");
$repository->commit('Initial commit');
// Detached HEAD repository fixture
$git->createRepository(self::$tmpdir . 'detached-head');
@@ -112,7 +117,7 @@ class InterfaceTest extends WebTestCase
$repository->setConfig('user.email', 'luke@rebel.org');
file_put_contents(self::$tmpdir . 'detached-head/README.md', "## detached head\ndetached-head is a *test* repository!");
$repository->addAll();
$repository->commit("First commit");
$repository->commit('First commit');
$repository->checkout('HEAD');
// mailmap repository fixture
@@ -121,26 +126,33 @@ class InterfaceTest extends WebTestCase
$repository->setConfig('user.name', 'Luke Skywalker');
$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/.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->commit("First commit");
$repository->commit('First commit');
}
public static function tearDownAfterClass()
{
$fs = new Filesystem();
$fs->remove(self::$tmpdir);
}
public function createApplication()
{
$config = new GitList\Config;
$config = new GitList\Config();
$config->set('app', 'debug', true);
$config->set('app', 'debug', false);
$config->set('git', 'client', self::$gitPath);
$config->set('git', 'default_branch', 'master');
$config->set('git', 'repositories', array(self::$tmpdir));
$config->set('git', 'repositories', [self::$tmpdir]);
$app = require 'boot.php';
return $app;
}
/**
* @covers GitList\Controller\MainController::connect
* @covers \GitList\Controller\MainController::connect
*/
public function testInitialPage()
{
@@ -178,7 +190,7 @@ class InterfaceTest extends WebTestCase
}
/**
* @covers GitList\Controller\TreeController::connect
* @covers \GitList\Controller\TreeController::connect
*/
public function testRepositoryPage()
{
@@ -211,7 +223,7 @@ class InterfaceTest extends WebTestCase
}
/**
* @covers GitList\Controller\BlobController::connect
* @covers \GitList\Controller\BlobController::connect
*/
public function testBlobPage()
{
@@ -221,18 +233,26 @@ class InterfaceTest extends WebTestCase
$this->assertTrue($client->getResponse()->isOk());
$this->assertCount(1, $crawler->filter('.breadcrumb .active:contains("test.php")'));
$this->assertEquals('/GitTest/raw/master/test.php',
$crawler->filter('.source-header .btn-group a')->eq(0)->attr('href'));
$this->assertEquals('/GitTest/blame/master/test.php',
$crawler->filter('.source-header .btn-group a')->eq(1)->attr('href'));
$this->assertEquals('/GitTest/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'));
$this->assertEquals(
'/GitTest/raw/master/test.php',
$crawler->filter('.source-header .btn-group a')->eq(0)->attr('href')
);
$this->assertEquals(
'/GitTest/blame/master/test.php',
$crawler->filter('.source-header .btn-group a')->eq(1)->attr('href')
);
$this->assertEquals(
'/GitTest/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()
{
@@ -244,7 +264,7 @@ class InterfaceTest extends WebTestCase
}
/**
* @covers GitList\Controller\CommitController::connect
* @covers \GitList\Controller\CommitController::connect
*/
public function testBlamePage()
{
@@ -253,18 +273,22 @@ class InterfaceTest extends WebTestCase
$crawler = $client->request('GET', '/GitTest/blame/master/test.php');
$this->assertTrue($client->getResponse()->isOk());
$this->assertCount(1, $crawler->filter('.source-header .meta:contains("test.php")'));
$this->assertRegexp('/\/GitTest\/commit\/[a-zA-Z0-9%]+/',
$crawler->filter('.blame-view .commit')->eq(0)->filter('a')->attr('href'));
$this->assertRegexp(
'/\/GitTest\/commit\/[a-zA-Z0-9%]+/',
$crawler->filter('.blame-view .commit')->eq(0)->filter('a')->attr('href')
);
$crawler = $client->request('GET', '/foobar/blame/master/bar.json');
$this->assertTrue($client->getResponse()->isOk());
$this->assertCount(1, $crawler->filter('.source-header .meta:contains("bar.json")'));
$this->assertRegexp('/\/foobar\/commit\/[a-zA-Z0-9%]+/',
$crawler->filter('.blame-view .commit')->eq(0)->filter('a')->attr('href'));
$this->assertRegexp(
'/\/foobar\/commit\/[a-zA-Z0-9%]+/',
$crawler->filter('.blame-view .commit')->eq(0)->filter('a')->attr('href')
);
}
/**
* @covers GitList\Controller\CommitController::connect
* @covers \GitList\Controller\CommitController::connect
*/
public function testHistoryPage()
{
@@ -289,7 +313,7 @@ class InterfaceTest extends WebTestCase
}
/**
* @covers GitList\Controller\CommitController::connect
* @covers \GitList\Controller\CommitController::connect
*/
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'));
}
public function testPatchLogPage()
{
$client = $this->createClient();
@@ -327,9 +350,8 @@ class InterfaceTest extends WebTestCase
$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()
{
@@ -348,7 +370,7 @@ class InterfaceTest extends WebTestCase
}
/**
* @covers GitList\Controller\MainController::connect
* @covers \GitList\Controller\MainController::connect
*/
public function testRssPage()
{
@@ -363,7 +385,7 @@ class InterfaceTest extends WebTestCase
}
/**
* @covers GitList\Controller\TreeController::connect
* @covers \GitList\Controller\TreeController::connect
*/
public function testNestedRepoPage()
{
@@ -377,7 +399,7 @@ class InterfaceTest extends WebTestCase
}
/**
* @covers GitList\Controller\TreeController::connect
* @covers \GitList\Controller\TreeController::connect
*/
public function testDevelopRepo()
{
@@ -388,7 +410,7 @@ class InterfaceTest extends WebTestCase
}
/**
* @covers GitList\Controller\TreeController::connect
* @covers \GitList\Controller\TreeController::connect
*/
public function testNestedRepoBranch()
{
@@ -398,11 +420,4 @@ class InterfaceTest extends WebTestCase
$this->assertTrue($client->getResponse()->isOk());
$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" />
<title>{% block title %}Welcome!{% endblock %}</title>
<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="{{ app.request.basepath }}/themes/{{ app.theme }}/css/fontawesome.css">
<link rel="stylesheet" type="text/css" href="{{ app.request.basepath }}/themes/{{ app.theme }}/css/gitgraph.css">
<link rel="shortcut icon" type="image/png" href="{{ app.request.basepath }}/themes/{{ app.theme }}/img/favicon.png" />
<link rel="stylesheet" type="text/css" href="{{ global.request.basepath }}/themes/{{ theme }}/css/style.css">
<link rel="stylesheet" type="text/css" href="{{ global.request.basepath }}/themes/{{ theme }}/css/fontawesome.css">
<link rel="stylesheet" type="text/css" href="{{ global.request.basepath }}/themes/{{ theme }}/css/gitgraph.css">
<link rel="shortcut icon" type="image/png" href="{{ global.request.basepath }}/themes/{{ theme }}/img/favicon.png" />
<!--[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]-->
</head>
<body>
{% block body %}{% endblock %}
{% block javascripts %}
<script src="{{ app.request.basepath }}/themes/{{ app.theme }}/js/jquery.js"></script>
<script src="{{ app.request.basepath }}/themes/{{ app.theme }}/js/raphael.js"></script>
<script src="{{ app.request.basepath }}/themes/{{ app.theme }}/js/bootstrap.js"></script>
<script src="{{ app.request.basepath }}/themes/{{ app.theme }}/js/codemirror.js"></script>
<script src="{{ app.request.basepath }}/themes/{{ app.theme }}/js/showdown.js"></script>
<script src="{{ app.request.basepath }}/themes/{{ app.theme }}/js/table.js"></script>
<script src="{{ app.request.basepath }}/themes/{{ app.theme }}/js/main.js"></script>
<script src="{{ app.request.basepath }}/themes/{{ app.theme }}/js/networkGraph.js"></script>
<script src="{{ app.request.basepath }}/themes/{{ app.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/jquery.js"></script>
<script src="{{ global.request.basepath }}/themes/{{ theme }}/js/raphael.js"></script>
<script src="{{ global.request.basepath }}/themes/{{ theme }}/js/bootstrap.js"></script>
<script src="{{ global.request.basepath }}/themes/{{ theme }}/js/codemirror.js"></script>
<script src="{{ global.request.basepath }}/themes/{{ theme }}/js/showdown.js"></script>
<script src="{{ global.request.basepath }}/themes/{{ theme }}/js/table.js"></script>
<script src="{{ global.request.basepath }}/themes/{{ theme }}/js/main.js"></script>
<script src="{{ global.request.basepath }}/themes/{{ theme }}/js/networkGraph.js"></script>
<script src="{{ global.request.basepath }}/themes/{{ theme }}/js/gitgraph.js"></script>
<script src="{{ global.request.basepath }}/themes/{{ theme }}/js/draw.js"></script>
{% endblock %}
</body>
</html>

View File

@@ -8,11 +8,11 @@
<div class="col-sm-12">
<div class="tab-border nav-tabs">
{% 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...">
</form>
{% 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...">
</form>
{% endif %}

View File

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

View File

@@ -9,7 +9,7 @@
{% block extra %}
<div class="pull-right">
<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>
{% 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>

View File

@@ -9,7 +9,7 @@
{% block extra %}
<div class="pull-right">
<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>
{% 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>
@@ -19,23 +19,23 @@
<a href="{{ path('rss', {repo: repo, branch: branch}) }}"><span class="fa fa-rss rss-icon"></span></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-inner-wrapper">
<a class="close" href="#" id="clone-button-hide">&times;</a>
<div class="btn-group">
{% if app.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>
{% if show_ssh_remote %}
<button type="button" class="btn btn-default{{ show_ssh_remote and show_http_remote ? ' active' }}" id="clone-button-ssh">SSH</button>
{% endif %}
{% if app.show_http_remote %}
<button type="button" class="btn btn-default" id="clone-button-http">HTTP{{ app.use_https ? 'S' }}</button>
{% if show_http_remote %}
<button type="button" class="btn btn-default" id="clone-button-http">HTTP{{ use_https ? 'S' }}</button>
{% endif %}
</div><br />
{% if app.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 }}">
{% if show_ssh_remote %}
<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 %}
{% if app.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 }}">
{% if show_http_remote %}
<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 %}
</div>
</div>

View File

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

View File

@@ -7,11 +7,11 @@
<div class="row">
<div class="span12">
{% 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("") }}">
</form>
{% 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("") }}">
</form>
{% endif %}

View File

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

View File

@@ -9,7 +9,7 @@
{% block extra %}
<div class="pull-right">
<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>
{% endif %}
<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>
<a href="{{ path('rss', {repo: repo, branch: branch}) }}" class="rss-icon"><i class="rss"></i></a>
</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-inner-wrapper">
<a class="close" href="#" id="clone-button-hide">&times;</a>
<div class="btn-group">
{% if app.show_ssh_remote %}
<button class="btn{{ app.show_ssh_remote and app.show_http_remote ? ' active' }}" id="clone-button-ssh">SSH</button>
{% if show_ssh_remote %}
<button class="btn{{ show_ssh_remote and show_http_remote ? ' active' }}" id="clone-button-ssh">SSH</button>
{% endif %}
{% if app.show_http_remote %}
<button class="btn" id="clone-button-http">HTTP{{ app.use_https ? 'S' }}</button>
{% if show_http_remote %}
<button class="btn" id="clone-button-http">HTTP{{ use_https ? 'S' }}</button>
{% endif %}
</div><br />
{% if app.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 }}">
{% if show_ssh_remote %}
<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 %}
{% if app.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 }}">
{% if show_http_remote %}
<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 %}
</div>
</div>