2 #############################################################################
4 ## Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
5 ## All rights reserved.
6 ## Contact: Nokia Corporation (qt-info@nokia.com)
8 ## This file is part of the utilities of the Qt Toolkit.
10 ## $QT_BEGIN_LICENSE:LGPL$
11 ## No Commercial Usage
12 ## This file contains pre-release code and may not be distributed.
13 ## You may use this file in accordance with the terms and conditions
14 ## contained in the Technology Preview License Agreement accompanying
17 ## GNU Lesser General Public License Usage
18 ## Alternatively, this file may be used under the terms of the GNU Lesser
19 ## General Public License version 2.1 as published by the Free Software
20 ## Foundation and appearing in the file LICENSE.LGPL included in the
21 ## packaging of this file. Please review the following information to
22 ## ensure the GNU Lesser General Public License version 2.1 requirements
23 ## will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 ## In addition, as a special exception, Nokia gives you certain additional
26 ## rights. These rights are described in the Nokia Qt LGPL Exception
27 ## version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 ## If you have questions regarding the use of this file, please contact
30 ## Nokia at qt-info@nokia.com.
41 #############################################################################
46 package Qt::InitRepository;
51 init-repository - initialize the Qt5 repository and all submodules
55 ./init-repository [options]
57 This script may be run after an initial `git clone' of Qt5 in order to check
61 =head2 Global options:
67 Force initialization (even if the submodules are already checked out).
72 Be quiet. Will exit cleanly if the repository is already initialized.
77 =head2 Module options:
83 Skip webkit and webkit examples submodules.
84 It may be desirable to skip these modules due to the large size of the webkit
90 Skip the `git submodule update' command.
93 =item --ignore-submodules
95 Set git config to ignore submodules by default when doing operations on the
96 qt5 repo, such as `pull', `fetch', `diff' etc.
98 After using this option, pass `--ignore-submodules=none' to git to override
104 =head2 Repository options:
108 =item --nokia-developer
110 Switch to internal Nokia URLs.
115 Switch to internal Nokia URLs and make use of the Brisbane git mirrors.
116 (Implies `--mirror' and `--mirror-webkit').
121 Use the SSH protocol for git operations. This may be useful if the git
122 protocol is blocked by a firewall. Note that this requires a user account
123 with an uploaded SSH key on all servers used. (Implies `--nokia-developer').
128 Use the HTTP protocol for git operations. This may be useful if the git
129 protocol is blocked by a firewall. Note that this only works with the
130 external Gitorious server.
133 =item --alternates <path to other Qt5 repo>
135 Adds alternates for each submodule to another full qt5 checkout. This makes
136 this qt5 checkout very small, as it will use the object store of the
137 alternates before unique objects are stored in its own object store.
139 This option has no effect when using `--no-update'.
141 B<NOTE:> This will make this repo dependent on the alternate, which is
142 potentially dangerous! The dependency can be broken by also using
143 the `--copy-objects' option, or by running C<git repack -a> in each
144 submodule, where required. Please read the note about the `--shared' option
145 in the documentation of `git clone' for more information.
150 When `--alternates' is used, automatically do a C<git repack -a> in each
151 submodule after cloning, to ensure that the repositories are independent
152 from the source used as a reference for cloning.
154 Note that this negates the disk usage benefits gained from the use of
158 =item --mirror <url-base>
160 Uses <url-base> as the base URL for submodule git mirrors.
164 --mirror user@machine:/foo/bar
166 ...will use the following as a mirror for qtbase:
168 user@machine:/foo/bar/qtbase.git
171 =item --mirror-webkit <url>
173 Uses <url> as the URL for the webkit git mirror.
179 use Carp qw( confess );
180 use English qw( -no_match_vars );
181 use Getopt::Long qw( GetOptionsFromArray );
182 use Pod::Usage qw( pod2usage );
185 'internal' => 'git://scm.dev.nokia.troll.no/' ,
186 'ssh' => 'git@scm.dev.nokia.troll.no:' ,
187 'http' => 'http://git.gitorious.org/' ,
190 my %STAGING_REPOS = map { $_ => "git://gitorious.org/qt/$_.git" } qw(
196 qtdeclarative-staging
204 qttranslations-staging
205 qtwebkit-examples-and-demos-staging
206 qtxmlpatterns-staging
209 my $BNE_MIRROR_URL_BASE
210 = 'git://bq-git.apac.nokia.com/qtsoftware/qt/';
212 my $BNE_MIRROR_WEBKIT_URL
213 = 'git://bq-git.apac.nokia.com/qtsoftware/research/gitorious-org-webkit-qtwebkit-mirror.git';
217 my ($class, @arguments) = @_;
221 $self->parse_arguments(@arguments);
226 # Like `system', but possibly log the command, and die on non-zero exit code
229 my ($self, @cmd) = @_;
231 if (!$self->{quiet}) {
235 if (system(@cmd) != 0) {
236 confess "@cmd exited with status $CHILD_ERROR";
244 my ($self, @args) = @_;
246 %{$self} = (%{$self},
248 'detach-alternates' => 0 ,
250 'ignore-submodules' => 0 ,
252 'mirror-webkit-url' => "",
253 'nokia-developer' => 0 ,
259 GetOptionsFromArray(\@args,
260 'alternates=s' => \$self->{qw{ alternates }},
261 'copy-objects' => \$self->{qw{ detach-alternates }},
262 'force' => \$self->{qw{ force }},
263 'ignore-submodules' => \$self->{qw{ ignore_submodules }},
264 'mirror-webkit=s' => \$self->{qw{ mirror-webkit-url }},
265 'mirror=s' => \$self->{qw{ mirror-url }},
266 'nokia-developer' => \$self->{qw{ nokia-developer }},
267 'quiet' => \$self->{qw{ quiet }},
268 'update!' => \$self->{qw{ update }},
269 'webkit!' => \$self->{qw{ webkit }},
271 'help|?' => sub { pod2usage(1); },
272 'http' => sub { $self->{protocol} = 'http'; },
273 'ssh|ssh-protocol' => sub { $self->{protocol} = 'ssh'; },
275 'brisbane|brisbane-nokia-developer' => sub {
276 $self->{'nokia-developer'} = 1;
277 $self->{'protocol'} = 'internal';
278 $self->{'mirror-url'} = $BNE_MIRROR_URL_BASE;
279 $self->{'mirror-webkit-url'} = $BNE_MIRROR_WEBKIT_URL;
282 'nokia-developer' => sub {
283 $self->{'nokia-developer'} = 1;
284 $self->{'protocol'} = 'internal';
288 if ($self->{'nokia-developer'} && $self->{'protocol'} eq 'http') {
289 print "*** Ignoring use of HTTP protocol, as it's only usable with external server\n";
290 $self->{'protocol'} = '';
293 # Replace any double trailing slashes from end of mirror
294 $self->{'mirror-url'} =~ s{//+$}{/};
299 sub check_if_already_initialized
303 # We consider the repo as `initialized' if submodule.qtbase.url is set
304 if (qx(git config --get submodule.qtbase.url)) {
305 if ($self->{force}) {
306 my @configresult = qx(git config -l);
307 foreach (@configresult) {
308 # Example line: submodule.qtqa.url=git://gitorious.org/qt/qtqa.git
309 if (/(submodule\.[^.=]+)\.url=.*/) {
310 $self->exe('git', 'config', '--remove-section', $1);
315 exit 0 if ($self->{quiet});
316 print "Will not reinitialize already initialized repository (use -f to force)!\n";
324 sub git_submodule_init
329 if ($self->{quiet}) {
330 push @init_args, '--quiet';
332 $self->exe('git', 'submodule', 'init', @init_args);
337 sub git_disable_webkit_submodule
341 $self->exe('git', 'config', '--remove', 'submodule.qtwebkit');
342 $self->exe('git', 'config', '--remove', 'submodule.qtwebkit-examples-and-demos');
347 sub git_set_submodule_config
351 my @configresult = qx(git config -l);
352 my $protocol = $self->{protocol};
353 my $url_base_for_protocol = $PROTOCOLS{$protocol};
356 foreach my $line (@configresult) {
357 # Example line: submodule.qtqa.url=git://gitorious.org/qt/qtqa.git
358 next GITCONFIG if ($line !~ /(submodule\.[^.=]+\.url)=(.*)/);
364 # WebKit is special, and has only external link.
365 if ($key ne 'submodule.qtwebkit.url') {
366 # qt-labs projects are still hosted under qt internally.
367 if ($protocol ne 'http') {
368 $value =~ s,^git://gitorious\.org/qt-labs/,${url_base_for_protocol}qt/,;
370 $value =~ s,^git://gitorious\.org/,$url_base_for_protocol,;
374 $self->exe('git', 'config', $key, $value);
376 if ($self->{'ignore-submodules'}) {
377 $key =~ s,\.url,.ignore,;
378 $self->exe('git', 'config', $key, 'all');
385 sub git_clone_all_submodules
389 # manually clone each repo here, so we can easily use reference repos, mirrors and
390 # add all staging repos
391 my @configresult = qx(git config -l);
392 foreach my $line (@configresult) {
393 if ($line =~ /submodule\.([^.=]+)\.url=(.*)/) {
394 $self->git_clone_one_submodule($1, $2);
398 $self->exe('git', 'submodule', 'update');
403 sub git_add_staging_remote
405 my ($self, $repo_basename) = @_;
407 my $protocol = $self->{protocol};
408 my $url_base_for_protocol = $PROTOCOLS{$protocol};
411 for my $line (qx(git remote show)) {
413 $current_remotes{$line} = 1;
416 # We assume that any staging starting with `$repo_basename-' relates to this
417 # repo. For example, for the `qtbase' module, `qtbase-staging'
418 # and `qtbase-earth-staging' are considered as related staging repos.
419 my @staging = grep { /^\Q$repo_basename\E-/; } keys %STAGING_REPOS;
422 foreach my $staging_repo (@staging) {
423 # nothing to do if remote already exists
424 next STAGING if ($current_remotes{$staging_repo});
426 my $staging_repo_url = $STAGING_REPOS{$staging_repo};
428 if ($protocol ne 'http') {
429 $staging_repo_url =~ s,^git://gitorious\.org/qt-labs/,${url_base_for_protocol}qt/,;
431 $staging_repo_url =~ s,^git://gitorious\.org/,$url_base_for_protocol,;
433 $self->exe('git', 'remote', 'add', $staging_repo, $staging_repo_url);
439 sub git_clone_one_submodule
441 my ($self, $submodule, $url) = @_;
443 my $alternates = $self->{ 'alternates' };
444 my $mirror_url = $self->{ 'mirror-url' };
445 my $mirror_webkit_url = $self->{ 'mirror-webkit-url' };
447 # `--reference FOO' args for the clone, if any.
451 # alternates is a qt5 repo, so the submodule will be under that.
452 if (-d "$alternates/$submodule") {
453 @reference_args = ('--reference', "$alternates/$submodule");
456 print " *** $alternates/$submodule not found, ignoring alternate for this submodule\n";
461 if ($mirror_url && ($submodule ne 'qtwebkit')) {
462 $mirror = $mirror_url.$submodule;
463 $mirror .= ".git" unless (-d $mirror); # Support local disk mirror
465 elsif ($mirror_webkit_url && ($submodule eq 'qtwebkit')) {
466 $mirror = $mirror_webkit_url;
469 my $do_clone = (! -d "$submodule/.git");
471 $self->exe('git', 'clone', @reference_args, ($mirror ? $mirror : $url), $submodule);
474 chdir($submodule) or confess "chdir $submodule: $OS_ERROR";
477 $self->exe('git', 'fetch', ($mirror ? $mirror : $url));
481 $self->exe('git', 'config', 'remote.origin.url', $url);
482 $self->exe('git', 'remote', 'add', 'mirror', $mirror);
485 $self->git_add_staging_remote($submodule);
487 if ($self->{'detach-alternates'}) {
488 $self->exe('git', 'repack', '-a');
490 my $alternates_path = '.git/objects/info/alternates';
491 unlink($alternates_path) || confess "unlink $alternates_path: $OS_ERROR";
494 chdir("..") or confess "cd ..: $OS_ERROR";
503 $self->check_if_already_initialized;
504 $self->git_submodule_init;
506 if (!$self->{webkit}) {
507 $self->git_disable_webkit_submodule;
510 $self->git_set_submodule_config;
512 if ($self->{update}) {
513 $self->git_clone_all_submodules;
516 $self->git_add_staging_remote('qt5');
521 #==============================================================================
523 Qt::InitRepository->new(@ARGV)->run if (!caller);