forked from github/platform-samples
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathboot
executable file
·180 lines (149 loc) · 5.93 KB
/
boot
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
#!/usr/bin/perl
#
# Bootstrap a repository. See here for more info:
# https://github.com/github/platform-samples/tree/master/scripts/bootstrap/create-bootstrap
#
use 5.010;
use strict;
use warnings;
use File::Basename;
use MIME::Base64;
my $min_git_version=2.16.0;
my $min_git_lfs_version=2.3.4;
sub error_exit {
my($msg) = shift;
$msg = 'Bootstrapping repository failed.' if !$msg;
print STDERR "ERROR: $msg\n";
exit 1;
}
sub run {
my($cmd, $err_msg) = @_;
system($cmd) == 0 or error_exit($err_msg);
}
# Set a local config for the repository
sub config {
my($keyvalue) = shift;
run('git config --local ' . $keyvalue);
}
sub header {
my($str) = shift;
print "\n##############################################################\n";
print " " . $str;
print "\n##############################################################\n";
}
my $start = time;
header('Checking Git and Git LFS...');
#
# Upgrade Git
#
# TODO: Currently we upgrade Git only Windows. In the future we could check if
# Git is installed via Homebrew on MacOS and upgrade it there too.
if ($^O eq 'MSWin32') {
system('git update-git-for-windows --gui');
}
#
# Check versions
#
my ($git_version) = `git --version` =~ /([0-9]+([.][0-9]+)+)/;
if (version->parse($git_version) lt version->parse($min_git_version)) {
error_exit("Git version $git_version on this system is outdated. Please upgrade to the latest version!");
}
print "Git version: $git_version\n";
my ($git_lfs_version) = `git lfs version` =~ /([0-9]+([.][0-9]+)+)/;
if (!$git_lfs_version) {
error_exit("Git LFS seems not to be installed on this system.\nPlease follow install instructions on https://git-lfs.github.com/");
}
if (version->parse($git_lfs_version) lt version->parse($min_git_lfs_version)) {
error_exit("Git LFS version $git_version on this system is outdated. Please upgrade to the latest version!");
}
print "Git LFS version: $git_lfs_version\n";
if (system('git config user.name >/dev/null') != 0) {
print "\nIt looks like your name was not configured in Git yet.\n";
print "Please enter your name: ";
chomp(my $username = <STDIN>);
system('git config --global user.name ' . $username);
}
if (system('git config user.email >/dev/null') != 0) {
# TODO: We could check for the correct email format here
print "\nIt looks like your email was not configured in Git yet.\n";
print "Please enter your email address: ";
chomp(my $email = <STDIN>);
system('git config --global user.email ' . $email);
} else {
print "\nGit user: " . `git config --null user.name` . "\n";
print "Git email: " . `git config --null user.email` . "\n";
}
header('Bootstrapping repository...');
#
# Configure the repo
#
chdir dirname(__FILE__);
if (`git rev-parse --abbrev-ref HEAD` !~ /bootstrap/) {
error_exit("Please run '$0' from the bootstrap branch");
}
# Ensure we are starting from a clean state in case the script is failed
# in a previous run.
run('git reset --hard HEAD --quiet');
run('git clean --force -fdx');
# Ensure Git LFS is initialized in the repo
run('git lfs install --local >/dev/null', 'Initializing Git LFS failed.');
# Enable file system cache on Windows (no effect on OS X/Linux)
# see https://groups.google.com/forum/#!topic/git-for-windows/9WrSosaa4A8
config('core.fscache true');
# If the Git LFS locking feature is used, then Git LFS will set lockable files
# to "readonly" by default. This is implemented with a Git LFS "post-checkout"
# hook. Git LFS can skip this hook if no file is locked. However, Git LFS needs
# to traverse the entire tree to find all ".gitattributes" and check for locked
# files. In a large tree (e.g. >20k directories, >300k files) this can take a
# while. Instruct Git LFS to not set lockable files to "readonly". This skips
# the "post-checkout" entirely and speeds up Git LFS for large repositories.
config('lfs.setlockablereadonly false');
# Enable long path support for Windows (no effect on OS X/Linux)
# Git uses the proper API to create long paths on Windows. However, many
# Windows applications use an outdated API that only support paths up to a
# length of 260 characters. As a result these applications would not be able to
# work with the longer paths properly. Keep that in mind if you run into path
# trouble!
# see https://msdn.microsoft.com/en-us/library/aa365247(VS.85).aspx
config('core.longpaths true');
if (system('git config core.untrackedCache >/dev/null 2>&1') == 1 &&
system('git update-index --test-untracked-cache') == 0) {
# Enable untracked cache if the file system supports it
# see https://news.ycombinator.com/item?id=11388479
config('core.untrackedCache true');
config('feature.manyFiles true');
}
config('protocol.version 2');
# Download Submodule content in parallel
# see https://git-scm.com/docs/git-config#Documentation/git-config.txt-submodulefetchJobs
config('submodule.fetchJobs 0');
# Speed up "git status" and by suppressing unnecessary terminal output
# see https://github.com/git/git/commit/fd9b544a2991ad74d73ad1bc0af4d24f91a6802b
config('status.aheadBehind false');
#
# Prepare the repo
#
if (-e 'pack/lfs-objects-1.tar.gz') {
# Get the LFS "pack files"
run('git lfs pull --include="pack/lfs-objects-*.tar.gz"', 'Downloading Git LFS pack files failed.');
print "\n";
my $error_lfs = 'Extracting Git LFS pack files failed.';
my $progress = 0;
open(my $pipe, 'tar -xzvf pack/lfs-objects-* 2>&1 |') or error_exit($error_lfs);
while (my $line = <$pipe> ) {
$progress++;
print "\rExtracting LFS objects: $progress/lfs_pack_count";
}
close($pipe) or error_exit($error_lfs);
print "\n";
}
# Check out default branch
run('git checkout --force default_branch');
if (-e '.gitmodules') {
run('git submodule update --init --recursive --reference .git');
}
# Cleanup now obsolete Git LFS pack files
run('git -c lfs.fetchrecentcommitsdays=0 -c lfs.fetchrecentrefsdays=0 -c lfs.fetchrecentremoterefs=false -c lfs.pruneoffsetdays=0 lfs prune >/dev/null');
header('Hurray! Your Git repository is ready for you!');
my $duration = time - $start;
print "Bootstrap time: $duration s\n";