File Coverage

blib/lib/Cogit/Protocol.pm
Criterion Covered Total %
statement 21 78 26.9
branch 0 32 0.0
condition 0 12 0.0
subroutine 7 13 53.8
pod 0 6 0.0
total 28 141 19.8


line stmt bran cond sub pod time code
1             package Cogit::Protocol;
2             $Cogit::Protocol::VERSION = '0.001001';
3 4     4   17 use Moo;
  4         6  
  4         19  
4 4     4   7264 use MooX::Types::MooseLike::Base qw( Str );
  4         6  
  4         195  
5 4     4   18 use namespace::clean;
  4         6  
  4         30  
6              
7 4     4   2325 use Cogit::Protocol::Git;
  4         10  
  4         121  
8 4     4   1816 use Cogit::Protocol::SSH;
  4         9  
  4         133  
9 4     4   1564 use Cogit::Protocol::File;
  4         10  
  4         2193  
10              
11             has remote => (
12             is => 'ro',
13             isa => Str,
14             required => 1,
15             );
16              
17             has read_socket => (is => 'rw');
18             has write_socket => (is => 'rw');
19              
20             sub connect {
21 0     0 0   my $self = shift;
22              
23 0           my @args = (remote => $self->remote);
24              
25 0           my $ret;
26 0 0 0       if ($self->remote =~ m{^git://(.*?@)?(.*?)(/.*)}) {
    0          
    0          
27 0           $ret = Cogit::Protocol::Git->new(
28             @args,
29             hostname => $2,
30             project => $3,
31             );
32             } elsif ($self->remote =~ m{^file://(/.*)}) {
33 0           $ret = Cogit::Protocol::File->new(@args, path => $1,);
34             } elsif ($self->remote =~ m{^ssh://(?:(.*?)@)?(.*?)(/.*)}
35             or $self->remote =~ m{^(?:(.*?)@)?(.*?):(.*)}) {
36 0 0         $ret = Cogit::Protocol::SSH->new(
37             @args,
38             $1 ? (username => $1) : (),
39             hostname => $2,
40             path => $3,
41             );
42             }
43              
44 0           $ret->connect_socket;
45              
46 0           return $ret
47             }
48              
49             sub fetch {
50 0     0 0   my $self = shift;
51              
52 0           my %sha1s;
53 0           while (my $line = $self->read_line()) {
54              
55             # warn "S $line";
56 0           my ($sha1, $name) = $line =~ /^([a-z0-9]+) ([^\0\n]+)/;
57              
58             #use YAML; warn Dump $line;
59 0           $sha1s{$name} = $sha1;
60             }
61 0           return \%sha1s;
62             }
63              
64             sub fetch_pack {
65 0     0 0   my ($self, $sha1) = @_;
66 0           $self->send_line("want $sha1 side-band-64k\n");
67              
68             #send_line(
69             # "want 0c7b3d23c0f821e58cd20e60d5e63f5ed12ef391 multi_ack side-band-64k ofs-delta\n"
70             #);
71 0           $self->send_line('');
72 0           $self->send_line('done');
73              
74 0           my $pack;
75              
76 0           while (my $line = $self->read_line()) {
77 0 0         if ($line =~ s/^\x02//) {
    0          
    0          
78 0           print $line;
79             } elsif ($line =~ /^NAK\n/) {
80             } elsif ($line =~ s/^\x01//) {
81 0           $pack .= $line;
82             } else {
83 0           die "Unknown line: $line";
84             }
85              
86             #say "s $line";
87             }
88 0           return $pack;
89             }
90              
91             sub send_line {
92 0     0 0   my ($self, $line) = @_;
93 0           my $length = length($line);
94 0 0         if ($length == 0) {
95             } else {
96 0           $length += 4;
97             }
98              
99             #warn "length $length";
100 0           my $prefix = sprintf("%04X", $length);
101 0           my $text = $prefix . $line;
102              
103             # warn "$text";
104 0 0         $self->write_socket->print($text) || die $!;
105             }
106              
107             sub read {
108 0     0 0   my $self = shift;
109 0           my $len = shift;
110              
111 0           my $ret = "";
112 4     4   25 use bytes;
  4         13  
  4         26  
113 0           while (1) {
114 0           my $got = $self->read_socket->read(my $data, $len - length($ret));
115 0 0         if (not defined $got) {
    0          
116 0           die "error: $!";
117             } elsif ($got == 0) {
118 0           die "EOF"
119             }
120 0           $ret .= $data;
121 0 0         if (length($ret) == $len) {
122 0           return $ret;
123             }
124             }
125             }
126              
127             sub read_line {
128 0     0 0   my $self = shift;
129 0           my $socket = $self->read_socket;
130              
131 0           my $prefix = $self->read(4);
132              
133 0 0         return if $prefix eq '0000';
134              
135             # warn "read prefix [$prefix]";
136              
137 0           my $len = 0;
138 0           for my $n (0 .. 3) {
139 0           my $c = substr($prefix, $n, 1);
140 0           $len <<= 4;
141              
142 0 0 0       if ($c ge '0' && $c le '9') {
    0 0        
    0 0        
143 0           $len += ord($c) - ord('0');
144             } elsif ($c ge 'a' && $c le 'f') {
145 0           $len += ord($c) - ord('a') + 10;
146             } elsif ($c ge 'A' && $c le 'F') {
147 0           $len += ord($c) - ord('A') + 10;
148             }
149             }
150              
151 0           return $self->read($len - 4);
152             }
153              
154             1;
155              
156             __END__
157              
158             =pod
159              
160             =encoding UTF-8
161              
162             =head1 NAME
163              
164             Cogit::Protocol
165              
166             =head1 VERSION
167              
168             version 0.001001
169              
170             =head1 AUTHOR
171              
172             Arthur Axel "fREW" Schmidt <cogit@afoolishmanifesto.com>
173              
174             =head1 COPYRIGHT AND LICENSE
175              
176             This software is copyright (c) 2017 by Arthur Axel "fREW" Schmidt.
177              
178             This is free software; you can redistribute it and/or modify it under
179             the same terms as the Perl 5 programming language system itself.
180              
181             =cut