mirror of
https://github.com/klaussilveira/gitlist.git
synced 2025-11-17 11:10:57 +01:00
Merged master branch to multidir branch.
This commit is contained in:
30
build.xml
30
build.xml
@@ -1,6 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project name="gitlist" default="build">
|
||||
<target name="build" depends="prepare,lint,phploc,pdepend,phpmd,phpcpd,phpunit,package" />
|
||||
<target name="build" depends="prepare,lint,phploc,pdepend,phpmd,phpcpd,phpunit" />
|
||||
<target name="build-package" depends="prepare-package,lint,phploc,package" />
|
||||
|
||||
<target name="clean" description="Clean build artifacts">
|
||||
<delete dir="${basedir}/build"/>
|
||||
@@ -15,6 +16,12 @@
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
<target name="prepare-package" depends="clean" description="Prepare for build">
|
||||
<exec executable="composer" failonerror="true">
|
||||
<arg value="install" />
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
<target name="lint" description="Perform syntax check of sourcecode files">
|
||||
<apply executable="php" failonerror="true">
|
||||
<arg value="-l" />
|
||||
@@ -32,9 +39,7 @@
|
||||
<exec executable="phploc">
|
||||
<arg value="--log-csv" />
|
||||
<arg value="${basedir}/build/logs/phploc.csv" />
|
||||
<arg value="--exclude" />
|
||||
<arg value="${basedir}/cache,${basedir}/vendor" />
|
||||
<arg path="${basedir}/" />
|
||||
<arg path="${basedir}/src" />
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
@@ -44,19 +49,17 @@
|
||||
<arg value="--jdepend-chart=${basedir}/build/pdepend/dependencies.svg" />
|
||||
<arg value="--overview-pyramid=${basedir}/build/pdepend/overview-pyramid.svg" />
|
||||
<arg value="--ignore=${basedir}/cache,${basedir}/vendor" />
|
||||
<arg path="${basedir}/" />
|
||||
<arg path="${basedir}/src" />
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
<target name="phpmd" description="Perform project mess detection using PHPMD creating a log file for the continuous integration server">
|
||||
<exec executable="phpmd">
|
||||
<arg path="${basedir}/" />
|
||||
<arg path="${basedir}/src" />
|
||||
<arg value="xml" />
|
||||
<arg value="codesize,design,unusedcode,naming" />
|
||||
<arg value="--reportfile" />
|
||||
<arg value="${basedir}/build/logs/pmd.xml" />
|
||||
<arg value="--exclude" />
|
||||
<arg value="${basedir}/cache,${basedir}/vendor" />
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
@@ -64,9 +67,7 @@
|
||||
<exec executable="phpcpd">
|
||||
<arg value="--log-pmd" />
|
||||
<arg value="${basedir}/build/logs/pmd-cpd.xml" />
|
||||
<arg value="--exclude" />
|
||||
<arg value="${basedir}/cache,${basedir}/vendor" />
|
||||
<arg path="${basedir}/" />
|
||||
<arg path="${basedir}/src" />
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
@@ -75,9 +76,12 @@
|
||||
</target>
|
||||
|
||||
<target name="package" description="Package the application for distribution">
|
||||
<copy todir="${basedir}/build/gitlist/">
|
||||
<fileset dir="${basedir}" excludes="build/**, tests/**, pkg_builder/**, phpunit.xml.dist, cache.properties, .gitignore, .travis.yml, build.xml, composer.json, composer.lock, config.ini" />
|
||||
</copy>
|
||||
|
||||
<tar destfile="${basedir}/build/gitlist.tar.gz"
|
||||
basedir="${basedir}/"
|
||||
excludes="build/**, tests/**, phpunit.xml.dist, cache.properties, .gitignore, .travis.yml, build.xml, composer.json, composer.lock, config.ini"
|
||||
basedir="${basedir}/build/"
|
||||
compression="gzip"
|
||||
longfile="gnu"
|
||||
/>
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
{
|
||||
"require": {
|
||||
"silex/silex": "1.0.*",
|
||||
"twig/twig": "1.9.*",
|
||||
"symfony/twig-bridge": "2.1.*",
|
||||
"symfony/filesystem": "2.1.*",
|
||||
"klaussilveira/gitter": "dev-master"
|
||||
"silex/silex": "1.0.*@dev",
|
||||
"twig/twig": "1.12.*",
|
||||
"symfony/twig-bridge": "2.2.*",
|
||||
"symfony/filesystem": "2.2.*",
|
||||
"klaussilveira/gitter": "0.1.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/browser-kit": "2.1.*",
|
||||
"symfony/css-selector": "2.1.*"
|
||||
"symfony/browser-kit": "2.2.*",
|
||||
"symfony/css-selector": "2.2.*",
|
||||
"phpunit/phpunit": "3.7.*",
|
||||
"phpmd/phpmd": "1.4.*",
|
||||
"phploc/phploc": "1.7.*"
|
||||
},
|
||||
"minimum-stability": "dev",
|
||||
"autoload": {
|
||||
|
||||
1139
composer.lock
generated
1139
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,7 @@
|
||||
[git]
|
||||
client = '/usr/bin/git' ; Your git executable path
|
||||
repositories = '/var/www/projects/' ; Path to your repositories
|
||||
default_branch = 'master' ; Default branch when HEAD is detached
|
||||
|
||||
|
||||
;Windows Users
|
||||
|
||||
147
pkg_builder/Makefile
Normal file
147
pkg_builder/Makefile
Normal file
@@ -0,0 +1,147 @@
|
||||
# Main Info
|
||||
NAME = gitlist
|
||||
DESCRIPTION = "An elegant and modern git repository viewer"
|
||||
LICENSE = New BSD
|
||||
GROUP = gitlist
|
||||
VENDOR = gitlist.org
|
||||
URL = "http://www.gitlist.org"
|
||||
|
||||
#BUILD Info
|
||||
PREFIX = /usr/share
|
||||
PROJROOT = "$(shell pwd)"
|
||||
SRCROOT = "$(shell pwd)/gitlist"
|
||||
UPSTREAM_VERSION = $(shell cat tools/release.info | head -n1 | cut -d"=" -f2)
|
||||
BUILD_STAMP = $(shell date +"%Y%m%d%H%M%S")
|
||||
|
||||
#Packager Info
|
||||
PACKAGER = $(shell git config user.name)
|
||||
PACKAGER_MAIL = $(shell git config user.email)
|
||||
|
||||
#Debian Package Info
|
||||
PACKAGE-VERSION= 1
|
||||
DEBIAN_BUILD_ROOT = ${PROJROOT}/debian/
|
||||
PROJECT_DEBIAN_LIKE_NAME=$(shell cat tools/release.info | grep name | cut -d"=" -f2)
|
||||
DEBIAN_NAME=$(PROJECT_DEBIAN_LIKE_NAME)$(shell echo "_")$(UPSTREAM_VERSION)-${PACKAGE-VERSION}$(shell echo "_all.deb")
|
||||
DEBIAN_VERSION =
|
||||
# Generating control file
|
||||
define control
|
||||
Package: $(PROJECT_DEBIAN_LIKE_NAME)
|
||||
Version: $(UPSTREAM_VERSION)-${PACKAGE-VERSION}
|
||||
Architecture: all
|
||||
Section: web
|
||||
Priority: optional
|
||||
Maintainer: "${PACKAGER} <${PACKAGER_MAIL}>"
|
||||
Description: ${DESCRIPTION}
|
||||
endef
|
||||
export control
|
||||
|
||||
all:
|
||||
@echo "... $(UPSTREAM_VERSION)"
|
||||
@echo "... $(PACKAGER)"
|
||||
@echo "... $(PACKAGER_MAIL)"
|
||||
@echo "... $(DEBIAN_NAME)"
|
||||
|
||||
help:
|
||||
@echo "To use this make file just:"
|
||||
@echo "Download the gitlist tarball and stract it into a folder called gitlist"
|
||||
@echo "make [build_deb|build_rpm|build(apache|nginx|lighthttp)]"
|
||||
|
||||
clean_deb:
|
||||
@echo "Cleaning . . ."
|
||||
@rm -rf ${DEBIAN_BUILD_ROOT}/*.deb
|
||||
@rm -rf ${PROJROOT}/debian
|
||||
|
||||
prepare_deb: clean_deb
|
||||
@echo "############################### - Building DEB"
|
||||
@mkdir ${DEBIAN_BUILD_ROOT} -pv
|
||||
@mkdir ${DEBIAN_BUILD_ROOT}/DEBIAN -pv
|
||||
@mkdir ${DEBIAN_BUILD_ROOT}${PREFIX}/${PROJECT_DEBIAN_LIKE_NAME} -pv
|
||||
|
||||
copy_deb_files: prepare_deb
|
||||
@echo "$$control" > ${DEBIAN_BUILD_ROOT}/DEBIAN/control
|
||||
|
||||
copy_deb: copy_deb_files
|
||||
@echo Sync files
|
||||
@rsync -avz ${SRCROOT} ${DEBIAN_BUILD_ROOT}${PREFIX}/
|
||||
|
||||
md5sum_deb: copy_deb
|
||||
@cd debian; find . -type f ! -regex '.*\.hg.*' ! -regex '.*?debian-binary.*' ! -regex '.*?DEBIAN.*' | xargs -d "\n" md5sum > DEBIAN/md5sums
|
||||
|
||||
deb_uniq: md5sum_deb
|
||||
@mkdir ${PROJROOT}/pkg -p
|
||||
@dpkg -b debian $(DEBIAN_NAME);
|
||||
@mv $(DEBIAN_NAME) ${PROJROOT}/pkg/
|
||||
@rm debian -rf
|
||||
@echo '### Wrote $(DEBIAN_NAME) in ${PROJROOT}/pkg/ . . . . . Success'
|
||||
|
||||
|
||||
build_deb: deb_uniq
|
||||
|
||||
#### RPM STUFF
|
||||
|
||||
RPM_NAME=$(PROJECT_DEBIAN_LIKE_NAME)$(shell echo "_")$(UPSTREAM_VERSION)-${PACKAGE-VERSION}$(shell echo "_all.rpm")
|
||||
|
||||
DIST_DIR = dist
|
||||
TAR_DIR = tar
|
||||
|
||||
RPM_DIR = rpm
|
||||
RPM_DIRS = SPECS RPMS SOURCES BUILD
|
||||
|
||||
clean_rpm:
|
||||
@echo Cleaning temporary dirs...
|
||||
@rm -rf $(TAR_DIR)
|
||||
@rm -rf $(RPM_DIR)
|
||||
@rm -rf $(DIST_DIR)
|
||||
|
||||
rpm_init: clean_rpm
|
||||
@echo Creating directories...
|
||||
@echo $(DIST_DIR)
|
||||
@mkdir -p $(DIST_DIR)
|
||||
@for dir in $(RPM_DIRS); do \
|
||||
echo $(RPM_DIR)/$$dir; \
|
||||
mkdir -p $(RPM_DIR)/$$dir; \
|
||||
done
|
||||
|
||||
rpm_preptar: rpm_init
|
||||
@echo Copying files to generate tar...
|
||||
@echo creating directory: $(TAR_DIR)/
|
||||
@mkdir $(TAR_DIR)/ -p
|
||||
@rsync -avz --exclude ".git" --exclude ".gitignore" --exclude "builder" gitlist $(TAR_DIR)/
|
||||
|
||||
rpm_tar: rpm_preptar
|
||||
@echo Generating tarball...
|
||||
@cd $(PROJROOT)/$(TAR_DIR); \
|
||||
tar cf $(PROJROOT)/$(RPM_DIR)/SOURCES/$(NAME).tar .
|
||||
|
||||
rpm: rpm_tar
|
||||
@echo Calling rpmbuild...
|
||||
@echo Vesion: $(VERSION)
|
||||
@cp tools/$(NAME).spec $(RPM_DIR)/SPECS/
|
||||
|
||||
@cd $(PROJROOT)/$(RPM_DIR)/SPECS ; \
|
||||
rpmbuild -bb \
|
||||
--buildroot="$(PROJROOT)/$(RPM_DIR)/BUILD/$(NAME)" \
|
||||
--define "_topdir $(PROJROOT)/$(RPM_DIR)" \
|
||||
--define "name $(NAME)" \
|
||||
--define "summary "$(DESCRIPTION)"" \
|
||||
--define "version $(UPSTREAM_VERSION)" \
|
||||
--define "release $(PACKAGE-VERSION)" \
|
||||
--define "url _$(URL)_" \
|
||||
--define "license $(LICENSE)" \
|
||||
--define "group $(GROUP)" \
|
||||
--define "vendor $(VENDOR)" \
|
||||
--define "packager $(PACKAGER)" \
|
||||
--define "prefix $(PREFIX)" \
|
||||
--define "source_dir $(PROJROOT)/$(RPM_DIR)/SOURCES" \
|
||||
$(NAME).spec
|
||||
@echo Copying generated RPM to dist dir...
|
||||
@mkdir ${PROJROOT}/pkg -p
|
||||
@cp $(PROJROOT)/$(RPM_DIR)/RPMS/noarch/*.rpm $(PROJROOT)/pkg
|
||||
@rm -rf $(TAR_DIR)
|
||||
@rm -rf $(RPM_DIR)
|
||||
@rm -rf $(DIST_DIR)
|
||||
|
||||
|
||||
|
||||
build_rpm: rpm
|
||||
|
||||
46
pkg_builder/README.md
Normal file
46
pkg_builder/README.md
Normal file
@@ -0,0 +1,46 @@
|
||||
# GitList Builder: Tools to build gitlist package
|
||||
|
||||
## Status
|
||||
|
||||
### Ready to build
|
||||
|
||||
* Core Deb Packages:
|
||||
```
|
||||
$ make build_deb
|
||||
```
|
||||
|
||||
* Core Rpm Packages:
|
||||
```
|
||||
$ make build_rpm
|
||||
```
|
||||
|
||||
### Not Ready (Comming soon)
|
||||
|
||||
Packages to install configuration files:
|
||||
|
||||
* make apache_deb
|
||||
* make apache_rpm
|
||||
* make nginx_deb
|
||||
* make nginx_rpm
|
||||
|
||||
## Dependencies
|
||||
|
||||
* To use this package builder you may need to install some development packages like: dpkg-dev or evem rpm;
|
||||
* A tarball of a stable release;
|
||||
|
||||
## Instructions
|
||||
|
||||
To use this builder just download the lastest stable release into this directory and build using the make functions avaible in make help
|
||||
|
||||
## How to build
|
||||
|
||||
The packages can be generated by running Makefile functions like:
|
||||
|
||||
```
|
||||
$ make build_deb
|
||||
$ make build_rpm
|
||||
```
|
||||
|
||||
## Structure
|
||||
|
||||
Core package is a simple source package while a configuration package requires all the dependencies.
|
||||
37
pkg_builder/tools/gitlist.spec
Normal file
37
pkg_builder/tools/gitlist.spec
Normal file
@@ -0,0 +1,37 @@
|
||||
Name: %{name}
|
||||
Summary: %{summary}
|
||||
Version: %{version}
|
||||
Release: %{release}
|
||||
URL: %{url}
|
||||
License: %{license}
|
||||
Group: %{group}
|
||||
Vendor: %{vendor}
|
||||
Packager: %{user}
|
||||
Prefix: %{prefix}
|
||||
BuildArch: noarch
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
|
||||
Source0: %{name}.tar
|
||||
|
||||
%description
|
||||
%{summary}
|
||||
|
||||
%prep
|
||||
%setup -c
|
||||
|
||||
%build
|
||||
|
||||
%install
|
||||
%{__rm} -rf %{buildroot}
|
||||
%{__mkdir} -p %{buildroot}%{prefix}
|
||||
%{__cp} -Ra * %{buildroot}%{prefix}
|
||||
|
||||
%clean
|
||||
rm -rf %{buildroot}
|
||||
|
||||
%files
|
||||
%defattr(0755,root,root)
|
||||
%{prefix}/*
|
||||
|
||||
%changelog
|
||||
* Thu Jan 21 2013 Bruno Gurgel <bruno.gurgel@gmail.com>
|
||||
- Initial
|
||||
2
pkg_builder/tools/release.info
Normal file
2
pkg_builder/tools/release.info
Normal file
@@ -0,0 +1,2 @@
|
||||
release=0.3
|
||||
name=gitlist
|
||||
@@ -55,6 +55,7 @@ class Application extends SilexApplication
|
||||
'ini.file' => "config.ini",
|
||||
'git.hidden' => $config->get('git', 'hidden') ?
|
||||
$config->get('git', 'hidden') : array(),
|
||||
'git.default_branch' => $config->get('git', 'default_branch') ? $config->get('git', 'default_branch') : 'master',
|
||||
));
|
||||
|
||||
$cached_repos = $root . DIRECTORY_SEPARATOR .
|
||||
@@ -66,9 +67,8 @@ class Application extends SilexApplication
|
||||
$this->register(new UrlGeneratorServiceProvider());
|
||||
$this->register(new RoutingUtilServiceProvider());
|
||||
|
||||
$this['twig'] = $this->share($this->extend('twig', function($twig, $app) {
|
||||
$twig->addFilter('htmlentities',
|
||||
new \Twig_Filter_Function('htmlentities'));
|
||||
$this['twig'] = $this->share($this->extend('twig', function ($twig, $app) {
|
||||
$twig->addFilter('htmlentities', new \Twig_Filter_Function('htmlentities'));
|
||||
$twig->addFilter('md5', new \Twig_Filter_Function('md5'));
|
||||
|
||||
return $twig;
|
||||
|
||||
@@ -6,11 +6,13 @@ class Config
|
||||
{
|
||||
protected $data;
|
||||
|
||||
public static function fromFile($file) {
|
||||
public static function fromFile($file)
|
||||
{
|
||||
if (!file_exists($file)) {
|
||||
die(sprintf('Please, create the %1$s file.', $file));
|
||||
}
|
||||
$data = parse_ini_file($file, true);
|
||||
|
||||
return new static($data);
|
||||
}
|
||||
|
||||
|
||||
@@ -12,9 +12,12 @@ class BlobController implements ControllerProviderInterface
|
||||
{
|
||||
$route = $app['controllers_factory'];
|
||||
|
||||
$route->get('{repo}/blob/{branch}/{file}', function($repo, $branch, $file) use ($app) {
|
||||
$route->get('{repo}/blob/{commitishPath}', function ($repo, $commitishPath) use ($app) {
|
||||
$repository = $app['git']->getRepository($app['git.repos'], $repo);
|
||||
|
||||
list($branch, $file) = $app['util.routing']
|
||||
->parseCommitishPathParam($commitishPath, $repo);
|
||||
|
||||
list($branch, $file) = $app['util.repository']->extractRef($repository, $branch, $file);
|
||||
|
||||
$blob = $repository->getBlob("$branch:\"$file\"");
|
||||
@@ -39,15 +42,18 @@ class BlobController implements ControllerProviderInterface
|
||||
'branches' => $repository->getBranches(),
|
||||
'tags' => $repository->getTags(),
|
||||
));
|
||||
})->assert('file', '.+')
|
||||
->assert('repo', $app['util.routing']->getRepositoryRegex())
|
||||
->assert('branch', '[\w-._\/]+')
|
||||
})->assert('repo', $app['util.routing']->getRepositoryRegex())
|
||||
->assert('commitishPath', '.+')
|
||||
->bind('blob');
|
||||
|
||||
$route->get('{repo}/raw/{branch}/{file}', function($repo, $branch, $file) use ($app) {
|
||||
$route->get('{repo}/raw/{commitishPath}', function ($repo, $commitishPath) use ($app) {
|
||||
$repository = $app['git']->getRepository($app['git.repos'], $repo);
|
||||
|
||||
list($branch, $file) = $app['util.routing']
|
||||
->parseCommitishPathParam($commitishPath, $repo);
|
||||
|
||||
list($branch, $file) = $app['util.repository']->extractRef($repository, $branch, $file);
|
||||
|
||||
$blob = $repository->getBlob("$branch:\"$file\"")->output();
|
||||
|
||||
$headers = array();
|
||||
@@ -60,9 +66,8 @@ class BlobController implements ControllerProviderInterface
|
||||
}
|
||||
|
||||
return new Response($blob, 200, $headers);
|
||||
})->assert('file', '.+')
|
||||
->assert('repo', $app['util.routing']->getRepositoryRegex())
|
||||
->assert('branch', '[\w-._\/]+')
|
||||
})->assert('repo', $app['util.routing']->getRepositoryRegex())
|
||||
->assert('commitishPath', $app['util.routing']->getCommitishPathRegex())
|
||||
->bind('blob_raw');
|
||||
|
||||
return $route;
|
||||
|
||||
@@ -12,13 +12,16 @@ class CommitController implements ControllerProviderInterface
|
||||
{
|
||||
$route = $app['controllers_factory'];
|
||||
|
||||
$route->get('{repo}/commits/{branch}/{file}', function($repo, $branch, $file) use ($app) {
|
||||
$route->get('{repo}/commits/{commitishPath}', function ($repo, $commitishPath) use ($app) {
|
||||
$repository = $app['git']->getRepository($app['git.repos'], $repo);
|
||||
|
||||
if ($branch === null) {
|
||||
$branch = $repository->getHead();
|
||||
if ($commitishPath === null) {
|
||||
$commitishPath = $repository->getHead();
|
||||
}
|
||||
|
||||
list($branch, $file) = $app['util.routing']
|
||||
->parseCommitishPathParam($commitishPath, $repo);
|
||||
|
||||
list($branch, $file) = $app['util.repository']->extractRef($repository, $branch, $file);
|
||||
|
||||
$type = $file ? "$branch -- \"$file\"" : $branch;
|
||||
@@ -45,13 +48,11 @@ class CommitController implements ControllerProviderInterface
|
||||
'file' => $file,
|
||||
));
|
||||
})->assert('repo', $app['util.routing']->getRepositoryRegex())
|
||||
->assert('branch', '[\w-._\/]+')
|
||||
->assert('file', '.+')
|
||||
->value('branch', null)
|
||||
->value('file', '')
|
||||
->assert('commitishPath', $app['util.routing']->getCommitishPathRegex())
|
||||
->value('commitishPath', null)
|
||||
->bind('commits');
|
||||
|
||||
$route->post('{repo}/commits/{branch}/search', function(Request $request, $repo, $branch) use ($app) {
|
||||
$route->post('{repo}/commits/{branch}/search', function (Request $request, $repo, $branch = '') use ($app) {
|
||||
$repository = $app['git']->getRepository($app['git.repos'], $repo);
|
||||
$query = $request->get('query');
|
||||
|
||||
@@ -74,12 +75,11 @@ class CommitController implements ControllerProviderInterface
|
||||
'query' => $query
|
||||
));
|
||||
})->assert('repo', $app['util.routing']->getRepositoryRegex())
|
||||
->assert('branch', '[\w-._\/]+')
|
||||
->assert('branch', $app['util.routing']->getBranchRegex())
|
||||
->bind('searchcommits');
|
||||
|
||||
$route->get('{repo}/commit/{commit}/', function($repo, $commit) use ($app) {
|
||||
$route->get('{repo}/commit/{commit}', function ($repo, $commit) use ($app) {
|
||||
$repository = $app['git']->getRepository($app['git.repos'], $repo);
|
||||
|
||||
$commit = $repository->getCommit($commit);
|
||||
$branch = $repository->getHead();
|
||||
|
||||
@@ -92,10 +92,12 @@ class CommitController implements ControllerProviderInterface
|
||||
->assert('commit', '[a-f0-9^]+')
|
||||
->bind('commit');
|
||||
|
||||
|
||||
$route->get('{repo}/blame/{branch}/{file}', function($repo, $branch, $file) use ($app) {
|
||||
$route->get('{repo}/blame/{commitishPath}', function ($repo, $commitishPath) use ($app) {
|
||||
$repository = $app['git']->getRepository($app['git.repos'], $repo);
|
||||
|
||||
list($branch, $file) = $app['util.routing']
|
||||
->parseCommitishPathParam($commitishPath, $repo);
|
||||
|
||||
list($branch, $file) = $app['util.repository']->extractRef($repository, $branch, $file);
|
||||
|
||||
$blames = $repository->getBlame("$branch -- \"$file\"");
|
||||
@@ -109,8 +111,7 @@ class CommitController implements ControllerProviderInterface
|
||||
'blames' => $blames,
|
||||
));
|
||||
})->assert('repo', $app['util.routing']->getRepositoryRegex())
|
||||
->assert('file', '.+')
|
||||
->assert('branch', '[\w-._\/]+')
|
||||
->assert('commitishPath', $app['util.routing']->getCommitishPathRegex())
|
||||
->bind('blame');
|
||||
|
||||
return $route;
|
||||
|
||||
@@ -46,16 +46,20 @@ class MainController implements ControllerProviderInterface
|
||||
'branches' => $repository->getBranches(),
|
||||
'tags' => $repository->getTags(),
|
||||
'stats' => $stats,
|
||||
'authors' => $authors,
|
||||
'authors' => $authors,
|
||||
));
|
||||
})->assert('repo', $app['util.routing']->getRepositoryRegex())
|
||||
->assert('branch', '[\w-._\/]+')
|
||||
->assert('branch', $app['util.routing']->getBranchRegex())
|
||||
->value('branch', null)
|
||||
->bind('stats');
|
||||
|
||||
$route->get('{repo}/{branch}/rss/', function($repo, $branch) use ($app) {
|
||||
$repository = $app['git']->getRepository($app['git.repos'], $repo);
|
||||
|
||||
if ($branch === null) {
|
||||
$branch = $repository->getHead();
|
||||
}
|
||||
|
||||
$commits = $repository->getPaginatedCommits($branch);
|
||||
|
||||
$html = $app['twig']->render('rss.twig', array(
|
||||
@@ -66,7 +70,8 @@ class MainController implements ControllerProviderInterface
|
||||
|
||||
return new Response($html, 200, array('Content-Type' => 'application/rss+xml'));
|
||||
})->assert('repo', $app['util.routing']->getRepositoryRegex())
|
||||
->assert('branch', '[\w-._\/]+')
|
||||
->assert('branch', $app['util.routing']->getBranchRegex())
|
||||
->value('branch', null)
|
||||
->bind('rss');
|
||||
|
||||
return $route;
|
||||
|
||||
@@ -13,14 +13,14 @@ class TreeController implements ControllerProviderInterface
|
||||
{
|
||||
$route = $app['controllers_factory'];
|
||||
|
||||
$treeController = function($repo, $branch = '', $tree = '') use ($app) {
|
||||
|
||||
$repository = $app['git']->getRepositoryCached($app['git.repos'], $repo);
|
||||
|
||||
if (!$branch) {
|
||||
$branch = $repository->getHead();
|
||||
$route->get('{repo}/tree/{commitishPath}/', $treeController = function ($repo, $commitishPath = '') use ($app) {
|
||||
$repository = $app['git']->getRepository($app['git.repos'], $repo);
|
||||
if (!$commitishPath) {
|
||||
$commitishPath = $repository->getHead();
|
||||
}
|
||||
|
||||
list($branch, $tree) = $app['util.routing']->parseCommitishPathParam($commitishPath, $repo);
|
||||
|
||||
list($branch, $tree) = $app['util.repository']->extractRef($repository, $branch, $tree);
|
||||
$files = $repository->getTree($tree ? "$branch:\"$tree\"/" : $branch);
|
||||
$breadcrumbs = $app['util.view']->getBreadcrumbs($tree);
|
||||
@@ -43,17 +43,11 @@ class TreeController implements ControllerProviderInterface
|
||||
'tags' => $repository->getTags(),
|
||||
'readme' => $app['util.repository']->getReadme($repository, $branch),
|
||||
));
|
||||
};
|
||||
|
||||
$route->get('{repo}/tree/{branch}/{tree}/', $treeController
|
||||
)->assert('repo', $app['util.routing']->getRepositoryRegex())
|
||||
->assert('branch', '[\w-._\/]+')
|
||||
->assert('tree', '.+')
|
||||
})->assert('repo', $app['util.routing']->getRepositoryRegex())
|
||||
->assert('commitishPath', $app['util.routing']->getCommitishPathRegex())
|
||||
->bind('tree');
|
||||
|
||||
$route->post('{repo}/tree/{branch}/search',
|
||||
function(Request $request, $repo, $branch = '', $tree = '') use ($app) {
|
||||
|
||||
$route->post('{repo}/tree/{branch}/search', function (Request $request, $repo, $branch = '', $tree = '') use ($app) {
|
||||
$repository = $app['git']->getRepository($app['git.repos'], $repo);
|
||||
if (!$branch) {
|
||||
$branch = $repository->getHead();
|
||||
@@ -73,7 +67,7 @@ class TreeController implements ControllerProviderInterface
|
||||
'tags' => $repository->getTags(),
|
||||
));
|
||||
})->assert('repo', $app['util.routing']->getRepositoryRegex())
|
||||
->assert('branch', '[\w-._\/]+')
|
||||
->assert('branch', $app['util.routing']->getBranchRegex())
|
||||
->bind('search');
|
||||
|
||||
|
||||
@@ -109,14 +103,14 @@ class TreeController implements ControllerProviderInterface
|
||||
));
|
||||
})->assert('format', '(zip|tar)')
|
||||
->assert('repo', $app['util.routing']->getRepositoryRegex())
|
||||
->assert('branch', '[\w-._\/]+')
|
||||
->assert('branch', $app['util.routing']->getBranchRegex())
|
||||
->bind('archive');
|
||||
|
||||
|
||||
$route->get('{repo}/{branch}/', function($repo, $branch) use ($app, $treeController) {
|
||||
return $treeController($repo, $branch);
|
||||
})->assert('repo', $app['util.routing']->getRepositoryRegex())
|
||||
->assert('branch', '[\w-._\/]+')
|
||||
->assert('branch', $app['util.routing']->getBranchRegex())
|
||||
->bind('branch');
|
||||
|
||||
$route->get('{repo}/', function($repo) use ($app, $treeController) {
|
||||
|
||||
@@ -6,6 +6,39 @@ use Gitter\Client as BaseClient;
|
||||
|
||||
class Client extends BaseClient
|
||||
{
|
||||
protected $default_branch;
|
||||
|
||||
public function __construct($options = null)
|
||||
{
|
||||
parent::__construct($options);
|
||||
|
||||
if (!isset($options['default_branch'])) {
|
||||
$options['default_branch'] = 'master';
|
||||
}
|
||||
|
||||
$this->setDefaultBranch($options['default_branch']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set default branch as a string.
|
||||
*
|
||||
* @param string $branch Name of branch to use when repo's HEAD is detached.
|
||||
*/
|
||||
protected function setDefaultBranch($branch)
|
||||
{
|
||||
$this->default_branch = $branch;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return name of default branch as a string.
|
||||
*/
|
||||
public function getDefaultBranch()
|
||||
{
|
||||
return $this->default_branch;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new repository on the specified path
|
||||
*
|
||||
|
||||
@@ -10,6 +10,30 @@ use Symfony\Component\Filesystem\Filesystem;
|
||||
|
||||
class Repository extends BaseRepository
|
||||
{
|
||||
/**
|
||||
* Return true if the repo contains this commit.
|
||||
*
|
||||
* @param $commitHash Hash of commit whose existence we want to check
|
||||
* @return boolean Whether or not the commit exists in this repo
|
||||
*/
|
||||
public function hasCommit($commitHash)
|
||||
{
|
||||
$logs = $this->getClient()->run($this, "show $commitHash");
|
||||
$logs = explode("\n", $logs);
|
||||
|
||||
return strpos($logs[0], 'commit') === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current branch, returning a default value when HEAD is detached.
|
||||
*/
|
||||
public function getHead($default = null)
|
||||
{
|
||||
$client = $this->getClient();
|
||||
|
||||
return parent::getHead($client->getDefaultBranch());
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the data from a specific commit
|
||||
*
|
||||
@@ -22,16 +46,21 @@ class Repository extends BaseRepository
|
||||
"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>"
|
||||
. "<date>%at</date><commiter>%cn</commiter><commiter_email>%ce</commiter_email>"
|
||||
. "<commiter_date>%ct</commiter_date>"
|
||||
. "<message><![CDATA[%s]]></message></item>\" $commitHash");
|
||||
|
||||
$logs = explode("\n", $logs);
|
||||
. "<message><![CDATA[%s]]></message>"
|
||||
. "<body><![CDATA[%b]]></body>"
|
||||
. "</item>\" $commitHash"
|
||||
);
|
||||
$xmlEnd = strpos($logs, '</item>') + 7;
|
||||
$commitInfo = substr($logs, 0, $xmlEnd);
|
||||
$commitData = substr($logs, $xmlEnd);
|
||||
$logs = explode("\n", $commitData);
|
||||
array_shift($logs);
|
||||
|
||||
// Read commit metadata
|
||||
$format = new PrettyFormat;
|
||||
$data = $format->parse($logs[0]);
|
||||
$data = $format->parse($commitInfo);
|
||||
$commit = new Commit;
|
||||
$commit->importData($data[0]);
|
||||
|
||||
@@ -88,8 +117,8 @@ class Repository extends BaseRepository
|
||||
/**
|
||||
* Read diff logs and generate a collection of diffs
|
||||
*
|
||||
* @param array $logs Array of log rows
|
||||
* @return array Array of diffs
|
||||
* @param array $logs Array of log rows
|
||||
* @return array Array of diffs
|
||||
*/
|
||||
public function readDiffLogs(array $logs)
|
||||
{
|
||||
@@ -312,7 +341,11 @@ class Repository extends BaseRepository
|
||||
}
|
||||
|
||||
if (($pos = strrpos($file[4], '.')) !== false) {
|
||||
$data['extensions'][] = substr($file[4], $pos);
|
||||
$extension = substr($file[4], $pos);
|
||||
|
||||
if (($pos = strrpos($extension, '/')) === false) {
|
||||
$data['extensions'][] = $extension;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -335,5 +368,25 @@ class Repository extends BaseRepository
|
||||
$fs->mkdir(dirname($output));
|
||||
$this->getClient()->run($this, "archive --format=$format --output=$output $tree");
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if $path exists in $branch; return false otherwise.
|
||||
*
|
||||
* @param string $commitish Commitish reference; branch, tag, SHA1, etc.
|
||||
* @param string $path Path whose existence we want to verify.
|
||||
*
|
||||
* GRIPE Arguably belongs in Gitter, as it's generally useful functionality.
|
||||
* Also, this really may not be the best way to do this.
|
||||
*/
|
||||
public function pathExists($commitish, $path)
|
||||
{
|
||||
$output = $this->getClient()->run($this, "ls-tree $commitish '$path'");
|
||||
|
||||
if (strlen($output) > 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ class GitServiceProvider implements ServiceProviderInterface
|
||||
$options['hidden'] = $app['git.hidden'];
|
||||
$options['ini.file'] = $app['ini.file'];
|
||||
$options['cache.repos'] = $app['cache.repos'];
|
||||
$options['default_branch'] = $app['git.default_branch'];
|
||||
|
||||
return new Client($options);
|
||||
};
|
||||
|
||||
@@ -188,7 +188,7 @@ class Repository
|
||||
* @param string $tree
|
||||
* @return array
|
||||
*/
|
||||
public function extractRef($repository, $branch='', $tree='')
|
||||
public function extractRef($repository, $branch = '', $tree = '')
|
||||
{
|
||||
$branch = trim($branch, '/');
|
||||
$tree = trim($tree, '/');
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace Gitlist\Util;
|
||||
namespace GitList\Util;
|
||||
|
||||
use Silex\Application;
|
||||
|
||||
@@ -13,6 +13,95 @@ class Routing
|
||||
$this->app = $app;
|
||||
}
|
||||
|
||||
/* @brief Return $commitish, $path parsed from $commitishPath, based on
|
||||
* what's in $repo. Raise a 404 if $branchpath does not represent a
|
||||
* valid branch and path.
|
||||
*
|
||||
* A helper for parsing routes that use commit-ish names and paths
|
||||
* separated by /, since route regexes are not enough to get that right.
|
||||
*/
|
||||
public function parseCommitishPathParam($commitishPath, $repo)
|
||||
{
|
||||
$app = $this->app;
|
||||
$repository = $app['git']->getRepository($app['git.repos'], $repo);
|
||||
|
||||
$commitish = null;
|
||||
$path = null;
|
||||
|
||||
$slashPosition = strpos($commitishPath, '/');
|
||||
if (strlen($commitishPath) >= 40 &&
|
||||
($slashPosition === false ||
|
||||
$slashPosition === 40)) {
|
||||
// We may have a commit hash as our commitish.
|
||||
$hash = substr($commitishPath, 0, 40);
|
||||
if ($repository->hasCommit($hash)) {
|
||||
$commitish = $hash;
|
||||
}
|
||||
}
|
||||
|
||||
if ($commitish === null) {
|
||||
// DEBUG Can you have a repo with no branches? How should we handle
|
||||
// that?
|
||||
$branches = $repository->getBranches();
|
||||
|
||||
$tags = $repository->getTags();
|
||||
if ($tags !== null && count($tags) > 0) {
|
||||
$branches = array_merge($branches, $tags);
|
||||
}
|
||||
|
||||
$matchedBranch = null;
|
||||
$matchedBranchLength = 0;
|
||||
foreach ($branches as $branch) {
|
||||
if (strpos($commitishPath, $branch) === 0 &&
|
||||
strlen($branch) > $matchedBranchLength) {
|
||||
$matchedBranch = $branch;
|
||||
$matchedBranchLength = strlen($matchedBranch);
|
||||
}
|
||||
}
|
||||
|
||||
$commitish = $matchedBranch;
|
||||
}
|
||||
|
||||
if ($commitish === null) {
|
||||
$app->abort(404, "'$branch_path' does not appear to contain a commit-ish for '$repo'.");
|
||||
}
|
||||
|
||||
$commitishLength = strlen($commitish);
|
||||
$path = substr($commitishPath, $commitishLength);
|
||||
if (strpos($path, '/') === 0) {
|
||||
$path = substr($path, 1);
|
||||
}
|
||||
|
||||
$commitHasPath = $repository->pathExists($commitish, $path);
|
||||
if ($commitHasPath !== true) {
|
||||
$app->abort(404, "\"$path\" does not exist in \"$commitish\".");
|
||||
}
|
||||
|
||||
return array($commitish, $path);
|
||||
}
|
||||
|
||||
public function getBranchRegex()
|
||||
{
|
||||
static $branchRegex = null;
|
||||
|
||||
if ($branchRegex === null) {
|
||||
$branchRegex = '(?!/|.*([/.]\.|//|@\{|\\\\))[^\040\177 ~^:?*\[]+(?<!\.lock|[/.])';
|
||||
}
|
||||
|
||||
return $branchRegex;
|
||||
}
|
||||
|
||||
public function getCommitishPathRegex()
|
||||
{
|
||||
static $commitishPathRegex = null;
|
||||
|
||||
if ($commitishPathRegex === null) {
|
||||
$commitishPathRegex = '.+';
|
||||
}
|
||||
|
||||
return $commitishPathRegex;
|
||||
}
|
||||
|
||||
public function getRepositoryRegex()
|
||||
{
|
||||
static $regex = null;
|
||||
@@ -31,9 +120,14 @@ class Routing
|
||||
},
|
||||
$this->app['git']->getRepositories($this->app['git.repos'])
|
||||
);
|
||||
usort($quotedPaths, function ($a, $b) {
|
||||
return strlen($b) - strlen($a);
|
||||
});
|
||||
|
||||
usort(
|
||||
$quotedPaths,
|
||||
function ($a, $b) {
|
||||
return strlen($b) - strlen($a);
|
||||
}
|
||||
);
|
||||
|
||||
$regex = implode('|', $quotedPaths);
|
||||
}
|
||||
|
||||
@@ -54,13 +148,14 @@ class Routing
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
public function getRelativePath($repoPath)
|
||||
{
|
||||
if (strpos($repoPath, $this->app['git.repos']) === 0) {
|
||||
$relativePath = substr($repoPath, strlen($this->app['git.repos']));
|
||||
|
||||
return ltrim(strtr($relativePath, '\\', '/'), '/');
|
||||
} else {
|
||||
throw new \InvalidArgumentException(
|
||||
|
||||
@@ -108,6 +108,17 @@ class InterfaceTest extends WebTestCase
|
||||
$repository->addAll();
|
||||
$repository->commit("Initial commit");
|
||||
|
||||
// Detached HEAD repository fixture
|
||||
$git->createRepository(self::$tmpdir . 'detached-head');
|
||||
$repository = $git->getRepositoryCached(self::$tmpdir, 'detached-head');
|
||||
# $repository = $git->getRepository(self::$tmpdir . '/detached-head');
|
||||
$repository->setConfig('user.name', 'Luke Skywalker');
|
||||
$repository->setConfig('user.email', 'luke@rebel.org');
|
||||
file_put_contents(self::$tmpdir . 'detached-head/README.md', "## detached head\ndetached-head is a *test* repository!");
|
||||
$repository->addAll();
|
||||
$repository->commit("First commit");
|
||||
$repository->checkout('HEAD');
|
||||
|
||||
$git->deleteCached();
|
||||
}
|
||||
|
||||
@@ -137,8 +148,8 @@ class InterfaceTest extends WebTestCase
|
||||
$this->assertEquals('/NestedRepo/master/rss/', $crawler->filter('.repository-header a')->eq(3)->attr('href'));
|
||||
$this->assertCount(1, $crawler->filter('div.repository-header:contains("foobar")'));
|
||||
$this->assertCount(1, $crawler->filter('div.repository-body:contains("This is a test repo!")'));
|
||||
$this->assertEquals('/foobar/', $crawler->filter('.repository-header a')->eq(6)->attr('href'));
|
||||
$this->assertEquals('/foobar/master/rss/', $crawler->filter('.repository-header a')->eq(7)->attr('href'));
|
||||
$this->assertEquals('/foobar/', $crawler->filter('.repository-header a')->eq(8)->attr('href'));
|
||||
$this->assertEquals('/foobar/master/rss/', $crawler->filter('.repository-header a')->eq(9)->attr('href'));
|
||||
}
|
||||
|
||||
public function testRepositoryPage()
|
||||
@@ -149,13 +160,10 @@ class InterfaceTest extends WebTestCase
|
||||
$this->assertTrue($client->getResponse()->isOk());
|
||||
$this->assertCount(1, $crawler->filter('.tree tr:contains("README.md")'));
|
||||
$this->assertCount(1, $crawler->filter('.tree tr:contains("test.php")'));
|
||||
$this->assertCount(1, $crawler->filter('.readme-header:contains("README.md")'));
|
||||
$this->assertEquals("## GitTest\nGitTest is a *test* repository!",
|
||||
$crawler->filter('#readme-content')->eq(0)->text());
|
||||
$this->assertEquals('/GitTest/blob/master/README.md',
|
||||
$crawler->filter('.tree tr td')->eq(0)->filter('a')->eq(0)->attr('href'));
|
||||
$this->assertEquals('/GitTest/blob/master/test.php',
|
||||
$crawler->filter('.tree tr td')->eq(3)->filter('a')->eq(0)->attr('href'));
|
||||
$this->assertCount(1, $crawler->filter('.md-header:contains("README.md")'));
|
||||
$this->assertEquals("## GitTest\nGitTest is a *test* repository!", $crawler->filter('#md-content')->eq(0)->text());
|
||||
$this->assertEquals('/GitTest/blob/master/README.md', $crawler->filter('.tree tr td')->eq(0)->filter('a')->eq(0)->attr('href'));
|
||||
$this->assertEquals('/GitTest/blob/master/test.php', $crawler->filter('.tree tr td')->eq(3)->filter('a')->eq(0)->attr('href'));
|
||||
|
||||
$this->assertEquals('branch/name/wiith/slashes', $crawler->filter('.dropdown-menu li')->eq(1)->text());
|
||||
$this->assertEquals('issue12', $crawler->filter('.dropdown-menu li')->eq(2)->text());
|
||||
@@ -167,13 +175,10 @@ class InterfaceTest extends WebTestCase
|
||||
$this->assertCount(1, $crawler->filter('.tree tr:contains("myfolder")'));
|
||||
$this->assertCount(1, $crawler->filter('.tree tr:contains("testfolder")'));
|
||||
$this->assertCount(1, $crawler->filter('.tree tr:contains("bar.json")'));
|
||||
$this->assertEquals('/foobar/tree/master/myfolder/',
|
||||
$crawler->filter('.tree tr td')->eq(0)->filter('a')->eq(0)->attr('href'));
|
||||
$this->assertEquals('/foobar/tree/master/testfolder/',
|
||||
$crawler->filter('.tree tr td')->eq(3)->filter('a')->eq(0)->attr('href'));
|
||||
$this->assertEquals('/foobar/blob/master/bar.json',
|
||||
$crawler->filter('.tree tr td')->eq(6)->filter('a')->eq(0)->attr('href'));
|
||||
$this->assertCount(0, $crawler->filter('.readme-header'));
|
||||
$this->assertEquals('/foobar/tree/master/myfolder/', $crawler->filter('.tree tr td')->eq(0)->filter('a')->eq(0)->attr('href'));
|
||||
$this->assertEquals('/foobar/tree/master/testfolder/', $crawler->filter('.tree tr td')->eq(3)->filter('a')->eq(0)->attr('href'));
|
||||
$this->assertEquals('/foobar/blob/master/bar.json', $crawler->filter('.tree tr td')->eq(6)->filter('a')->eq(0)->attr('href'));
|
||||
$this->assertCount(0, $crawler->filter('.md-header'));
|
||||
$this->assertEquals('master', $crawler->filter('.dropdown-menu li')->eq(1)->text());
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<li><a href="{{ path('repository', {repo: repo}) }}">{{ repo }}</a></li>
|
||||
{% for breadcrumb in breadcrumbs %}
|
||||
<span class="divider">/</span>
|
||||
<li{% if loop.last %} class="active"{% endif %}>{% if not loop.last %}<a href="{{ path('tree', {repo: repo, branch: branch, tree: breadcrumb.path}) }}">{{ breadcrumb.dir }}</a>{% endif %}{% if loop.last %}{{ breadcrumb.dir }}{% endif %}</li>
|
||||
<li{% if loop.last %} class="active"{% endif %}>{% if not loop.last %}<a href="{{ path('tree', {repo: repo, commitishPath: branch ~ '/' ~ breadcrumb.path}) }}">{{ breadcrumb.dir }}</a>{% endif %}{% if loop.last %}{{ breadcrumb.dir }}{% endif %}</li>
|
||||
{% endfor %}
|
||||
|
||||
{% block extra %}{% endblock %}
|
||||
|
||||
@@ -13,8 +13,11 @@
|
||||
<h4>{{ commit.message }}</h4>
|
||||
</div>
|
||||
<div class="commit-body">
|
||||
<img src="https://gravatar.com/avatar/{{ commit.author.email | md5 }}?s=32" class="pull-left space-right" />
|
||||
<span><a href="mailto:{{ commit.author.email }}">{{ commit.author.name }}</a> authored in {{ commit.date | date('d/m/Y \\a\\t H:i:s') }}<br />Showing {{ commit.changedFiles }} changed files</span>
|
||||
{% if commit.body is not empty %}
|
||||
<p>{{ commit.body | nl2br }}</p>
|
||||
{% endif %}
|
||||
<img src="https://gravatar.com/avatar/{{ commit.author.email | lower | md5 }}?s=32" class="pull-left space-right" />
|
||||
<span><a href="mailto:{{ commit.author.email }}">{{ commit.author.name }}</a> authored on {{ commit.date | date('d/m/Y \\a\\t H:i:s') }}<br />Showing {{ commit.changedFiles }} changed files</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -30,8 +33,8 @@
|
||||
<div class="meta"><a name="{{ loop.index }}">{{ diff.file }}</div>
|
||||
|
||||
<div class="btn-group pull-right">
|
||||
<a href="{{ path('commits', {repo: repo, branch: commit.hash, file: diff.file}) }}" class="btn btn-small"><i class="icon-list-alt"></i> History</a>
|
||||
<a href="{{ path('blob', {repo: repo, branch: commit.hash, file: diff.file}) }}" class="btn btn-small"><i class="icon-file"></i> View file @ {{ commit.shortHash }}</a>
|
||||
<a href="{{ path('commits', {repo: repo, commitishPath: commit.hash ~ '/' ~ diff.file}) }}" class="btn btn-small"><i class="icon-list-alt"></i> History</a>
|
||||
<a href="{{ path('blob', {repo: repo, commitishPath: commit.hash ~'/' ~ diff.file}) }}" class="btn btn-small"><i class="icon-file"></i> View file @ {{ commit.shortHash }}</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -9,11 +9,11 @@
|
||||
<tbody>
|
||||
{% for item in commit %}
|
||||
<tr>
|
||||
<td width="5%"><img src="http://gravatar.com/avatar/{{ item.author.email | md5 }}?s=40" /></td>
|
||||
<td width="5%"><img src="http://gravatar.com/avatar/{{ item.author.email | lower | md5 }}?s=40" /></td>
|
||||
<td width="95%">
|
||||
<span class="pull-right"><a class="btn btn-small" href="{{ path('commit', {repo: repo, commit: item.hash}) }}"><i class="icon-list-alt"></i> View {{ item.shortHash }}</a></span>
|
||||
<h4>{{ item.message }}</h4>
|
||||
<span><a href="mailto:{{ item.author.email }}">{{ item.author.name }}</a> authored in {{ item.date | date('d/m/Y \\a\\t H:i:s') }}</span>
|
||||
<span><a href="mailto:{{ item.author.email }}">{{ item.author.name }}</a> authored on {{ item.date | date('d/m/Y \\a\\t H:i:s') }}</span>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
||||
@@ -12,16 +12,16 @@
|
||||
<div class="meta"></div>
|
||||
|
||||
<div class="btn-group pull-right">
|
||||
<a href="{{ path('blob_raw', {repo: repo, branch: branch, file: file}) }}" class="btn btn-small"><i class="icon-file"></i> Raw</a>
|
||||
<a href="{{ path('blame', {repo: repo, branch: branch, file: file}) }}" class="btn btn-small"><i class="icon-bullhorn"></i> Blame</a>
|
||||
<a href="{{ path('commits', {repo: repo, branch: branch, file: file}) }}" class="btn btn-small"><i class="icon-list-alt"></i> History</a>
|
||||
<a href="{{ path('blob_raw', {repo: repo, commitishPath: branch ~ '/' ~ file}) }}" class="btn btn-small"><i class="icon-file"></i> Raw</a>
|
||||
<a href="{{ path('blame', {repo: repo, commitishPath: branch ~ '/' ~ file}) }}" class="btn btn-small"><i class="icon-bullhorn"></i> Blame</a>
|
||||
<a href="{{ path('commits', {repo: repo, commitishPath: branch ~ '/' ~ file}) }}" class="btn btn-small"><i class="icon-list-alt"></i> History</a>
|
||||
</div>
|
||||
</div>
|
||||
{% if fileType == 'image' %}
|
||||
<center><img src="{{ path('blob_raw', {repo: repo, branch: branch, file: file}) }}" alt="{{ file }}" class="image-blob" /></center>
|
||||
<center><img src="{{ path('blob_raw', {repo: repo, commitishPath: branch ~ '/' ~ file}) }}" alt="{{ file }}" class="image-blob" /></center>
|
||||
|
||||
{% elseif fileType == 'markdown' %}
|
||||
<div class="readme-view"><div id="readme-content">{{ blob }}</div></div>
|
||||
<div class="md-view"><div id="md-content">{{ blob }}</div></div>
|
||||
|
||||
{% else %}
|
||||
<pre id="sourcecode" language="{{ fileType }}">{{ blob|htmlentities|raw }}</pre>
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
<meta charset="UTF-8" />
|
||||
<title>{% block title %}Welcome!{% endblock %}</title>
|
||||
<link rel="stylesheet" type="text/css" href="{{ app.request.basepath }}/web/css/style.css">
|
||||
<link rel="shortcut icon" type="image/png" href="{{ app.request.basepath }}/web/img/favicon.png" />
|
||||
<!--[if lt IE 9]>
|
||||
<script src="{{ app.request.basepath }}/web/js/html5.js"></script>
|
||||
<![endif]-->
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<ul class="nav nav-tabs">
|
||||
<li{% if page == 'files' %} class="active"{% endif %}><a href="{{ path('branch', {repo: repo, branch: branch}) }}">Files</a></li>
|
||||
<li{% if page in ['commits', 'searchcommits'] %} class="active"{% endif %}><a href="{{ path('commits', {repo: repo, branch: branch}) }}">Commits</a></li>
|
||||
<li{% if page in ['commits', 'searchcommits'] %} class="active"{% endif %}><a href="{{ path('commits', {repo: repo, commitishPath: branch}) }}">Commits</a></li>
|
||||
<li{% if page == 'stats' %} class="active"{% endif %}><a href="{{ path('stats', {repo: repo, branch: branch}) }}">Stats</a></li>
|
||||
</ul>
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
<channel>
|
||||
<title>Latest commits in {{ repo }}:{{ branch }}</title>
|
||||
<description>RSS provided by GitList</description>
|
||||
<link>{{ path('homepage') }}</link>
|
||||
<link>{{ url('homepage') }}</link>
|
||||
|
||||
{% for commit in commits %}
|
||||
<item>
|
||||
<title>{{ commit.message }}</title>
|
||||
<description>{{ commit.author.name }} authored {{ commit.shortHash }} in {{ commit.date | date('d/m/Y \\a\\t H:i:s') }}</description>
|
||||
<link>{{ path('commit', {repo: repo, commit: commit.hash}) }}</link>
|
||||
<link>{{ url('commit', {repo: repo, commit: commit.hash}) }}</link>
|
||||
<pubDate>{{ commit.date | date('r') }}</pubDate>
|
||||
</item>
|
||||
{% endfor %}
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
<tbody>
|
||||
{% for result in results %}
|
||||
<tr>
|
||||
<td><i class="icon-file icon-spaced"></i> <a href="{{ path('blob', {repo: repo, branch: branch, file: result.file}) }}#L{{ result.line }}">{{ result.file }}</a></td>
|
||||
<td><i class="icon-file icon-spaced"></i> <a href="{{ path('blob', {repo: repo, branch: branch, file: result.file, commitishPath: branch ~ '/' ~ result.file}) }}#L{{ result.line }}">{{ result.file }}</a></td>
|
||||
<td>{{ result.match }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
{% if not parent %}
|
||||
<a href="{{ path('branch', {repo: repo, branch: branch}) }}">..</a>
|
||||
{% else %}
|
||||
<a href="{{ path('tree', {repo: repo, branch: branch, tree: parent}) }}">..</a>
|
||||
<a href="{{ path('tree', {repo: repo, commitishPath: branch ~ '/' ~ parent}) }}">..</a>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td></td>
|
||||
@@ -43,9 +43,9 @@
|
||||
<tr>
|
||||
<td><i class="{{ file.type == "folder" or file.type == "symlink" ? "icon-folder-open" : "icon-file" }} icon-spaced"></i> <a href="
|
||||
{%- if file.type == "folder" or file.type == "symlink" -%}
|
||||
{{ path('tree', {repo: repo, branch: branch, tree: path ~ (file.type == "symlink" ? file.path : file.name)}) }}
|
||||
{{ path('tree', {repo: repo, commitishPath: branch ~ '/' ~ path ~ (file.type == "symlink" ? file.path : file.name)}) }}
|
||||
{%- else -%}
|
||||
{{ path('blob', {repo: repo, branch: branch, file: path ~ (file.type == "symlink" ? file.path : file.name)}) }}
|
||||
{{ path('blob', {repo: repo, commitishPath: branch ~ '/' ~ path ~ (file.type == "symlink" ? file.path : file.name)}) }}
|
||||
{%- endif -%}
|
||||
">{{ file.name }}</a></td>
|
||||
<td>{{ file.mode }}</td>
|
||||
@@ -56,10 +56,10 @@
|
||||
</table>
|
||||
{% if readme is defined and readme is not empty %}
|
||||
<div class="readme-view">
|
||||
<div class="readme-header">
|
||||
<div class="md-header">
|
||||
<div class="meta">{{ readme.filename }}</div>
|
||||
</div>
|
||||
<div id="readme-content">{{ readme.content }}</div>
|
||||
<div id="md-content">{{ readme.content }}</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
|
||||
@@ -274,8 +274,10 @@ table .span24{float:none;width:1884px;margin-left:0;}
|
||||
.commit-list li:last-child{border-bottom:0;margin-bottom:25px;}
|
||||
.repository{margin-bottom:18px;border:1px solid #d7d7d7;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;}.repository .repository-header{border-bottom:1px solid #d7d7d7;text-shadow:1px 1px 1px #ffffff;padding:8px;font-weight:700;font-size:14px;}
|
||||
.repository .repository-body{padding:8px;background-color:#f7f7f7;}.repository .repository-body p{margin:0;}
|
||||
.readme-view{width:100%;margin-bottom:18px;border:1px solid #cacaca;}.readme-view .readme-header{padding:8px;line-height:18px;text-align:left;vertical-align:bottom;background-color:#f4f4f4;background-image:-moz-linear-gradient(top, #fafafa, #eaeaea);background-image:-ms-linear-gradient(top, #fafafa, #eaeaea);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#fafafa), to(#eaeaea));background-image:-webkit-linear-gradient(top, #fafafa, #eaeaea);background-image:-o-linear-gradient(top, #fafafa, #eaeaea);background-image:linear-gradient(top, #fafafa, #eaeaea);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fafafa', endColorstr='#eaeaea', GradientType=0);border-bottom:1px solid #d7d7d7;font-weight:bold;color:#555555;text-shadow:1px 1px 1px #ffffff;height:28px;}.readme-view .readme-header .meta{float:left;padding:4px 0;font-size:14px;}
|
||||
.readme-view #readme-content{padding:30px;color:#000000;}
|
||||
.readme-view{border:1px solid #cacaca;}
|
||||
.md-view{width:100%;margin-bottom:18px;}
|
||||
.md-header{padding:8px;line-height:18px;text-align:left;vertical-align:bottom;background-color:#f4f4f4;background-image:-moz-linear-gradient(top, #fafafa, #eaeaea);background-image:-ms-linear-gradient(top, #fafafa, #eaeaea);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#fafafa), to(#eaeaea));background-image:-webkit-linear-gradient(top, #fafafa, #eaeaea);background-image:-o-linear-gradient(top, #fafafa, #eaeaea);background-image:linear-gradient(top, #fafafa, #eaeaea);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fafafa', endColorstr='#eaeaea', GradientType=0);border-bottom:1px solid #d7d7d7;font-weight:bold;color:#555555;text-shadow:1px 1px 1px #ffffff;height:28px;}.md-header .meta{float:left;padding:4px 0;font-size:14px;}
|
||||
#md-content{padding:30px;color:#000000;}
|
||||
.rss{display:inline-block;width:16px;height:16px;*margin-right:.3em;line-height:16px;vertical-align:text-top;background-image:url("../img/feed.png");background-position:0 0;background-repeat:no-repeat;}.rss:last-child{*margin-left:0;}
|
||||
[class^="icon-"],[class*=" icon-"]{display:inline-block;width:14px;height:14px;*margin-right:.3em;line-height:14px;vertical-align:text-top;background-image:url("../img/glyphicons-halflings.png");background-position:14px 14px;background-repeat:no-repeat;}[class^="icon-"]:last-child,[class*=" icon-"]:last-child{*margin-left:0;}
|
||||
.icon-white{background-image:url("../img/glyphicons-halflings-white.png");}
|
||||
@@ -760,13 +762,13 @@ a.label:hover,a.badge:hover{color:#ffffff;text-decoration:none;cursor:pointer;}
|
||||
.CodeMirror-gutter-text{color:#aaa;text-align:right;padding:.4em .2em .4em .4em;white-space:pre !important;}
|
||||
.CodeMirror-lines{padding:.4em;white-space:pre;cursor:text;margin-left:5px;}
|
||||
.CodeMirror-lines *{pointer-events:none;}
|
||||
.CodeMirror pre{-moz-border-radius:0;-webkit-border-radius:0;-o-border-radius:0;border-radius:0;border-width:0;margin:0;padding:0;background:transparent;font-family:inherit;font-size:inherit;padding:0;margin:0;white-space:pre;word-wrap:normal;line-height:inherit;color:inherit;}
|
||||
.CodeMirror pre{-moz-border-radius:0;-webkit-border-radius:0;-o-border-radius:0;border-radius:0;border-width:0;background:transparent;font-family:inherit;font-size:inherit;padding:0;margin:0;white-space:pre;word-wrap:normal;line-height:inherit;color:inherit;}
|
||||
.CodeMirror-wrap pre{word-wrap:break-word;white-space:pre-wrap;word-break:normal;}
|
||||
.CodeMirror-wrap .CodeMirror-scroll{overflow-x:hidden;}
|
||||
.CodeMirror textarea{outline:none !important;}
|
||||
.CodeMirror pre.CodeMirror-cursor{z-index:10;position:absolute;visibility:hidden;border-left:1px solid black;border-right:none;width:0;}
|
||||
.cm-keymap-fat-cursor pre.CodeMirror-cursor{width:auto;border:0;background:transparent;background:rgba(0, 200, 0, 0.4);}
|
||||
.cm-keymap-fat-cursor pre.CodeMirror-cursor:not(#nonsense_id){filter:progid:dximagetransform.microsoft.gradient(enabled=false);}
|
||||
.cm-keymap-fat-cursor pre.CodeMirror-cursor:not(#nonsense_id){filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);}
|
||||
.CodeMirror-focused pre.CodeMirror-cursor{visibility:visible;}
|
||||
div.CodeMirror-selected{background:#d9d9d9;}
|
||||
.CodeMirror-focused div.CodeMirror-selected{background:#d7d4f0;}
|
||||
|
||||
BIN
web/img/favicon.png
Normal file
BIN
web/img/favicon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 884 B |
@@ -20,22 +20,23 @@ $(function () {
|
||||
});
|
||||
}
|
||||
|
||||
if ($('#readme-content').length) {
|
||||
if ($('#md-content').length) {
|
||||
var converter = new Showdown.converter();
|
||||
$('#readme-content').html(converter.makeHtml($('#readme-content').text()));
|
||||
$('#md-content').html(converter.makeHtml($('#md-content').text()));
|
||||
}
|
||||
|
||||
function paginate() {
|
||||
var $pager = $('.pager');
|
||||
|
||||
$pager.find('.next a').one('click', function (e) {
|
||||
e.preventDefault();
|
||||
$(this).css('pointer-events', 'none');
|
||||
$.get(this.href, function (html) {
|
||||
$pager.after(html);
|
||||
$pager.remove();
|
||||
paginate();
|
||||
});
|
||||
});
|
||||
|
||||
$pager.find('.previous').remove();
|
||||
}
|
||||
paginate();
|
||||
|
||||
@@ -161,30 +161,33 @@
|
||||
}
|
||||
|
||||
.readme-view {
|
||||
border: 1px solid @treeHeaderBorder;
|
||||
}
|
||||
|
||||
.md-view {
|
||||
width: 100%;
|
||||
margin-bottom: @baseLineHeight;
|
||||
border: 1px solid @treeHeaderBorder;
|
||||
}
|
||||
|
||||
.readme-header {
|
||||
padding: 8px;
|
||||
line-height: @baseLineHeight;
|
||||
text-align: left;
|
||||
vertical-align: bottom;
|
||||
#gradient > .vertical(@treeHeaderHighlight, @treeHeader);
|
||||
border-bottom: 1px solid lighten(@treeHeaderBorder, 5%);
|
||||
font-weight: bold;
|
||||
color: @gray;
|
||||
text-shadow: 1px 1px 1px rgba(255,255,255,1);
|
||||
height:28px;
|
||||
.meta {
|
||||
float: left;
|
||||
padding: 4px 0;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
#readme-content {
|
||||
padding: 30px;
|
||||
color: @black;
|
||||
.md-header {
|
||||
padding: 8px;
|
||||
line-height: @baseLineHeight;
|
||||
text-align: left;
|
||||
vertical-align: bottom;
|
||||
#gradient > .vertical(@treeHeaderHighlight, @treeHeader);
|
||||
border-bottom: 1px solid lighten(@treeHeaderBorder, 5%);
|
||||
font-weight: bold;
|
||||
color: @gray;
|
||||
text-shadow: 1px 1px 1px rgba(255,255,255,1);
|
||||
height:28px;
|
||||
.meta {
|
||||
float: left;
|
||||
padding: 4px 0;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
#md-content {
|
||||
padding: 30px;
|
||||
color: @black;
|
||||
}
|
||||
Reference in New Issue
Block a user