Skip to content

Commit a7c06d7

Browse files
author
Alexandre Salomé
committed
makes revision API more consistent
1 parent d6cd88d commit a7c06d7

File tree

7 files changed

+150
-23
lines changed

7 files changed

+150
-23
lines changed

src/Gitonomy/Git/Blame.php

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,32 +14,54 @@
1414

1515
use Gitonomy\Git\Exception\InvalidArgumentException;
1616
use Gitonomy\Git\Parser\BlameParser;
17+
use Gitonomy\Git\Blame\Line;
1718

1819
/**
1920
* @author Alexandre Salomé <alexandre.salome@gmail.com>
2021
*/
2122
class Blame implements \Countable
2223
{
24+
/**
25+
* @var Repository
26+
*/
2327
protected $repository;
28+
29+
/**
30+
* @var Revision
31+
*/
2432
protected $revision;
33+
34+
/**
35+
* @var string
36+
*/
2537
protected $file;
38+
39+
/**
40+
* @var string|null
41+
*/
2642
protected $lineRange;
2743

44+
/**
45+
* @var array|null
46+
*/
2847
protected $lines;
2948

3049
/**
3150
* @param string $lineRange Argument to pass to git blame (-L).
3251
* Can be a line range (40,60 or 40,+21)
3352
* or a regexp ('/^function$/')
3453
*/
35-
public function __construct(Repository $repository, $revision, $file, $lineRange = null)
54+
public function __construct(Repository $repository, Revision $revision, $file, $lineRange = null)
3655
{
3756
$this->repository = $repository;
3857
$this->revision = $revision;
3958
$this->lineRange = $lineRange;
4059
$this->file = $file;
4160
}
4261

62+
/**
63+
* @return Line
64+
*/
4365
public function getLine($number)
4466
{
4567
if ($number < 1) {
@@ -55,6 +77,11 @@ public function getLine($number)
5577
return $lines[$number];
5678
}
5779

80+
/**
81+
* Returns lines grouped by commit.
82+
*
83+
* @return array a list of two-elements array (commit, lines)
84+
*/
5885
public function getGroupedLines()
5986
{
6087
$result = array();
@@ -80,6 +107,11 @@ public function getGroupedLines()
80107
return $result;
81108
}
82109

110+
/**
111+
* Returns all lines of the blame.
112+
*
113+
* @return array
114+
*/
83115
public function getLines()
84116
{
85117
if (null !== $this->lines) {
@@ -93,7 +125,7 @@ public function getLines()
93125
$args[] = $this->lineRange;
94126
}
95127

96-
$args[] = $this->revision;
128+
$args[] = $this->revision->getRevision();
97129
$args[] = '--';
98130
$args[] = $this->file;
99131

@@ -104,6 +136,9 @@ public function getLines()
104136
return $this->lines;
105137
}
106138

139+
/**
140+
* @return int
141+
*/
107142
public function count()
108143
{
109144
return count($this->getLines());

src/Gitonomy/Git/Log.php

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,32 @@ class Log implements \Countable, \IteratorAggregate
4444
*/
4545
protected $limit;
4646

47-
public function __construct(Repository $repository, $revisions, $paths = null, $offset = 0, $limit = null)
47+
/**
48+
* Instanciates a git log object.
49+
*
50+
* @param Repository $repository the repository where log occurs
51+
* @param RevisionList $revisions a list of revisions or null if you want all history
52+
* @param array $paths paths to filter on
53+
* @param int|null $offset start list from a given position
54+
* @param int|null $limit limit number of fetched elements
55+
*/
56+
public function __construct(Repository $repository, $revisions = null, $paths = null, $offset = null, $limit = null)
4857
{
58+
if (null !== $revisions && !$revisions instanceof RevisionList) {
59+
$revisions = new RevisionList($repository, $revisions);
60+
}
61+
62+
if (null === $paths) {
63+
$paths = array();
64+
} elseif (is_string($paths)) {
65+
$paths = array($paths);
66+
} elseif (!is_array($paths)) {
67+
throw new \InvalidArgumentException(sprintf('Expected a string or an array, got a "%s".', is_object($paths) ? get_class($paths) : gettype($paths)));
68+
}
69+
4970
$this->repository = $repository;
50-
$this->revisions = (array) $revisions;
51-
$this->paths = (array) $paths;
71+
$this->revisions = $revisions;
72+
$this->paths = $paths;
5273
$this->offset = $offset;
5374
$this->limit = $limit;
5475
}
@@ -62,7 +83,7 @@ public function getDiff()
6283
}
6384

6485
/**
65-
* @return array
86+
* @return RevisionList
6687
*/
6788
public function getRevisions()
6889
{
@@ -118,10 +139,6 @@ public function setLimit($limit)
118139
*/
119140
public function getCommits()
120141
{
121-
$offset = null !== $this->offset ? '--skip='.((int) $this->offset) : '';
122-
$limit = null !== $this->limit ? '-n '.((int) $this->limit) : '';
123-
$revisions = null !== $this->revisions ? $this->revisions : '--all';
124-
125142
$args = array('--encoding='.StringHelper::getEncoding(), '--format=format:%H');
126143

127144
if (null !== $this->offset) {
@@ -133,8 +150,8 @@ public function getCommits()
133150
$args[] = (int) $this->limit;
134151
}
135152

136-
if (count($this->revisions)) {
137-
$args = array_merge($args, $this->revisions);
153+
if (null !== $this->revisions) {
154+
$args = array_merge($args, $this->revisions->getAsTextArray());
138155
} else {
139156
$args[] = '--all';
140157
}
@@ -180,7 +197,7 @@ public function getIterator()
180197
public function countCommits()
181198
{
182199
if (count($this->revisions)) {
183-
$output = $this->repository->run('rev-list', array_merge($this->revisions, array('--'), $this->paths));
200+
$output = $this->repository->run('rev-list', array_merge($this->revisions->getAsTextArray(), array('--'), $this->paths));
184201
} else {
185202
$output = $this->repository->run('rev-list', array_merge(array('--all', '--'), $this->paths));
186203
}

src/Gitonomy/Git/PushReference.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ public function getLog($excludes = array())
101101
public function getRevision()
102102
{
103103
if ($this->isDelete()) {
104-
throw new LogicException('No log on deletion');
104+
throw new LogicException('No revision for deletion');
105105
}
106106

107107
if ($this->isCreate()) {

src/Gitonomy/Git/Repository.php

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ public function isBare()
167167
/**
168168
* Returns the HEAD resolved as a commit.
169169
*
170-
* @return Commit|null a Commit object or null if debug-mode disabled and HEAD not found.
170+
* @return Revision|null returns a Commit, Branch, or ``null`` if repository is empty
171171
*/
172172
public function getHeadCommit()
173173
{
@@ -229,19 +229,15 @@ public function getHead()
229229
*/
230230
public function isHeadDetached()
231231
{
232-
$head = $this->getHead();
233-
234-
return null === $head || $head instanceof Commit;
232+
return !$this->isHeadAttached();
235233
}
236234

237235
/**
238236
* @return boolean
239237
*/
240238
public function isHeadAttached()
241239
{
242-
$head = $this->getHead();
243-
244-
return $head instanceof Reference;
240+
return $this->getHead() instanceof Reference;
245241
}
246242

247243
/**
@@ -359,6 +355,10 @@ public function getBlob($hash)
359355

360356
public function getBlame($revision, $file, $lineRange = null)
361357
{
358+
if (is_string($revision)) {
359+
$revision = $this->getRevision($revision);
360+
}
361+
362362
return new Blame($this, $revision, $file, $lineRange);
363363
}
364364

src/Gitonomy/Git/Revision.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ public function __construct(Repository $repository, $revision, $commitHash = nul
4848
*/
4949
public function getLog($paths = null, $offset = null, $limit = null)
5050
{
51-
return $this->repository->getLog($this->revision, $paths, $offset, $limit);
51+
return $this->repository->getLog($this, $paths, $offset, $limit);
5252
}
5353

5454
/**

src/Gitonomy/Git/RevisionList.php

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
<?php
2+
3+
/**
4+
* This file is part of Gitonomy.
5+
*
6+
* (c) Alexandre Salomé <alexandre.salome@gmail.com>
7+
* (c) Julien DIDIER <genzo.wm@gmail.com>
8+
*
9+
* This source file is subject to the GPL license that is bundled
10+
* with this source code in the file LICENSE.
11+
*/
12+
13+
namespace Gitonomy\Git;
14+
15+
use Gitonomy\Git\Util\StringHelper;
16+
17+
/**
18+
* @author Alexandre Salomé <alexandre.salome@gmail.com>
19+
*/
20+
class RevisionList implements \IteratorAggregate, \Countable
21+
{
22+
protected $revisions;
23+
24+
/**
25+
* Constructs a revision list from a variety of types.
26+
*
27+
* @param mixed $revisions can be a string, an array of strings or an array of Revision, Branch, Tag, Commit
28+
*/
29+
public function __construct(Repository $repository, $revisions)
30+
{
31+
if (is_string($revisions)) {
32+
$revisions = array($repository->getRevision($revisions));
33+
} elseif ($revisions instanceof Revision) {
34+
$revisions = array($revisions);
35+
} elseif (!is_array($revisions)) {
36+
throw new \InvalidArgumentException(sprintf('Expected a string, a Revision or an array, got a "%s".', is_object($revisions) ? get_class($revisions) : gettype($revisions)));
37+
}
38+
39+
if (count($revisions) == 0) {
40+
throw new \InvalidArgumentException(sprintf("Empty revision list not allowed"));
41+
}
42+
43+
foreach ($revisions as $i => $revision) {
44+
if (is_string($revision)) {
45+
$revisions[$i] = new Revision($repository, $revision);
46+
} elseif (!$revision instanceof Revision) {
47+
throw new \InvalidArgumentException(sprintf('Expected a "Revision", got a "%s".', is_object($revision) ? get_class($revision) : gettype($revision)));
48+
}
49+
}
50+
51+
$this->revisions = $revisions;
52+
}
53+
54+
public function getAll()
55+
{
56+
return $this->revisions;
57+
}
58+
59+
public function getIterator()
60+
{
61+
return new \ArrayIterator($this->revisions);
62+
}
63+
64+
public function count()
65+
{
66+
return count($this->revisions);
67+
}
68+
69+
public function getAsTextArray()
70+
{
71+
return array_map(function ($revision) {
72+
return $revision->getRevision();
73+
}, $this->revisions);
74+
}
75+
}

tests/Gitonomy/Git/Tests/RevisionTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,6 @@ public function testGetLog($repository)
5656
$this->assertTrue($log instanceof Log, "Log type object");
5757
$this->assertEquals(2, $log->getOffset(), "Log offset is passed");
5858
$this->assertEquals(3, $log->getLimit(), "Log limit is passed");
59-
$this->assertEquals(array(self::LONGFILE_COMMIT), $log->getRevisions(), "Revision is passed");
59+
$this->assertEquals(array($revision), $log->getRevisions()->getAll(), "Revision is passed");
6060
}
6161
}

0 commit comments

Comments
 (0)