Skip to content
This repository was archived by the owner on Apr 12, 2020. It is now read-only.

Commit 77b6d04

Browse files
committed
Implemented a tree browser
1 parent dac0d8f commit 77b6d04

File tree

10 files changed

+157
-6
lines changed

10 files changed

+157
-6
lines changed

src/Gitonomy/Browser/Application.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,15 @@ public function registerRouting()
9191
->bind('log_ajax')
9292
;
9393

94+
/** Browse repository */
95+
$this
96+
->get('/{repository}/browse/tree/{reference}/{path}', 'controller.main:treeAction')
97+
->bind('tree')
98+
->value('reference', 'master')
99+
->value('path', '')
100+
->assert('path', '.*')
101+
;
102+
94103
/** Commit page */
95104
$this
96105
->get('/{repository}/commit/{hash}', 'controller.main:showCommitAction')

src/Gitonomy/Browser/Controller/MainController.php

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@
44

55
use Symfony\Component\Routing\Generator\UrlGenerator;
66
use Symfony\Component\HttpFoundation\RedirectResponse;
7+
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
8+
9+
use Gitonomy\Git\Blob;
10+
use Gitonomy\Git\Tree;
11+
use Gitonomy\Git\Exception\ReferenceNotFoundException;
712

813
class MainController
914
{
@@ -49,6 +54,39 @@ public function logAjaxAction(Request $request, $repository)
4954
return $this->twig->render('log_ajax.html.twig', array('log' => $log));
5055
}
5156

