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
210 my $BNE_MIRROR_URL_BASE
211 = 'git://bq-git.apac.nokia.com/qtsoftware/qt/';
213 my $BNE_MIRROR_WEBKIT_URL
214 = 'git://bq-git.apac.nokia.com/qtsoftware/research/gitorious-org-webkit-qtwebkit-mirror.git';
218 my ($class, @arguments) = @_;
222 $self->parse_arguments(@arguments);
227 # Like `system', but possibly log the command, and die on non-zero exit code
230 my ($self, @cmd) = @_;
232 if (!$self->{quiet}) {
236 if (system(@cmd) != 0) {
237 confess "@cmd exited with status $CHILD_ERROR";
245 my ($self, @args) = @_;
247 %{$self} = (%{$self},
249 'detach-alternates' => 0 ,
251 'ignore-submodules' => 0 ,
253 'mirror-webkit-url' => "",
254 'nokia-developer' => 0 ,
260 GetOptionsFromArray(\@args,
261 'alternates=s' => \$self->{qw{ alternates }},
262 'copy-objects' => \$self->{qw{ detach-alternates }},
263 'force' => \$self->{qw{ force }},
264 'ignore-submodules' => \$self->{qw{ ignore_submodules }},
265 'mirror-webkit=s' => \$self->{qw{ mirror-webkit-url }},
266 'mirror=s' => \$self->{qw{ mirror-url }},
267 'nokia-developer' => \$self->{qw{ nokia-developer }},
268 'quiet' => \$self->{qw{ quiet }},
269 'update!' => \$self->{qw{ update }},
270 'webkit!' => \$self->{qw{ webkit }},
272 'help|?' => sub { pod2usage(1); },
273 'http' => sub { $self->{protocol} = 'http'; },
274 'ssh|ssh-protocol' => sub { $self->{protocol} = 'ssh'; },
276 'brisbane|brisbane-nokia-developer' => sub {
277 $self->{'nokia-developer'} = 1;
278 $self->{'protocol'} = 'internal';
279 $self->{'mirror-url'} = $BNE_MIRROR_URL_BASE;
280 $self->{'mirror-webkit-url'} = $BNE_MIRROR_WEBKIT_URL;
283 'nokia-developer' => sub {
284 $self->{'nokia-developer'} = 1;
285 $self->{'protocol'} = 'internal';
289 if ($self->{'nokia-developer'} && $self->{'protocol'} eq 'http') {
290 print "*** Ignoring use of HTTP protocol, as it's only usable with external server\n";
291 $self->{'protocol'} = '';
294 # Replace any double trailing slashes from end of mirror
295 $self->{'mirror-url'} =~ s{//+$}{/};
300 sub check_if_already_initialized
304 # We consider the repo as `initialized' if submodule.qtbase.url is set
305 if (qx(git config --get submodule.qtbase.url)) {
306 if ($self->{force}) {
307 my @configresult = qx(git config -l);
308 foreach (@configresult) {
309 # Example line: submodule.qtqa.url=git://gitorious.org/qt/qtqa.git
310 if (/(submodule\.[^.=]+)\.url=.*/) {
311 $self->exe('git', 'config', '--remove-section', $1);
316 exit 0 if ($self->{quiet});
317 print "Will not reinitialize already initialized repository (use -f to force)!\n";
325 sub git_submodule_init
330 if ($self->{quiet}) {
331 push @init_args, '--quiet';
333 $self->exe('git', 'submodule', 'init', @init_args);
338 sub git_disable_webkit_submodule
342 $self->exe('git', 'config', '--remove', 'submodule.qtwebkit');
343 $self->exe('git', 'config', '--remove', 'submodule.qtwebkit-examples-and-demos');
348 sub git_set_submodule_config
352 my @configresult = qx(git config -l);
353 my $protocol = $self->{protocol};
354 my $url_base_for_protocol = $PROTOCOLS{$protocol};
357 foreach my $line (@configresult) {
358 # Example line: submodule.qtqa.url=git://gitorious.org/qt/qtqa.git
359 next GITCONFIG if ($line !~ /(submodule\.[^.=]+\.url)=(.*)/);
365 # WebKit is special, and has only external link.
366 if ($key ne 'submodule.qtwebkit.url') {
367 # qt-labs projects are still hosted under qt internally.
368 if ($protocol ne 'http') {
369 $value =~ s,^git://gitorious\.org/qt-labs/,${url_base_for_protocol}qt/,;
371 $value =~ s,^git://gitorious\.org/,$url_base_for_protocol,;
375 $self->exe('git', 'config', $key, $value);
377 if ($self->{'ignore-submodules'}) {
378 $key =~ s,\.url,.ignore,;
379 $self->exe('git', 'config', $key, 'all');
386 sub git_clone_all_submodules
390 # manually clone each repo here, so we can easily use reference repos, mirrors and
391 # add all staging repos
392 my @configresult = qx(git config -l);
393 foreach my $line (@configresult) {
394 if ($line =~ /submodule\.([^.=]+)\.url=(.*)/) {
395 $self->git_clone_one_submodule($1, $2);
399 $self->exe('git', 'submodule', 'update');
404 sub git_add_staging_remote
406 my ($self, $repo_basename) = @_;
408 my $protocol = $self->{protocol};
409 my $url_base_for_protocol = $PROTOCOLS{$protocol};
412 for my $line (qx(git remote show)) {
414 $current_remotes{$line} = 1;
417 # We assume that any staging starting with `$repo_basename-' relates to this
418 # repo. For example, for the `qtbase' module, `qtbase-staging'
419 # and `qtbase-earth-staging' are considered as related staging repos.
420 my @staging = grep { /^\Q$repo_basename\E-/; } keys %STAGING_REPOS;
423 foreach my $staging_repo (@staging) {
424 # nothing to do if remote already exists
425 next STAGING if ($current_remotes{$staging_repo});
427 my $staging_repo_url = $STAGING_REPOS{$staging_repo};
429 if ($protocol ne 'http') {
430 $staging_repo_url =~ s,^git://gitorious\.org/qt-labs/,${url_base_for_protocol}qt/,;
432 $staging_repo_url =~ s,^git://gitorious\.org/,$url_base_for_protocol,;
434 $self->exe('git', 'remote', 'add', $staging_repo, $staging_repo_url);
440 sub git_clone_one_submodule
442 my ($self, $submodule, $url) = @_;
444 my $alternates = $self->{ 'alternates' };
445 my $mirror_url = $self->{ 'mirror-url' };
446 my $mirror_webkit_url = $self->{ 'mirror-webkit-url' };
448 # `--reference FOO' args for the clone, if any.
452 # alternates is a qt5 repo, so the submodule will be under that.
453 if (-d "$alternates/$submodule") {
454 @reference_args = ('--reference', "$alternates/$submodule");
457 print " *** $alternates/$submodule not found, ignoring alternate for this submodule\n";
462 if ($mirror_url && ($submodule ne 'qtwebkit')) {
463 $mirror = $mirror_url.$submodule;
464 $mirror .= ".git" unless (-d $mirror); # Support local disk mirror
466 elsif ($mirror_webkit_url && ($submodule eq 'qtwebkit')) {
467 $mirror = $mirror_webkit_url;
470 my $do_clone = (! -d "$submodule/.git");
472 $self->exe('git', 'clone', @reference_args, ($mirror ? $mirror : $url), $submodule);
475 chdir($submodule) or confess "chdir $submodule: $OS_ERROR";
478 $self->exe('git', 'fetch', ($mirror ? $mirror : $url));
482 $self->exe('git', 'config', 'remote.origin.url', $url);
484 # In `force' mode, remove the mirror if it already exists,
485 # since we may be reinitializing the module.
486 if ($self->{force}) {
487 eval { $self->exe('git', 'remote', 'rm', 'mirror'); }; # failure is OK
490 $self->exe('git', 'remote', 'add', 'mirror', $mirror);
493 $self->git_add_staging_remote($submodule);
495 if ($self->{'detach-alternates'}) {
496 $self->exe('git', 'repack', '-a');
498 my $alternates_path = '.git/objects/info/alternates';
499 unlink($alternates_path) || confess "unlink $alternates_path: $OS_ERROR";
502 chdir("..") or confess "cd ..: $OS_ERROR";
511 $self->check_if_already_initialized;
512 $self->git_submodule_init;
514 if (!$self->{webkit}) {
515 $self->git_disable_webkit_submodule;
518 $self->git_set_submodule_config;
520 if ($self->{update}) {
521 $self->git_clone_all_submodules;
524 $self->git_add_staging_remote('qt5');
529 #==============================================================================
531 Qt::InitRepository->new(@ARGV)->run if (!caller);