Skip to content

Commit

Permalink
got init working
Browse files Browse the repository at this point in the history
  • Loading branch information
ingydotnet committed Dec 27, 2011
1 parent d38da7a commit 10d4228
Show file tree
Hide file tree
Showing 9 changed files with 192 additions and 99 deletions.
2 changes: 1 addition & 1 deletion Changes
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
version: 0.10
version: 0.01
date:
changes:
- First Release
45 changes: 38 additions & 7 deletions LibGit2/LibGit2.xs
Original file line number Diff line number Diff line change
@@ -1,13 +1,44 @@
#include <perl_libgit2.h>
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "ppport.h"

MODULE = Git::XS::LibGit2 PACKAGE = Git::XS::LibGit2
#include "git2.h"
#include <helpers.c>

typedef struct {
git_repository *repo;
} git_t;

MODULE = Git::XS PACKAGE = Git::XS
PROTOTYPES: DISABLE
VERSIONCHECK: DISABLE

void
Object ()
PPCODE:
PL_markstack_ptr++;
Object();
return;
_build(self)
SV *self
PREINIT:
git_t *git;
CODE:
Newx(git, sizeof(git_t), git_t);
xs_object_magic_attach_struct(aTHX_ SvRV(self), git);
SV *repo = call_getter(self, "repo");
if (call_test(self, "repo_exists", repo))
git_repository_open(&(git->repo), SvPV_nolen(repo));

SV *
init(self)
SV *self
PREINIT:
int rc;
git_t *git = xs_object_magic_get_struct_rv(aTHX_ self);
CODE:
RETVAL = self;
SV *repo = call_getter(self, "repo");
char *path = SvPV_nolen(repo);
git_repository **pptr = &(git->repo);
rc = git_repository_init(pptr, path, 0);
if (rc != GIT_SUCCESS)
croak("git init failed with code: %d", rc);
OUTPUT:
RETVAL
41 changes: 20 additions & 21 deletions LibGit2/Makefile.PL
Original file line number Diff line number Diff line change
Expand Up @@ -5,31 +5,27 @@ use Cwd;

my $start_dir = Cwd::cwd;
my $libgit2_repo = 'git://github.com/ingydotnet/libgit2.git';
my $libgit2_dir = 'libgit2';
my $libgit2_build = "$libgit2_dir/build";
my $libgit2_path = "$libgit2_build/libgit2.o";
my $libgit2_path = Cwd::cwd . '/libgit2';
my $libgit2_inc = "$libgit2_path/include";
my $libgit2_build = "$libgit2_path/build";
my $libgit2_so = "$libgit2_build/libgit2.so";

