Skip to content

Commit 038ee92

Browse files
kentfredricwchristian
authored andcommitted
Add a utility library for convenience methods
Add tests for utils Update changes
1 parent 55cd202 commit 038ee92

File tree

5 files changed

+169
-1
lines changed

5 files changed

+169
-1
lines changed

CHANGES

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
Revision history for Perl module Git::PurePerl:
22

3+
0.49
4+
- Add Git::PurePerl::Util with handy current_git_dir() util (Kent Fredric)
5+
36
0.48 Thu Jul 14 22:53:55 BST 2011
47
- Translation from Digest::SHA1 to Digest::SHA (Jonas Genannt)
58
- A git object can also be of zero size. (Christian Walde)

lib/Git/PurePerl/Util.pm

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
use strict;
2+
use warnings;
3+
4+
package Git::PurePerl::Util;
5+
6+
# FILENAME: Util.pm
7+
# CREATED: 29/05/12 21:46:21 by Kent Fredric (kentnl) <[email protected]>
8+
# ABSTRACT: Helper tools for Git::PurePerl
9+
10+
use Sub::Exporter -setup => {
11+
exports => [qw( current_git_dir find_git_dir is_git_dir )],
12+
groups => { default => [qw( current_git_dir )], },
13+
};
14+
use Path::Class qw( dir );
15+
16+
=head1 SYNOPSIS
17+
18+
use Git::PurePerl::Util;
19+
use Git::PurePerl;
20+
21+
my $repo = Git::PurePerl->new(
22+
gitdir => current_git_dir(),
23+
);
24+
25+
=cut
26+
27+
=head1 FUNCTIONS
28+
29+
=head2 is_git_dir
30+
31+
Determines if the given C<$dir> has the basic requirements of a Git repository dir.
32+
33+
( ie: either a checkouts C<.git> folder, or a bare repository )
34+
35+
if ( is_git_dir( $dir ) ) {
36+
...
37+
}
38+
39+
=cut
40+
41+
sub is_git_dir {
42+
my ($dir) = @_;
43+
return if not -e $dir->subdir('objects');
44+
return if not -e $dir->subdir('refs');
45+
return if not -e $dir->file('HEAD');
46+
return 1;
47+
}
48+
49+
=head2 find_git_dir
50+
51+
my $dir = find_git_dir( $subdir );
52+
53+
Finds the closest C<.git> or bare tree that is either at C<$subdir> or somewhere above C<$subdir>
54+
55+
If C<$subdir> is inside a 'bare' repo, returns the path to that repo.
56+
57+
If C<$subdir> is inside a checkout, returns the path to the checkouts C<.git> dir.
58+
59+
If C<$subdir> is not inside a git repo, returns a false value.
60+
61+
=cut
62+
63+
sub find_git_dir {
64+
my $start = shift;
65+
66+
return $start if is_git_dir($start);
67+
68+
my $repodir = $start->subdir('.git');
69+
70+
return $repodir if -e $repodir and is_git_dir($repodir);
71+
72+
return find_git_dir( $start->parent )
73+
if $start->parent->absolute ne $start->absolute;
74+
75+
return undef;
76+
}
77+
78+
=head2 current_git_dir
79+
80+
Finds the closest C<.git> or bare tree by walking up parents.
81+
82+
my $git_dir = current_git_dir();
83+
84+
If C<$CWD> is inside a bare repo somewhere, it will return the path to the bare repo root directory.
85+
86+
If C<$CWD> is inside a git checkout, it will return the path to the C<.git> folder of that checkout.
87+
88+
If C<$CWD> is not inside any recognisable git repo, will return a false value.
89+
90+
=cut
91+
92+
sub current_git_dir {
93+
return find_git_dir( dir('.') );
94+
}
95+
96+
1;
97+

t/00_setup.t

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use warnings;
44
use Test::More;
55
use Archive::Extract;
66

7-
foreach my $name qw(test-project test-project-packs test-project-packs2 test-encoding) {
7+
foreach my $name (qw(test-project test-project-packs test-project-packs2 test-encoding test-util)) {
88
next if -d $name;
99
my $ae = Archive::Extract->new( archive => "$name.tgz" );
1010
$ae->extract;

t/09_util.t

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
#!perl
2+
use strict;
3+
use warnings;
4+
use Test::More;
5+
use Git::PurePerl;
6+
use Path::Class;
7+
8+
use Git::PurePerl::Util qw( find_git_dir current_git_dir );
9+
10+
foreach my $directory (qw(test-project test-project-packs test-project-packs2))
11+
{
12+
my $dir = dir($directory);
13+
my $gd = find_git_dir( dir($directory) );
14+
15+
is(
16+
$gd->absolute->stringify,
17+
dir($directory)->subdir('.git')->absolute->stringify,
18+
"Correctly resolves an .git from a repo( $directory )"
19+
);
20+
21+
}
22+
23+
foreach my $directory (
24+
qw(
25+
test-util/deep
26+
test-util/deep/.git
27+
test-util/deep/stage1
28+
test-util/deep/stage1/stage2/
29+
)
30+
)
31+
{
32+
is(
33+
find_git_dir( dir($directory) )->absolute->stringify,
34+
dir('test-util/deep/.git')->absolute->stringify,
35+
"finding .git dirs works at all tree levels ( $directory )"
36+
);
37+
}
38+
39+
foreach my $directory (
40+
qw(
41+
test-util/bare
42+
test-util/bare/info
43+
test-util/bare/objects
44+
test-util/bare/refs
45+
test-util/bare/refs/heads
46+
)
47+
)
48+
{
49+
is(
50+
find_git_dir( dir($directory) )->absolute->stringify,
51+
dir('test-util/bare')->absolute->stringify,
52+
"finding bare dirs works at all tree levels ( $directory )"
53+
);
54+
}
55+
56+
use Cwd qw( getcwd );
57+
58+
my $old_dir = getcwd;
59+
60+
chdir "test-util/deep/stage1";
61+
62+
is(
63+
current_git_dir()->absolute->stringify,
64+
dir('.')->parent->subdir('.git')->absolute->stringify,
65+
"Can work with CWD"
66+
);
67+
68+
done_testing;

test-util.tgz

12.2 KB
Binary file not shown.

0 commit comments

Comments
 (0)