-
Notifications
You must be signed in to change notification settings - Fork 0
/
cg-Xfetchprogress
executable file
·116 lines (96 loc) · 2.6 KB
/
cg-Xfetchprogress
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#!/usr/bin/env perl
#
# Show a cute progressbar for cg-fetch
# Copyright (c) Petr Baudis, 2005
#
# This file shows a progressbar for cg-fetch based on output of rsync
# or native git fetchers. It is written in perl because I cannot figure
# out a way to check a file size without slowing the fetch by a factor
# of four.
use warnings;
use strict;
# Even line-buffering is bad since we output no newlines normally.
$| = 1;
my $_git_objects = shift;
my $objects = 0;
my $size = 0;
my $osize = 0;
my $percentage = '';
my $object = '';
my $timeout = 1;
my $rin = '';
vec($rin, fileno(STDIN), 1) = 1;
my $ein = $rin;
while (1) {
my ($rout, $eout);
# POSIX might be mad at us about <> vs. select(), but what can go
# wrong with $|==1?
if (not select($rout = $rin, undef, $eout = $ein, $timeout)) {
# Timeout, show file progress
$timeout = 0.25; # Update more frequently
if ($object) {
my ($objid) = ($object =~ /([a-f0-9]{12})[^\/]*$/);
my $fobject = "$_git_objects/$object";
if (-e $fobject or -e ($fobject .= ".temp")) {
my $fsize = (stat("$fobject"))[7];
$size = $osize + $fsize;
progress(', now fetching '.$objid.'... ('.$fsize.' bytes)');
}
}
} elsif (vec($eout, fileno(STDIN), 1)) {
finish:
# Error - fetch agent is probably finished
print "\n";
exit 0;
} else {
# Next line from the fetch agent
$timeout = 1; # ...seconds before we show per-file progress
getline() or goto finish;
}
}
sub getline {
$_ = <STDIN>;
return 0 if not defined $_;
chomp;
# git fetcher
if (m#^(link|symlink|copy|got) ([a-f0-9]{2})([a-f0-9]{38})#) {
$object = "$2/$3";
} elsif (m#^(ref|walk) ([a-f0-9]{2})([a-f0-9]{38})#) {
return 1; # redundant information
# rsync
} elsif (m#^([a-f0-9]{2})/([a-f0-9]{38})$#) {
$object = $_;
# Estimate percentage done using the position of
# the object subdir. It might not get all the way
# up to 100% ...
$percentage = ', ' . int(hex($1) * 100 / 0xff) . '% done';
# rsync packs
} elsif (m#^pack/pack-(.+)$#) {
$object = $_;
print "Getting pack file $_\033[K\n";
progress('');
return 1;
# some rsync versions output this
} elsif (m#^([a-f0-9]{2})/$#) {
return 1;
# misc. output
} else {
if (m#^Getting index for pack ([a-f0-9]{40})#) {
$object = "pack/pack-$1.idx";
} elsif (m#^Getting pack ([a-f0-9]{40})#) {
$object = "pack/pack-$1.pack";
}
print "$_\033[K\n";
progress('');
return 1;
}
my $fobject = "$_git_objects/$object";
-e $fobject and $size += (stat($fobject))[7];
$osize = $size;
$objects++;
progress('');
return 1;
}
sub progress {
print "progress: $objects objects, $size bytes$percentage$_[0]\033[K\r";
}