if (not(-e $libgit2_dir)) {
system("git clone $libgit2_repo $libgit2_dir") == 0
if (not(-e $libgit2_path)) {
system("git clone $libgit2_repo $libgit2_path") == 0
or die "Can't git clone $libgit2_repo";
}

if (not(-f $libgit2_path)) {
chdir $libgit2_dir
or die "Can't chdir $libgit2_dir";
system("git checkout static-build") == 0
or die "Can't checkout static-build branch";

mkdir 'build'
or die "Can't chdir build";
chdir 'build'
or die "Can't chdir build";
if (not(-f $libgit2_so)) {
mkdir $libgit2_build
or die "Can't mkdir $libgit2_build";
chdir $libgit2_build
or die "Can't chdir $libgit2_build";

system("cmake ..") == 0
or die "Can't cmake libgit2. Maybe you need to install cmake.";

system("cmake --build .") == 0
or die "Can't cmake libgit2. Maybe you need to install cmake.";
or die "Can't cmake --build libgit2.";

chdir $start_dir
or die "Can't chdir to $start_dir";
Expand All @@ -39,18 +35,21 @@ my $obj_files = join ' ', map {
my $c = $_;
$c =~ s/\.c$/$Config::Config{_o}/;
$c;
} glob("*.c"), 'LibGit2.c';
}
# glob("*.c"),
'LibGit2.c';

WriteMakefile(
NAME => 'Git::XS::LibGit2',
NAME => 'Git::XS',
PREREQ_PM => {},
# CCFLAGS => '-ansi -pedantic -Wall',
# CCFLAGS => '-ansi -Wall',
# CCFLAGS => '-pedantic -Wall',
# CCFLAGS => '-Wall',
LIBS => ['-lgit2'], # e.g., '-lm'
INC => "-I.",
LIBS => ["-L$libgit2_build -lgit2"],
INC => "-I. -I$libgit2_inc",
OBJECT => $obj_files,
ABSTRACT_FROM => 'lib/Git/XS/LibGit2.pm',
# ABSTRACT_FROM => '../lib/Git/XS.pm',
ABSTRACT => 'Perl XS binding to libgit2',
AUTHOR => 'Ingy döt Net <ingy@cpan.org>',
);
66 changes: 66 additions & 0 deletions LibGit2/helpers.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
static SV * call_getter(SV *self, char *has) {
dSP;
int count;

ENTER;
SAVETMPS;

PUSHMARK(SP);
XPUSHs(self);
PUTBACK;

count = call_method(has, G_SCALAR);

SPAGAIN;

if (SvTRUE(ERRSV)) {
POPs;
croak("Git::XS error - %s\n", SvPV_nolen(ERRSV));
}

if (count != 1)
croak("O NOES");

SV *ret = SvREFCNT_inc(POPs);

PUTBACK;
FREETMPS;
LEAVE;

return ret;
}

static int call_test(SV *self, char *test, SV* arg) {
dSP;
int count;

ENTER;
SAVETMPS;

PUSHMARK(SP);
XPUSHs(self);
XPUSHs(arg);
PUTBACK;

count = call_method(test, G_SCALAR);

SPAGAIN;

if (SvTRUE(ERRSV)) {
POPs;
croak("Git::XS error - %s\n", SvPV_nolen(ERRSV));
}

if (count != 1)
croak("O NOES");

int ret = POPi;

PUTBACK;
FREETMPS;
LEAVE;

return ret;
}


18 changes: 0 additions & 18 deletions LibGit2/lib/Git/XS/LibGit2.pm

This file was deleted.

15 changes: 0 additions & 15 deletions LibGit2/perl_libgit2.h

This file was deleted.

32 changes: 24 additions & 8 deletions README
Original file line number Diff line number Diff line change
@@ -1,27 +1,43 @@
NAME
Git::XS - Perl XS Wrapper of libgit2
Git::XS - Perl XS binding to libgit2

SYNOPSIS
use Git::XS;

my $git = Git::XS->new();

$git->open("path/to/git/repo");
my $git = Git::XS->new(
repo => "path/to/git/repo",
);

$git->init;

print $git->status;

$git->add('file.name');

$git->commit('-m' => 'It works');
$git->commit(-m => 'It works');

$git->fetch;

$git->push('--all');

$git->close;

DESCRIPTION
This module is a Perl binding to libgit2. It attempts to do things
This module is a Perl binding to libgit2. It attempts to make a clean OO
API for dealing with git repositories from Perl. It should be very fast.

STATUS
WARNING: This module is still in the "proof of concept" phase. Come back
later.

So far new() and init() are working. Kind of.

INSTALLATION
You can install this module like any other CPAN module, but you will
need 2 things:

git - to clone the libgit2 repository from GitHub
cmake - to build libgit2

In the future, this module might use your systems copy of libgit2.

AUTHOR
Ingy döt Net <ingy@cpan.org>
Expand Down
62 changes: 37 additions & 25 deletions lib/Git/XS.pm
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
##
# name: Git::XS
# abstract: Perl XS Wrapper of libgit2
# abstract: Perl XS binding to libgit2
# author: Ingy döt Net <ingy@cpan.org>
# license: perl
# copyright: 2011
Expand All @@ -9,32 +9,24 @@ use 5.010;
use strict;
use warnings;
use Mo 0.30 ();
use XS::Object::Magic 0.04 ();

package Git::XS;
use Mo qw'default';
use Git::XS::LibGit2;
use Mo qw'default build required';

our $VERSION = '0.01';

has repo_path => ();
has stdout => ();
has stderr => ();
has error => ();
has is_open => (default => sub {0});
has is_closed => (default => sub {0});
use XSLoader;
XSLoader::load(__PACKAGE__, $VERSION);

sub open {
my $self = shift;
die "Git::XS object already open" if $self->is_open;
die "Git::XS object already closed" if $self->is_closed;
$self->open(1);
}
sub BUILD { shift->_build }

has repo => ( required => 1 );

sub close {
sub repo_exists {
my $self = shift;
die "Git::XS object is not open" unless $self->is_open;
die "Git::XS object already closed" if $self->is_closed;
$self->close(1);
my $repo = shift;
return -f "$repo/.git/conf" ? 1 : 0;
}

1;
Expand All @@ -43,22 +35,42 @@ sub close {
use Git::XS;
my $git = Git::XS->new();
$git->open("path/to/git/repo");
my $git = Git::XS->new(
repo => "path/to/git/repo",
);
$git->init;
print $git->status;
$git->add('file.name');
$git->commit('-m' => 'It works');
$git->commit(-m => 'It works');
$git->fetch;
$git->push('--all');
$git->close;
=head1 STATUS
WARNING: This module is still in the "proof of concept" phase. Come back
later.
So far new() and init() are working. Kind of.
Find me online if you have good ideas for this module.
=head1 DESCRIPTION
This module is a Perl binding to libgit2. It attempts to do things
This module is a Perl binding to libgit2. It attempts to make a clean OO API
for dealing with git repositories from Perl. It should be very fast.
=head1 INSTALLATION
You can install this module like any other CPAN module, but you will need 2
things:
git - to clone the libgit2 repository from GitHub
cmake - to build libgit2
In the future, this module might use your systems copy of libgit2.
Loading

0 comments on commit 10d4228

Please sign in to comment.