57+
public function treeAction($repository, $reference, $path)
58+
{
59+
try {
60+
$commit = $repository->getRevision($reference)->getResolved();
61+
$tree = $commit->getTree();
62+
} catch (ReferenceNotFoundException $e) {
63+
throw new NotFoundHttpException(sprintf('The reference "%s" is not valid', $reference), $e);
64+
}
65+
66+
try {
67+
$element = $tree->resolvePath($path);
68+
} catch (\Exception $e) {
69+
throw new NotFoundHttpException(sprintf('Cannot find path "%s" for current commit "%s"', $path, $commit->getHash()), $e);
70+
}
71+
72+
$parameters = array(
73+
'reference' => $reference,
74+
'commit' => $commit,
75+
'parent_path' => substr($path, 0, strrpos($path, '/')),
76+
'path' => $path,
77+
);
78+
79+
if ($element instanceof Blob) {
80+
$parameters['blob'] = $element;
81+
$tpl = 'browse_blob.html.twig';
82+
} elseif ($element instanceof Tree) {
83+
$parameters['tree'] = $element;
84+
$tpl = 'browse_tree.html.twig';
85+
}
86+
87+
return $this->twig->render($tpl, $parameters);
88+
}
89+
5290
public function showCommitAction($repository, $hash)
5391
{
5492
return $this->twig->render('commit.html.twig', array(

src/Gitonomy/Browser/Git/Repository.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
namespace Gitonomy\Browser\Git;
44

55
use Gitonomy\Git\Repository as BaseRepository;
6-
use Psr\Log\LoggerInterface;
76

87
class Repository extends BaseRepository
98
{
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{% extends "layout.html.twig" %}
2+
3+
{% block content %}
4+
<h3>Code</h3>
5+
{{ git_blob(blob, path) }}
6+
{% endblock %}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
{% extends "layout.html.twig" %}
2+
3+
{% block content %}
4+
<h3>Code</h3>
5+
<table class="table table-striped">
6+
<thead>
7+
<tr>
8+
<th width="20"></td>
9+
<th>{{ 'table.filename'|trans }}</th>
10+
<th>{{ 'table.date'|trans }}</th>
11+
<th>{{ 'table.last_commit'|trans }}</th>
12+
</tr>
13+
</thead>
14+
<tbody>
15+
{% if parent_path is not sameas(false) %}
16+
<tr>
17+
<td><i class="icon-folder-open"></i></td>
18+
<td>
19+
<a href="{{ path('tree', {reference: reference, path: parent_path}) }}">
20+
..
21+
</a>
22+
</td>
23+
<td></td>
24+
<td></td>
25+
</tr>
26+
{% endif %}
27+
{% for name, data in tree.entries if data[1] is git_tree %}
28+
{% embed 'browse_tree_row.html.twig' %}
29+
{% block first_column %}<i class="icon-folder-open"></i>{% endblock %}
30+
{% endembed %}
31+
{% endfor %}
32+
{% for name, data in tree.entries if data[1] is not git_tree %}
33+
{% embed 'browse_tree_row.html.twig' %}
34+
{% endembed %}
35+
{% endfor %}
36+
</tbody>
37+
</table>
38+
{% endblock %}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{% set pathLastModification = commit.lastModification(path~'/'~name) %}
2+
<tr>
3+
<td>{% block first_column %}{% endblock %}</td>
4+
<td>
5+
<a href="{{ path('tree', {reference: reference, path: (path ~ (path ? '/') ~ name)}) }}">
6+
{{ name }}
7+
</a>
8+
</td>
9+
<td>
10+
{{ pathLastModification.getCommitterDate.format('Y-m-d H:i:s') }}
11+
</td>
12+
<td>
13+
<a href="{{ path('commit', { hash: pathLastModification.hash }) }}">
14+
{{ pathLastModification.fixedShortHash }}
15+
</a>
16+
{{ pathLastModification.shortMessage }}
17+
<small>
18+
({{ pathLastModification.authorName }})
19+
</small>
20+
</td>
21+
</tr>

src/Gitonomy/Browser/Resources/views/git/default_theme.html.twig

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,3 +215,21 @@
215215
</a>
216216
{% endspaceless %}
217217
{% endblock %}
218+
219+
{% block blob_text %}
220+
{% spaceless %}
221+
<pre><code>{{ blob.content }}</code></pre>
222+
{% endspaceless %}
223+
{% endblock %}
224+
225+
{% block blob_image %}
226+
{% spaceless %}
227+
<pre><code>IMAGE</code></pre>
228+
{% endspaceless %}
229+
{% endblock %}
230+
231+
{% block blob_binary %}
232+
{% spaceless %}
233+
<pre><code>BINARY</code></pre>
234+
{% endspaceless %}
235+
{% endblock %}

src/Gitonomy/Browser/Resources/views/repository.html.twig

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
{{ git_tags(repository) }}
1212
{% endif %}
1313

14+
<h3>Browse</h3>
15+
<a href="{{ url('tree') }}">Browse the repository</a>
16+
1417
<h3>Logs</h3>
1518
{{ git_log(repository.log.setLimit(30), {query_url: url('log_ajax')}) }}
1619
{% endblock %}

src/Gitonomy/Browser/Twig/GitExtension.php

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,16 @@ public function getTokenParsers()
3838
public function getFunctions()
3939
{
4040
return array(
41-
new \Twig_SimpleFunction('git_repository_name', array($this, 'renderRepositoryName'), array('is_safe' => array('html'))),
4241
new \Twig_SimpleFunction('git_author', array($this, 'renderAuthor'), array('is_safe' => array('html'), 'needs_environment' => true)),
42+
new \Twig_SimpleFunction('git_blob', array($this, 'renderBlob'), array('is_safe' => array('html'), 'needs_environment' => true)),
43+
new \Twig_SimpleFunction('git_branches', array($this, 'renderBranches'), array('is_safe' => array('html'), 'needs_environment' => true)),
4344
new \Twig_SimpleFunction('git_commit_header', array($this, 'renderCommitHeader'), array('is_safe' => array('html'), 'needs_environment' => true)),
4445
new \Twig_SimpleFunction('git_diff', array($this, 'renderDiff'), array('is_safe' => array('html'), 'needs_environment' => true)),
45-
new \Twig_SimpleFunction('git_branches', array($this, 'renderBranches'), array('is_safe' => array('html'), 'needs_environment' => true)),
46-
new \Twig_SimpleFunction('git_tags', array($this, 'renderTags'), array('is_safe' => array('html'), 'needs_environment' => true)),
4746
new \Twig_SimpleFunction('git_log', array($this, 'renderLog'), array('is_safe' => array('html'), 'needs_environment' => true)),
4847
new \Twig_SimpleFunction('git_log_rows', array($this, 'renderLogRows'), array('is_safe' => array('html'), 'needs_environment' => true)),
4948
new \Twig_SimpleFunction('git_render', array($this, 'renderBlock'), array('is_safe' => array('html'), 'needs_environment' => true)),
49+
new \Twig_SimpleFunction('git_repository_name', array($this, 'renderRepositoryName'), array('is_safe' => array('html'))),
50+
new \Twig_SimpleFunction('git_tags', array($this, 'renderTags'), array('is_safe' => array('html'), 'needs_environment' => true)),
5051
new \Twig_SimpleFunction('git_url', array($this, 'getUrl')),
5152
);
5253
}
@@ -138,7 +139,6 @@ public function renderBranches(\Twig_Environment $env, Repository $repository, a
138139
));
139140
}
140141

141-
142142
public function renderTags(\Twig_Environment $env, Repository $repository)
143143
{
144144
return $this->renderBlock($env, 'tags', array(
@@ -160,6 +160,22 @@ public function renderAuthor(\Twig_Environment $env, Commit $commit, array $opti
160160
));
161161
}
162162

163+
public function renderBlob($env, Blob $blob, $path = null)
164+
{
165+
if ($blob->isText()) {
166+
$block = 'blob_text';
167+
} else {
168+
$mime = $blob->getMimetype();
169+
if (preg_match("#^image/(png|jpe?g|gif)#", $mime)) {
170+
$block = 'blob_image';
171+
} else {
172+
$block = 'blob_binary';
173+
}
174+
}
175+
176+
return $this->renderBlock($env, $block, array('blob' => $blob));
177+
}
178+
163179
public function addThemes($themes)
164180
{
165181
$themes = reset($themes);

tests/Gitonomy/Browser/Tests/Functionnal/ControllerTest.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ class ApplicationTest extends WebTestCase
99
{
1010
const TEST_REPOSITORY = '[email protected]:gitonomy/foobar.git';
1111

12-
static public function createRepository()
12+
public static function createRepository()
1313
{
1414
$tmp = sys_get_temp_dir().'gitonomybrowser_foobar';
1515
if (!is_dir($tmp)) {
@@ -45,6 +45,9 @@ public function getPage200Tests()
4545
array('/browser'),
4646
array('/browser/refs/heads/master'),
4747
array('/browser/commit/3c05a60d9522eb438d7be74f4ae51b4bcd0f697f'),
48+
array('/browser/browse/tree'),
49+
array('/browser/browse/tree/master'),
50+
array('/browser/browse/tree/3c05a60d9522eb438d7be74f4ae51b4bcd0f697f/composer.json'),
4851
);
4952
}
5053

0 commit comments

Comments
 (0)