xref: /aoo41x/main/solenv/bin/cws.pl (revision 7e90fac2)
1cdf0e10cSrcweir#!/usr/bin/perl -w
2*7e90fac2SAndrew Rist#**************************************************************
3*7e90fac2SAndrew Rist#
4*7e90fac2SAndrew Rist#  Licensed to the Apache Software Foundation (ASF) under one
5*7e90fac2SAndrew Rist#  or more contributor license agreements.  See the NOTICE file
6*7e90fac2SAndrew Rist#  distributed with this work for additional information
7*7e90fac2SAndrew Rist#  regarding copyright ownership.  The ASF licenses this file
8*7e90fac2SAndrew Rist#  to you under the Apache License, Version 2.0 (the
9*7e90fac2SAndrew Rist#  "License"); you may not use this file except in compliance
10*7e90fac2SAndrew Rist#  with the License.  You may obtain a copy of the License at
11*7e90fac2SAndrew Rist#
12*7e90fac2SAndrew Rist#    http://www.apache.org/licenses/LICENSE-2.0
13*7e90fac2SAndrew Rist#
14*7e90fac2SAndrew Rist#  Unless required by applicable law or agreed to in writing,
15*7e90fac2SAndrew Rist#  software distributed under the License is distributed on an
16*7e90fac2SAndrew Rist#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17*7e90fac2SAndrew Rist#  KIND, either express or implied.  See the License for the
18*7e90fac2SAndrew Rist#  specific language governing permissions and limitations
19*7e90fac2SAndrew Rist#  under the License.
20*7e90fac2SAndrew Rist#
21*7e90fac2SAndrew Rist#**************************************************************
22*7e90fac2SAndrew Rist
23*7e90fac2SAndrew Rist
24cdf0e10cSrcweir
25cdf0e10cSrcweir#*************************************************************************
26cdf0e10cSrcweir#
27cdf0e10cSrcweir# cws.pl   - wrap common childworkspace operations
28cdf0e10cSrcweir#
29cdf0e10cSrcweiruse strict;
30cdf0e10cSrcweiruse Getopt::Long;
31cdf0e10cSrcweiruse File::Basename;
32cdf0e10cSrcweiruse File::Path;
33cdf0e10cSrcweiruse File::Copy;
34cdf0e10cSrcweiruse Cwd;
35cdf0e10cSrcweiruse Benchmark;
36cdf0e10cSrcweir
37cdf0e10cSrcweir#### module lookup
38cdf0e10cSrcweirmy @lib_dirs;
39cdf0e10cSrcweirBEGIN {
40cdf0e10cSrcweir    if ( !defined($ENV{SOLARENV}) ) {
41cdf0e10cSrcweir        die "No environment found (environment variable SOLARENV is undefined)";
42cdf0e10cSrcweir    }
43cdf0e10cSrcweir    push(@lib_dirs, "$ENV{SOLARENV}/bin/modules");
44cdf0e10cSrcweir}
45cdf0e10cSrcweiruse lib (@lib_dirs);
46cdf0e10cSrcweir
47cdf0e10cSrcweiruse Cws;
48cdf0e10cSrcweir
49cdf0e10cSrcweir#### script id #####
50cdf0e10cSrcweir
51cdf0e10cSrcweir( my $script_name = $0 ) =~ s/^.*\b(\w+)\.pl$/$1/;
52cdf0e10cSrcweir
53cdf0e10cSrcweir#### globals ####
54cdf0e10cSrcweir
55cdf0e10cSrcweir# TODO: replace dummy vales with actual source_config migration milestone
56cdf0e10cSrcweirmy $ooo320_source_config_milestone = 'm999';
57cdf0e10cSrcweir
58cdf0e10cSrcweir# valid command with possible abbreviations
59cdf0e10cSrcweirmy @valid_commands = (
60cdf0e10cSrcweir                        'help', 'h', '?',
61cdf0e10cSrcweir                        'create',
62cdf0e10cSrcweir                        'fetch',  'f',
63cdf0e10cSrcweir                        'query', 'q',
64cdf0e10cSrcweir                        'task', 't',
65cdf0e10cSrcweir                        'eisclone',
66cdf0e10cSrcweir                        'setcurrent'
67cdf0e10cSrcweir                     );
68cdf0e10cSrcweir
69cdf0e10cSrcweir# list the valid options to each command
70cdf0e10cSrcweirmy %valid_options_hash = (
71cdf0e10cSrcweir                            'help'       => ['help'],
72cdf0e10cSrcweir                            'create'     => ['help', 'milestone', 'migration', 'hg'],
73cdf0e10cSrcweir                            'fetch'      => ['help', 'milestone', 'childworkspace','platforms','noautocommon',
74cdf0e10cSrcweir                                            'quiet', 'onlysolver', 'additionalrepositories'],
75cdf0e10cSrcweir                            'query'      => ['help', 'milestone','masterworkspace','childworkspace'],
76cdf0e10cSrcweir                            'task'       => ['help'],
77cdf0e10cSrcweir                            'setcurrent' => ['help', 'milestone'],
78cdf0e10cSrcweir                            'eisclone'   => ['help']
79cdf0e10cSrcweir                         );
80cdf0e10cSrcweir
81cdf0e10cSrcweirmy %valid_commands_hash;
82cdf0e10cSrcweirfor (@valid_commands) {
83cdf0e10cSrcweir    $valid_commands_hash{$_}++;
84cdf0e10cSrcweir}
85cdf0e10cSrcweir
86cdf0e10cSrcweir#  set by --debug switch
87cdf0e10cSrcweirmy $debug = 0;
88cdf0e10cSrcweir#  set by --profile switch
89cdf0e10cSrcweirmy $profile = 0;
90cdf0e10cSrcweir
91cdf0e10cSrcweir
92cdf0e10cSrcweir#### main ####
93cdf0e10cSrcweir
94cdf0e10cSrcweirmy ($command, $args_ref, $options_ref) = parse_command_line();
95cdf0e10cSrcweirdispatch_command($command, $args_ref, $options_ref);
96cdf0e10cSrcweirexit(0);
97cdf0e10cSrcweir
98cdf0e10cSrcweir#### subroutines ####
99cdf0e10cSrcweir
100cdf0e10cSrcweir# Parses the command line. does prelimiary argument and option verification
101cdf0e10cSrcweirsub parse_command_line
102cdf0e10cSrcweir{
103cdf0e10cSrcweir    if (@ARGV == 0) {
104cdf0e10cSrcweir        usage();
105cdf0e10cSrcweir        exit(1);
106cdf0e10cSrcweir    }
107cdf0e10cSrcweir
108cdf0e10cSrcweir    my %options_hash;
109cdf0e10cSrcweir    Getopt::Long::Configure ("no_auto_abbrev", "no_ignorecase");
110cdf0e10cSrcweir    my $success = GetOptions(\%options_hash, 'milestone|m=s',
111cdf0e10cSrcweir                                             'masterworkspace|master|M=s',
112cdf0e10cSrcweir                                             'hg',
113cdf0e10cSrcweir                                             'migration',
114cdf0e10cSrcweir                                             'childworkspace|child|c=s',
115cdf0e10cSrcweir                                             'debug',
116cdf0e10cSrcweir                                             'profile',
117cdf0e10cSrcweir                                             'commit|C',
118cdf0e10cSrcweir                                             'platforms|p=s',
119cdf0e10cSrcweir                                             'additionalrepositories|r=s',
120cdf0e10cSrcweir                                             'noautocommon|x=s',
121cdf0e10cSrcweir                                             'onlysolver|o',
122cdf0e10cSrcweir                                             'quiet|q',
123cdf0e10cSrcweir                                             'help|h'
124cdf0e10cSrcweir                            );
125cdf0e10cSrcweir
126cdf0e10cSrcweir    my $command = shift @ARGV;
127cdf0e10cSrcweir
128cdf0e10cSrcweir    if (!exists $valid_commands_hash{$command}) {
129cdf0e10cSrcweir        print_error("Unkown command: '$command'\n");
130cdf0e10cSrcweir        usage();
131cdf0e10cSrcweir        exit(1);
132cdf0e10cSrcweir    }
133cdf0e10cSrcweir
134cdf0e10cSrcweir    if ($command eq 'h' || $command eq '?') {
135cdf0e10cSrcweir        $command = 'help';
136cdf0e10cSrcweir    }
137cdf0e10cSrcweir    elsif ($command eq 'f') {
138cdf0e10cSrcweir        $command = 'fetch';
139cdf0e10cSrcweir    }
140cdf0e10cSrcweir    elsif ($command eq 'q') {
141cdf0e10cSrcweir        $command = 'query';
142cdf0e10cSrcweir    }
143cdf0e10cSrcweir    elsif ($command eq 't') {
144cdf0e10cSrcweir        $command = 'task';
145cdf0e10cSrcweir    }
146cdf0e10cSrcweir
147cdf0e10cSrcweir    # An unkown option might be accompanied with a valid command.
148cdf0e10cSrcweir    # Show the command specific help
149cdf0e10cSrcweir    if ( !$success ) {
150cdf0e10cSrcweir        do_help([$command])
151cdf0e10cSrcweir    }
152cdf0e10cSrcweir
153cdf0e10cSrcweir    verify_options($command, \%options_hash);
154cdf0e10cSrcweir    return ($command, \@ARGV, \%options_hash);
155cdf0e10cSrcweir}
156cdf0e10cSrcweir
157cdf0e10cSrcweir# Verify options against the valid options list.
158cdf0e10cSrcweirsub verify_options
159cdf0e10cSrcweir{
160cdf0e10cSrcweir    my $command     = shift;
161cdf0e10cSrcweir    my $options_ref = shift;
162cdf0e10cSrcweir
163cdf0e10cSrcweir    my $valid_command_options_ref = $valid_options_hash{$command};
164cdf0e10cSrcweir
165cdf0e10cSrcweir    my %valid_command_options_hash;
166cdf0e10cSrcweir    foreach (@{$valid_command_options_ref}) {
167cdf0e10cSrcweir        $valid_command_options_hash{$_}++;
168cdf0e10cSrcweir    }
169cdf0e10cSrcweir
170cdf0e10cSrcweir    # check all specified options against the valid options for the sub command
171cdf0e10cSrcweir    foreach (keys %{$options_ref}) {
172cdf0e10cSrcweir        if ( /debug/ ) {
173cdf0e10cSrcweir            $debug = 1;
174cdf0e10cSrcweir            next;
175cdf0e10cSrcweir        }
176cdf0e10cSrcweir        if ( /profile/ ) {
177cdf0e10cSrcweir            $profile = 1;
178cdf0e10cSrcweir            next;
179cdf0e10cSrcweir        }
180cdf0e10cSrcweir        if (!exists $valid_command_options_hash{$_}) {
181cdf0e10cSrcweir            print_error("can't use option '--$_' with subcommand '$command'.", 1);
182cdf0e10cSrcweir        }
183cdf0e10cSrcweir    }
184cdf0e10cSrcweir
185cdf0e10cSrcweir}
186cdf0e10cSrcweir
187cdf0e10cSrcweir# Dispatches to the do_xxx() routines depending on command.
188cdf0e10cSrcweirsub dispatch_command
189cdf0e10cSrcweir{
190cdf0e10cSrcweir    my $command     = shift;
191cdf0e10cSrcweir    my $args_ref    = shift;
192cdf0e10cSrcweir    my $options_ref = shift;
193cdf0e10cSrcweir
194cdf0e10cSrcweir    no strict 'refs';
195cdf0e10cSrcweir    &{"do_".$command}($args_ref, $options_ref);
196cdf0e10cSrcweir}
197cdf0e10cSrcweir
198cdf0e10cSrcweir# Returns the global cws object.
199cdf0e10cSrcweirBEGIN {
200cdf0e10cSrcweirmy $the_cws;
201cdf0e10cSrcweir
202cdf0e10cSrcweir    sub get_this_cws {
203cdf0e10cSrcweir        if (!defined($the_cws)) {
204cdf0e10cSrcweir            $the_cws = Cws->new();
205cdf0e10cSrcweir            return $the_cws;
206cdf0e10cSrcweir        }
207cdf0e10cSrcweir        else {
208cdf0e10cSrcweir            return $the_cws;
209cdf0e10cSrcweir        }
210cdf0e10cSrcweir    }
211cdf0e10cSrcweir}
212cdf0e10cSrcweir
213cdf0e10cSrcweir# Returns a list of the master workspaces.
214cdf0e10cSrcweirsub get_master_workspaces
215cdf0e10cSrcweir{
216cdf0e10cSrcweir    my $cws = get_this_cws();
217cdf0e10cSrcweir    my @masters = $cws->get_masters();
218cdf0e10cSrcweir
219cdf0e10cSrcweir    return wantarray ? @masters : \@masters;
220cdf0e10cSrcweir}
221cdf0e10cSrcweir
222cdf0e10cSrcweir# Checks if master argument is a valid MWS name.
223cdf0e10cSrcweirBEGIN {
224cdf0e10cSrcweir    my %master_hash;
225cdf0e10cSrcweir
226cdf0e10cSrcweir    sub is_master
227cdf0e10cSrcweir    {
228cdf0e10cSrcweir        my $master_name = shift;
229cdf0e10cSrcweir
230cdf0e10cSrcweir        if (!%master_hash) {
231cdf0e10cSrcweir            my @masters = get_master_workspaces();
232cdf0e10cSrcweir            foreach (@masters) {
233cdf0e10cSrcweir                $master_hash{$_}++;
234cdf0e10cSrcweir            }
235cdf0e10cSrcweir        }
236cdf0e10cSrcweir        return exists $master_hash{$master_name} ? 1 : 0;
237cdf0e10cSrcweir    }
238cdf0e10cSrcweir}
239cdf0e10cSrcweir
240cdf0e10cSrcweir# Fetches the current CWS from environment, returns a Cws object
241cdf0e10cSrcweirsub get_cws_from_environment
242cdf0e10cSrcweir{
243cdf0e10cSrcweir    my $child  = $ENV{CWS_WORK_STAMP};
244cdf0e10cSrcweir    my $master = $ENV{WORK_STAMP};
245cdf0e10cSrcweir
246cdf0e10cSrcweir    if ( !$child ) {
247cdf0e10cSrcweir        print_error("Environment variable CWS_WORK_STAMP is not set. Please set it to your CWS name.", 2);
248cdf0e10cSrcweir    }
249cdf0e10cSrcweir
250cdf0e10cSrcweir    if ( !$master ) {
251cdf0e10cSrcweir        print_error("Environment variable WORK_STAMP is not set. Please set it to the MWS name.", 2);
252cdf0e10cSrcweir    }
253cdf0e10cSrcweir
254cdf0e10cSrcweir    my $cws = get_this_cws();
255cdf0e10cSrcweir    $cws->child($child);
256cdf0e10cSrcweir    $cws->master($master);
257cdf0e10cSrcweir
258cdf0e10cSrcweir    # Check if we got a valid child workspace.
259cdf0e10cSrcweir    my $id = $cws->eis_id();
260cdf0e10cSrcweir    if ( $debug ) {
261cdf0e10cSrcweir        print STDERR "CWS-DEBUG: ... master: $master, child: $child, $id\n";
262cdf0e10cSrcweir    }
263cdf0e10cSrcweir    if ( !$id ) {
264cdf0e10cSrcweir        print_error("Child workspace $child for master workspace $master not found in EIS database.", 2);
265cdf0e10cSrcweir    }
266cdf0e10cSrcweir    return ($cws);
267cdf0e10cSrcweir}
268cdf0e10cSrcweir
269cdf0e10cSrcweir# Fetches the CWS by name, returns a Cws object
270cdf0e10cSrcweirsub get_cws_by_name
271cdf0e10cSrcweir{
272cdf0e10cSrcweir    my $child  = shift;
273cdf0e10cSrcweir
274cdf0e10cSrcweir    my $cws = get_this_cws();
275cdf0e10cSrcweir    $cws->child($child);
276cdf0e10cSrcweir
277cdf0e10cSrcweir    # Check if we got a valid child workspace.
278cdf0e10cSrcweir    my $id = $cws->eis_id();
279cdf0e10cSrcweir    if ( $debug ) {
280cdf0e10cSrcweir        print STDERR "CWS-DEBUG: child: $child, $id\n";
281cdf0e10cSrcweir    }
282cdf0e10cSrcweir    if ( !$id ) {
283cdf0e10cSrcweir        print_error("Child workspace $child not found in EIS database.", 2);
284cdf0e10cSrcweir    }
285cdf0e10cSrcweir
286cdf0e10cSrcweir    # Update masterws part of Cws object.
287cdf0e10cSrcweir    my $masterws = $cws->get_mws();
288cdf0e10cSrcweir    if ( $cws->master() ne $masterws ) {
289cdf0e10cSrcweir        # can this still happen?
290cdf0e10cSrcweir        if ( $debug ) {
291cdf0e10cSrcweir            print STDERR "CWS-DEBUG: get_cws_by_name(): fixup of masterws in cws object detected\n";
292cdf0e10cSrcweir        }
293cdf0e10cSrcweir        $cws->master($masterws);
294cdf0e10cSrcweir    }
295cdf0e10cSrcweir    return ($cws);
296cdf0e10cSrcweir}
297cdf0e10cSrcweir
298cdf0e10cSrcweir# Register child workspace with eis.
299cdf0e10cSrcweirsub register_child_workspace
300cdf0e10cSrcweir{
301cdf0e10cSrcweir    my $cws          = shift;
302cdf0e10cSrcweir    my $scm          = shift;
303cdf0e10cSrcweir    my $is_promotion = shift;
304cdf0e10cSrcweir
305cdf0e10cSrcweir    my $milestone = $cws->milestone();
306cdf0e10cSrcweir    my $child     = $cws->child();
307cdf0e10cSrcweir    my $master    = $cws->master();
308cdf0e10cSrcweir
309cdf0e10cSrcweir    # TODO: introduce a EIS_USER in the configuration, which should be used here
310cdf0e10cSrcweir    my $config = CwsConfig->new();
311cdf0e10cSrcweir    my $vcsid  = $config->vcsid();
312cdf0e10cSrcweir    # TODO: there is no real need for socustom anymore, should go ASAP
313cdf0e10cSrcweir    my $socustom = $config->sointernal();
314cdf0e10cSrcweir
315cdf0e10cSrcweir    if ( !$vcsid ) {
316cdf0e10cSrcweir        if ( $socustom ) {
317cdf0e10cSrcweir            print_error("Can't determine owner for CWS '$child'. Please set VCSID environment variable.", 11);
318cdf0e10cSrcweir        }
319cdf0e10cSrcweir        else {
320cdf0e10cSrcweir            print_error("Can't determine owner for CWS '$child'. Please set CVS_ID entry in \$HOME/.cwsrc.", 11);
321cdf0e10cSrcweir        }
322cdf0e10cSrcweir    }
323cdf0e10cSrcweir
324cdf0e10cSrcweir    if ( $is_promotion ) {
325cdf0e10cSrcweir        my $rc = $cws->set_scm($scm);
326cdf0e10cSrcweir        if ( !$rc ) {
327cdf0e10cSrcweir            print_error("Failed to set the SCM property '$scm' on child workspace '$child'.\nContact EIS administrator!\n", 12);
328cdf0e10cSrcweir        }
329cdf0e10cSrcweir
330cdf0e10cSrcweir        $rc = $cws->promote($vcsid, "");
331cdf0e10cSrcweir
332cdf0e10cSrcweir        if ( !$rc ) {
333cdf0e10cSrcweir            print_error("Failed to promote child workspace '$child' to status 'new'.\n", 12);
334cdf0e10cSrcweir        }
335cdf0e10cSrcweir        else {
336cdf0e10cSrcweir            print "\n***** Successfully ***** promoted child workspace '$child' to status 'new'.\n";
337cdf0e10cSrcweir            print "Milestone: '$milestone'.\n";
338cdf0e10cSrcweir        }
339cdf0e10cSrcweir    }
340cdf0e10cSrcweir    else {
341cdf0e10cSrcweir
342cdf0e10cSrcweir        my $eis_id = $cws->register($vcsid, "");
343cdf0e10cSrcweir
344cdf0e10cSrcweir        if ( !defined($eis_id) ) {
345cdf0e10cSrcweir            print_error("Failed to register child workspace '$child' for master '$master'.", 12);
346cdf0e10cSrcweir        }
347cdf0e10cSrcweir        else {
348cdf0e10cSrcweir            my $rc = $cws->set_scm($scm);
349cdf0e10cSrcweir            if ( !$rc ) {
350cdf0e10cSrcweir                print_error("Failed to set the SCM property '$scm' on child workspace '$child'.\nContact EIS administrator!\n", 12);
351cdf0e10cSrcweir            }
352cdf0e10cSrcweir            print "\n***** Successfully ***** registered child workspace '$child'\n";
353cdf0e10cSrcweir            print "for master workspace '$master' (milestone '$milestone').\n";
354cdf0e10cSrcweir            print "Child workspace Id: $eis_id.\n";
355cdf0e10cSrcweir        }
356cdf0e10cSrcweir    }
357cdf0e10cSrcweir    return 0;
358cdf0e10cSrcweir}
359cdf0e10cSrcweir
360cdf0e10cSrcweirsub print_time_elapsed
361cdf0e10cSrcweir{
362cdf0e10cSrcweir    my $t_start = shift;
363cdf0e10cSrcweir    my $t_stop  = shift;
364cdf0e10cSrcweir
365cdf0e10cSrcweir    my $time_diff = timediff($t_stop, $t_start);
366cdf0e10cSrcweir    print_message("... finished in " . timestr($time_diff));
367cdf0e10cSrcweir}
368cdf0e10cSrcweir
369cdf0e10cSrcweirsub hgrc_append_push_path_and_hooks
370cdf0e10cSrcweir{
371cdf0e10cSrcweir    my $target     = shift;
372cdf0e10cSrcweir    my $cws_source = shift;
373cdf0e10cSrcweir
374cdf0e10cSrcweir    $cws_source =~ s/http:\/\//ssh:\/\/hg@/;
375cdf0e10cSrcweir    if ( $debug ) {
376cdf0e10cSrcweir        print STDERR "CWS-DEBUG: hgrc_append_push_path_and_hooks(): default-push path: '$cws_source'\n";
377cdf0e10cSrcweir    }
378cdf0e10cSrcweir    if ( !open(HGRC, ">>$target/.hg/hgrc") ) {
379cdf0e10cSrcweir        print_error("Can't append to hgrc file of repository '$target'.\n", 88);
380cdf0e10cSrcweir    }
381cdf0e10cSrcweir    print HGRC "default-push = " . "$cws_source\n";
382cdf0e10cSrcweir    print HGRC "[extensions]\n";
383cdf0e10cSrcweir    print HGRC "hgext.win32text=\n";
384cdf0e10cSrcweir    print HGRC "[hooks]\n";
385cdf0e10cSrcweir    print HGRC "# Reject commits which would introduce windows-style CR/LF files\n";
386cdf0e10cSrcweir    print HGRC "pretxncommit.crlf = python:hgext.win32text.forbidcrlf\n";
387cdf0e10cSrcweir    close(HGRC);
388cdf0e10cSrcweir}
389cdf0e10cSrcweir
390cdf0e10cSrcweirsub hg_clone_cws_or_milestone
391cdf0e10cSrcweir{
392cdf0e10cSrcweir    my $rep_type             = shift;
393cdf0e10cSrcweir    my $cws                  = shift;
394cdf0e10cSrcweir    my $target               = shift;
395cdf0e10cSrcweir    my $clone_milestone_only = shift;
396cdf0e10cSrcweir
397cdf0e10cSrcweir    my ($hg_local_source, $hg_lan_source, $hg_remote_source);
398cdf0e10cSrcweir    my $config = CwsConfig->new();
399cdf0e10cSrcweir
400cdf0e10cSrcweir    $hg_local_source = $config->get_hg_source(uc $rep_type, 'LOCAL');
401cdf0e10cSrcweir    $hg_lan_source = $config->get_hg_source(uc $rep_type, 'LAN');
402cdf0e10cSrcweir    $hg_remote_source = $config->get_hg_source(uc $rep_type, 'REMOTE');
403cdf0e10cSrcweir
404cdf0e10cSrcweir    my $masterws = $cws->master();
405cdf0e10cSrcweir    my ($master_local_source, $master_lan_source);
406cdf0e10cSrcweir
407cdf0e10cSrcweir    $master_local_source = "$hg_local_source/" . $masterws;
408cdf0e10cSrcweir    $master_lan_source = "$hg_lan_source/" . $masterws;
409cdf0e10cSrcweir
410cdf0e10cSrcweir    my $milestone_tag;
411cdf0e10cSrcweir    if ( $clone_milestone_only ) {
412cdf0e10cSrcweir        $milestone_tag = uc($masterws) . '_' . $clone_milestone_only;
413cdf0e10cSrcweir    }
414cdf0e10cSrcweir    else {
415cdf0e10cSrcweir        my @tags = $cws->get_tags();
416cdf0e10cSrcweir        $milestone_tag = $tags[3];
417cdf0e10cSrcweir    }
418cdf0e10cSrcweir
419cdf0e10cSrcweir    if ( $debug ) {
420cdf0e10cSrcweir        print STDERR "CWS-DEBUG: master_local_source: '$master_local_source'\n";
421cdf0e10cSrcweir        print STDERR "CWS-DEBUG: master_lan_source: '$master_lan_source'\n";
422cdf0e10cSrcweir        if ( !-d $master_local_source ) {
423cdf0e10cSrcweir            print STDERR "CWS-DEBUG: not a directory '$master_local_source'\n";
424cdf0e10cSrcweir        }
425cdf0e10cSrcweir    }
426cdf0e10cSrcweir
427cdf0e10cSrcweir    my $pull_from_remote = 0;
428cdf0e10cSrcweir    my $cws_remote_source;
429cdf0e10cSrcweir    if ( !$clone_milestone_only ) {
430cdf0e10cSrcweir        if ($rep_type eq "ooo" || $rep_type eq "so")
431cdf0e10cSrcweir        {
432cdf0e10cSrcweir            $cws_remote_source = "$hg_remote_source/cws/" . $cws->child();
433cdf0e10cSrcweir        }
434cdf0e10cSrcweir        # e.g. cws_l10n
435cdf0e10cSrcweir        else
436cdf0e10cSrcweir        {
437cdf0e10cSrcweir            $cws_remote_source = "$hg_remote_source/cws_".$rep_type."/" . $cws->child();
438cdf0e10cSrcweir        }
439cdf0e10cSrcweir
440cdf0e10cSrcweir        # The outgoing repository might not yet be available. Which is not
441cdf0e10cSrcweir        # an error. Since pulling from the cws outgoing URL results in an ugly
442cdf0e10cSrcweir        # and hardly understandable error message, we check for availibility
443cdf0e10cSrcweir        # first. TODO: incorporate configured proxy instead of env_proxy. Use
444cdf0e10cSrcweir        # a dedicated request and content-type to find out if the repo is there
445cdf0e10cSrcweir        # instead of parsing the content of the page
446cdf0e10cSrcweir        print_message("... check availibility of 'outgoing' repository '$cws_remote_source'.");
447cdf0e10cSrcweir        require LWP::Simple;
448cdf0e10cSrcweir        my $content = LWP::Simple::get($cws_remote_source);
449cdf0e10cSrcweir        my $pattern = "<title>cws/". $cws->child();
450cdf0e10cSrcweir        my $pattern2 = "<title>cws_".$rep_type."/". $cws->child();
451cdf0e10cSrcweir        if ( $content && ($content =~ /$pattern/ || $content =~ /$pattern2/) ) {
452cdf0e10cSrcweir            $pull_from_remote = 1;
453cdf0e10cSrcweir        }
454cdf0e10cSrcweir        else {
455cdf0e10cSrcweir            print_message("... 'outgoing' repository '$cws_remote_source' is not accessible/available yet.");
456cdf0e10cSrcweir        }
457cdf0e10cSrcweir    }
458cdf0e10cSrcweir
459cdf0e10cSrcweir    # clone repository (without working tree if we still need to pull from remote)
460cdf0e10cSrcweir    my $clone_with_update = !$pull_from_remote;
461cdf0e10cSrcweir    hg_clone_repository($master_local_source, $master_lan_source, $target, $milestone_tag, $clone_with_update);
462cdf0e10cSrcweir
463cdf0e10cSrcweir    # now pull from the remote cws outgoing repository if its already available
464cdf0e10cSrcweir    if ( $pull_from_remote ) {
465cdf0e10cSrcweir        hg_remote_pull_repository($cws_remote_source, $target);
466cdf0e10cSrcweir    }
467cdf0e10cSrcweir
468cdf0e10cSrcweir    # if we fetched a CWS adorn the result with push-path and hooks
469cdf0e10cSrcweir    if ( $cws_remote_source ) {
470cdf0e10cSrcweir        hgrc_append_push_path_and_hooks($target, $cws_remote_source);
471cdf0e10cSrcweir    }
472cdf0e10cSrcweir
473cdf0e10cSrcweir    # update the result if necessary
474cdf0e10cSrcweir    if ( !$clone_with_update ) {
475cdf0e10cSrcweir        hg_update_repository($target);
476cdf0e10cSrcweir    }
477cdf0e10cSrcweir
478cdf0e10cSrcweir}
479cdf0e10cSrcweir
480cdf0e10cSrcweirsub hg_clone_repository
481cdf0e10cSrcweir{
482cdf0e10cSrcweir    my $local_source    = shift;
483cdf0e10cSrcweir    my $lan_source    = shift;
484cdf0e10cSrcweir    my $dest          = shift;
485cdf0e10cSrcweir    my $milestone_tag = shift;
486cdf0e10cSrcweir    my $update        = shift;
487cdf0e10cSrcweir
488cdf0e10cSrcweir    my $t1 = Benchmark->new();
489cdf0e10cSrcweir    my $source;
490cdf0e10cSrcweir    my $clone_option = $update ? '' : '-U ';
491cdf0e10cSrcweir    if ( -d $local_source && can_use_hardlinks($local_source, $dest) ) {
492cdf0e10cSrcweir        $source = $local_source;
493cdf0e10cSrcweir        if ( !hg_milestone_is_latest_in_repository($local_source, $milestone_tag) ) {
494cdf0e10cSrcweir                $clone_option .= "-r $milestone_tag";
495cdf0e10cSrcweir        }
496cdf0e10cSrcweir        print_message("... clone LOCAL repository '$local_source' to '$dest'");
497cdf0e10cSrcweir    }
498cdf0e10cSrcweir    else {
499cdf0e10cSrcweir        $source = $lan_source;
500cdf0e10cSrcweir        $clone_option .= "-r $milestone_tag";
501cdf0e10cSrcweir        print_message("... clone LAN repository '$lan_source' to '$dest'");
502cdf0e10cSrcweir    }
503cdf0e10cSrcweir    hg_clone($source, $dest, $clone_option);
504cdf0e10cSrcweir
505cdf0e10cSrcweir    my $t2 = Benchmark->new();
506cdf0e10cSrcweir    print_time_elapsed($t1, $t2) if $profile;
507cdf0e10cSrcweir}
508cdf0e10cSrcweir
509cdf0e10cSrcweirsub hg_remote_pull_repository
510cdf0e10cSrcweir{
511cdf0e10cSrcweir    my $remote_source = shift;
512cdf0e10cSrcweir    my $dest          = shift;
513cdf0e10cSrcweir
514cdf0e10cSrcweir    my $t1 = Benchmark->new();
515cdf0e10cSrcweir    print_message("... pull from REMOTE repository '$remote_source' to '$dest'");
516cdf0e10cSrcweir    hg_pull($dest, $remote_source);
517cdf0e10cSrcweir    my $t2 = Benchmark->new();
518cdf0e10cSrcweir    print_time_elapsed($t1, $t2) if $profile;
519cdf0e10cSrcweir}
520cdf0e10cSrcweir
521cdf0e10cSrcweirsub hg_update_repository
522cdf0e10cSrcweir{
523cdf0e10cSrcweir    my $dest          = shift;
524cdf0e10cSrcweir
525cdf0e10cSrcweir    my $t1 = Benchmark->new();
526cdf0e10cSrcweir    print_message("... update repository '$dest'");
527cdf0e10cSrcweir    hg_update($dest);
528cdf0e10cSrcweir    my $t2 = Benchmark->new();
529cdf0e10cSrcweir    print_time_elapsed($t1, $t2) if $profile;
530cdf0e10cSrcweir}
531cdf0e10cSrcweir
532cdf0e10cSrcweirsub hg_milestone_is_latest_in_repository
533cdf0e10cSrcweir{
534cdf0e10cSrcweir    my $repository = shift;
535cdf0e10cSrcweir    my $milestone_tag = shift;
536cdf0e10cSrcweir
537cdf0e10cSrcweir    # Our milestone is the lastest thing in the repository
538cdf0e10cSrcweir    # if the parent of the repository tip is adorned
539cdf0e10cSrcweir    # with the milestone tag.
540cdf0e10cSrcweir    my $tags_of_parent_of_tip = hg_parent($repository, 'tip', "--template='{tags}\\n'");
541cdf0e10cSrcweir    if ( $tags_of_parent_of_tip =~ /\b$milestone_tag\b/ ) {
542cdf0e10cSrcweir        return 1;
543cdf0e10cSrcweir    }
544cdf0e10cSrcweir    return 0;
545cdf0e10cSrcweir}
546cdf0e10cSrcweir
547cdf0e10cSrcweir# Check if clone source and destination are on the same filesystem,
548cdf0e10cSrcweir# in that case hg clone can employ hard links.
549cdf0e10cSrcweirsub can_use_hardlinks
550cdf0e10cSrcweir{
551cdf0e10cSrcweir    my $source = shift;
552cdf0e10cSrcweir    my $dest = shift;
553cdf0e10cSrcweir
554cdf0e10cSrcweir    if ( $^O eq 'cygwin' ) {
555cdf0e10cSrcweir        # no hard links on windows
556cdf0e10cSrcweir        return 0;
557cdf0e10cSrcweir    }
558cdf0e10cSrcweir    # st_dev is the first field return by stat()
559cdf0e10cSrcweir    my @stat_source = stat($source);
560cdf0e10cSrcweir    my @stat_dest = stat(dirname($dest));
561cdf0e10cSrcweir
562cdf0e10cSrcweir    if ( $debug ) {
563cdf0e10cSrcweir        my $source_result = defined($stat_source[0]) ? $stat_source[0] : 'stat failed';
564cdf0e10cSrcweir        my $dest_result = defined($stat_dest[0]) ? $stat_dest[0] : 'stat failed';
565cdf0e10cSrcweir        print STDERR "CWS-DEBUG: can_use_hardlinks(): source device: '$stat_source[0]', destination device: '$stat_dest[0]'\n";
566cdf0e10cSrcweir    }
567cdf0e10cSrcweir    if ( defined($stat_source[0]) && defined($stat_dest[0]) && $stat_source[0] == $stat_dest[0] ) {
568cdf0e10cSrcweir        return 1;
569cdf0e10cSrcweir    }
570cdf0e10cSrcweir    return 0;
571cdf0e10cSrcweir}
572cdf0e10cSrcweir
573cdf0e10cSrcweirsub query_cws
574cdf0e10cSrcweir{
575cdf0e10cSrcweir    my $query_mode = shift;
576cdf0e10cSrcweir    my $options_ref = shift;
577cdf0e10cSrcweir    # get master and child workspace
578cdf0e10cSrcweir    my $masterws  = exists $options_ref->{'masterworkspace'} ? uc($options_ref->{'masterworkspace'}) : $ENV{WORK_STAMP};
579cdf0e10cSrcweir    my $childws   = exists $options_ref->{'childworkspace'} ? $options_ref->{'childworkspace'} : $ENV{CWS_WORK_STAMP};
580cdf0e10cSrcweir    my $milestone = exists $options_ref->{'milestone'} ? $options_ref->{'milestone'} : 'latest';
581cdf0e10cSrcweir
582cdf0e10cSrcweir    if ( !defined($masterws) && $query_mode ne 'masters') {
583cdf0e10cSrcweir        print_error("Can't determine master workspace environment.\n", 30);
584cdf0e10cSrcweir    }
585cdf0e10cSrcweir
586cdf0e10cSrcweir    if ( ($query_mode eq 'integratedinto' || $query_mode eq 'incompatible' || $query_mode eq 'taskids' || $query_mode eq 'status' || $query_mode eq 'current' || $query_mode eq 'owner' || $query_mode eq 'qarep' || $query_mode eq 'issubversion' || $query_mode eq 'ispublic' || $query_mode eq 'build') && !defined($childws) ) {
587cdf0e10cSrcweir        print_error("Can't determine child workspace environment.\n", 30);
588cdf0e10cSrcweir    }
589cdf0e10cSrcweir
590cdf0e10cSrcweir    my $cws = Cws->new();
591cdf0e10cSrcweir    if ( defined($childws) ) {
592cdf0e10cSrcweir        $cws->child($childws);
593cdf0e10cSrcweir    }
594cdf0e10cSrcweir    if ( defined($masterws) ) {
595cdf0e10cSrcweir        $cws->master($masterws);
596cdf0e10cSrcweir    }
597cdf0e10cSrcweir
598cdf0e10cSrcweir    no strict;
599cdf0e10cSrcweir    &{"query_".$query_mode}($cws, $milestone);
600cdf0e10cSrcweir    return;
601cdf0e10cSrcweir}
602cdf0e10cSrcweir
603cdf0e10cSrcweirsub query_integratedinto
604cdf0e10cSrcweir{
605cdf0e10cSrcweir    my $cws = shift;
606cdf0e10cSrcweir
607cdf0e10cSrcweir    if ( is_valid_cws($cws) ) {
608cdf0e10cSrcweir        my $milestone = $cws->get_milestone_integrated();
609cdf0e10cSrcweir        print_message("Integrated into:");
610cdf0e10cSrcweir        print defined($milestone) ? "$milestone\n" : "unkown\n";
611cdf0e10cSrcweir    }
612cdf0e10cSrcweir    return;
613cdf0e10cSrcweir}
614cdf0e10cSrcweir
615cdf0e10cSrcweirsub query_incompatible
616cdf0e10cSrcweir{
617cdf0e10cSrcweir    my $cws = shift;
618cdf0e10cSrcweir
619cdf0e10cSrcweir    if ( is_valid_cws($cws) ) {
620cdf0e10cSrcweir        my @modules = $cws->incompatible_modules();
621cdf0e10cSrcweir        print_message("Incompatible Modules:");
622cdf0e10cSrcweir        foreach (@modules) {
623cdf0e10cSrcweir            if ( defined($_) ) {
624cdf0e10cSrcweir                print "$_\n";
625cdf0e10cSrcweir            }
626cdf0e10cSrcweir        }
627cdf0e10cSrcweir    }
628cdf0e10cSrcweir    return;
629cdf0e10cSrcweir}
630cdf0e10cSrcweir
631cdf0e10cSrcweirsub query_taskids
632cdf0e10cSrcweir{
633cdf0e10cSrcweir    my $cws = shift;
634cdf0e10cSrcweir
635cdf0e10cSrcweir    if ( is_valid_cws($cws) ) {
636cdf0e10cSrcweir        my @taskids = $cws->taskids();
637cdf0e10cSrcweir        print_message("Task ID(s):");
638cdf0e10cSrcweir        foreach (@taskids) {
639cdf0e10cSrcweir            if ( defined($_) ) {
640cdf0e10cSrcweir                print "$_\n";
641cdf0e10cSrcweir            }
642cdf0e10cSrcweir        }
643cdf0e10cSrcweir    }
644cdf0e10cSrcweir    return;
645cdf0e10cSrcweir}
646cdf0e10cSrcweir
647cdf0e10cSrcweirsub query_status
648cdf0e10cSrcweir{
649cdf0e10cSrcweir    my $cws = shift;
650cdf0e10cSrcweir
651cdf0e10cSrcweir    if ( is_valid_cws($cws) ) {
652cdf0e10cSrcweir        my $status = $cws->get_approval();
653cdf0e10cSrcweir        if ( !$status ) {
654cdf0e10cSrcweir            print_error("Internal error: can't get approval status.", 3);
655cdf0e10cSrcweir        } else {
656cdf0e10cSrcweir            print_message("Approval status:");
657cdf0e10cSrcweir            print "$status\n";
658cdf0e10cSrcweir        }
659cdf0e10cSrcweir    }
660cdf0e10cSrcweir    return;
661cdf0e10cSrcweir}
662cdf0e10cSrcweir
663cdf0e10cSrcweirsub query_scm
664cdf0e10cSrcweir{
665cdf0e10cSrcweir    my $cws = shift;
666cdf0e10cSrcweir    my $masterws = $cws->master();
667cdf0e10cSrcweir    my $childws  = $cws->child();
668cdf0e10cSrcweir
669cdf0e10cSrcweir    if ( is_valid_cws($cws) ) {
670cdf0e10cSrcweir        my $scm = $cws->get_scm();
671cdf0e10cSrcweir        if ( !defined($scm) ) {
672cdf0e10cSrcweir            print_error("Internal error: can't retrieve scm info.", 3);
673cdf0e10cSrcweir        } else {
674cdf0e10cSrcweir                print_message("Child workspace uses '$scm'.");
675cdf0e10cSrcweir        }
676cdf0e10cSrcweir    }
677cdf0e10cSrcweir    return;
678cdf0e10cSrcweir}
679cdf0e10cSrcweir
680cdf0e10cSrcweirsub query_ispublic
681cdf0e10cSrcweir{
682cdf0e10cSrcweir    my $cws = shift;
683cdf0e10cSrcweir    my $masterws = $cws->master();
684cdf0e10cSrcweir    my $childws  = $cws->child();
685cdf0e10cSrcweir
686cdf0e10cSrcweir    if ( is_valid_cws($cws) ) {
687cdf0e10cSrcweir        my $ispublic = $cws->get_public_flag();
688cdf0e10cSrcweir        if ( !defined($ispublic) ) {
689cdf0e10cSrcweir            print_error("Internal error: can't get isPublic flag.", 3);
690cdf0e10cSrcweir        } else {
691cdf0e10cSrcweir            if ( $ispublic==1 ) {
692cdf0e10cSrcweir                print_message("Child workspace is public");
693cdf0e10cSrcweir            } else {
694cdf0e10cSrcweir                print_message("Child workspace is internal");
695cdf0e10cSrcweir            }
696cdf0e10cSrcweir        }
697cdf0e10cSrcweir    }
698cdf0e10cSrcweir
699cdf0e10cSrcweir    return;
700cdf0e10cSrcweir}
701cdf0e10cSrcweir
702cdf0e10cSrcweirsub query_current
703cdf0e10cSrcweir{
704cdf0e10cSrcweir    my $cws = shift;
705cdf0e10cSrcweir
706cdf0e10cSrcweir    if ( is_valid_cws($cws) ) {
707cdf0e10cSrcweir        my $milestone = $cws->milestone();
708cdf0e10cSrcweir        if ( !$milestone ) {
709cdf0e10cSrcweir            print_error("Internal error: can't get current milestone.", 3);
710cdf0e10cSrcweir        } else {
711cdf0e10cSrcweir            print_message("Current milestone:");
712cdf0e10cSrcweir            print "$milestone\n";
713cdf0e10cSrcweir        }
714cdf0e10cSrcweir    }
715cdf0e10cSrcweir    return;
716cdf0e10cSrcweir}
717cdf0e10cSrcweir
718cdf0e10cSrcweirsub query_owner
719cdf0e10cSrcweir{
720cdf0e10cSrcweir    my $cws = shift;
721cdf0e10cSrcweir
722cdf0e10cSrcweir    if ( is_valid_cws($cws) ) {
723cdf0e10cSrcweir        my $owner = $cws->get_owner();
724cdf0e10cSrcweir        print_message("Owner:");
725cdf0e10cSrcweir        if ( !$owner ) {
726cdf0e10cSrcweir            print "not set\n" ;
727cdf0e10cSrcweir        } else {
728cdf0e10cSrcweir            print "$owner\n";
729cdf0e10cSrcweir        }
730cdf0e10cSrcweir    }
731cdf0e10cSrcweir    return;
732cdf0e10cSrcweir}
733cdf0e10cSrcweir
734cdf0e10cSrcweirsub query_qarep
735cdf0e10cSrcweir{
736cdf0e10cSrcweir    my $cws = shift;
737cdf0e10cSrcweir
738cdf0e10cSrcweir    if ( is_valid_cws($cws) ) {
739cdf0e10cSrcweir        my $qarep = $cws->get_qarep();
740cdf0e10cSrcweir        print_message("QA Representative:");
741cdf0e10cSrcweir        if ( !$qarep ) {
742cdf0e10cSrcweir            print "not set\n" ;
743cdf0e10cSrcweir        } else {
744cdf0e10cSrcweir            print "$qarep\n";
745cdf0e10cSrcweir        }
746cdf0e10cSrcweir    }
747cdf0e10cSrcweir    return;
748cdf0e10cSrcweir}
749cdf0e10cSrcweir
750cdf0e10cSrcweir
751cdf0e10cSrcweirsub query_build
752cdf0e10cSrcweir{
753cdf0e10cSrcweir    my $cws = shift;
754cdf0e10cSrcweir
755cdf0e10cSrcweir    if ( is_valid_cws($cws) ) {
756cdf0e10cSrcweir        my $build = $cws->get_build();
757cdf0e10cSrcweir        print_message("Build:");
758cdf0e10cSrcweir        if ( $build ) {
759cdf0e10cSrcweir            print "$build\n";
760cdf0e10cSrcweir        }
761cdf0e10cSrcweir    }
762cdf0e10cSrcweir    return;
763cdf0e10cSrcweir}
764cdf0e10cSrcweir
765cdf0e10cSrcweirsub query_latest
766cdf0e10cSrcweir{
767cdf0e10cSrcweir    my $cws = shift;
768cdf0e10cSrcweir
769cdf0e10cSrcweir    my $masterws = $cws->master();
770cdf0e10cSrcweir    my $latest = $cws->get_current_milestone($masterws);
771cdf0e10cSrcweir
772cdf0e10cSrcweir
773cdf0e10cSrcweir    if ( $latest ) {
774cdf0e10cSrcweir        print_message("Master workspace '$masterws':");
775cdf0e10cSrcweir        print_message("Latest milestone available for update:");
776cdf0e10cSrcweir        print "$masterws $latest\n";
777cdf0e10cSrcweir    }
778cdf0e10cSrcweir    else {
779cdf0e10cSrcweir        print_error("Can't determine latest milestone of '$masterws' available for update.", 3);
780cdf0e10cSrcweir    }
781cdf0e10cSrcweir
782cdf0e10cSrcweir    return;
783cdf0e10cSrcweir}
784cdf0e10cSrcweir
785cdf0e10cSrcweirsub query_masters
786cdf0e10cSrcweir{
787cdf0e10cSrcweir    my $cws = shift;
788cdf0e10cSrcweir
789cdf0e10cSrcweir    my @mws = $cws->get_masters();
790cdf0e10cSrcweir    my $list="";
791cdf0e10cSrcweir
792cdf0e10cSrcweir    if ( @mws ) {
793cdf0e10cSrcweir        foreach (@mws) {
794cdf0e10cSrcweir            if ( $list ne "" ) {
795cdf0e10cSrcweir                $list .= ", ";
796cdf0e10cSrcweir            }
797cdf0e10cSrcweir            $list .= $_;
798cdf0e10cSrcweir        }
799cdf0e10cSrcweir        print_message("Master workspaces available: $list");
800cdf0e10cSrcweir    }
801cdf0e10cSrcweir    else {
802cdf0e10cSrcweir        print_error("Can't determine masterworkspaces.", 3);
803cdf0e10cSrcweir    }
804cdf0e10cSrcweir
805cdf0e10cSrcweir    return;
806cdf0e10cSrcweir}
807cdf0e10cSrcweir
808cdf0e10cSrcweirsub query_milestones
809cdf0e10cSrcweir{
810cdf0e10cSrcweir    my $cws = shift;
811cdf0e10cSrcweir    my $masterws = $cws->master();
812cdf0e10cSrcweir
813cdf0e10cSrcweir    my @milestones = $cws->get_milestones($masterws);
814cdf0e10cSrcweir    my $list="";
815cdf0e10cSrcweir
816cdf0e10cSrcweir    if ( @milestones ) {
817cdf0e10cSrcweir        foreach (@milestones) {
818cdf0e10cSrcweir            if ( $list ne "" ) {
819cdf0e10cSrcweir                $list .= ", ";
820cdf0e10cSrcweir            }
821cdf0e10cSrcweir            $list .= $_;
822cdf0e10cSrcweir        }
823cdf0e10cSrcweir        print_message("Master workspace '$masterws':");
824cdf0e10cSrcweir        print_message("Milestones known on Master: $list");
825cdf0e10cSrcweir    }
826cdf0e10cSrcweir    else {
827cdf0e10cSrcweir        print_error("Can't determine milestones of '$masterws'.", 3);
828cdf0e10cSrcweir    }
829cdf0e10cSrcweir
830cdf0e10cSrcweir    return;
831cdf0e10cSrcweir}
832cdf0e10cSrcweir
833cdf0e10cSrcweirsub query_ispublicmaster
834cdf0e10cSrcweir{
835cdf0e10cSrcweir    my $cws = shift;
836cdf0e10cSrcweir    my $masterws = $cws->master();
837cdf0e10cSrcweir
838cdf0e10cSrcweir    my $ispublic = $cws->get_publicmaster_flag();
839cdf0e10cSrcweir    my $list="";
840cdf0e10cSrcweir
841cdf0e10cSrcweir    if ( defined($ispublic) ) {
842cdf0e10cSrcweir        print_message("Master workspace '$masterws':");
843cdf0e10cSrcweir        if ( !defined($ispublic) ) {
844cdf0e10cSrcweir            print_error("Internal error: can't get isPublicMaster flag.", 3);
845cdf0e10cSrcweir        } else {
846cdf0e10cSrcweir            if ( $ispublic==1 ) {
847cdf0e10cSrcweir                print_message("Master workspace is public");
848cdf0e10cSrcweir            } else {
849cdf0e10cSrcweir                print_message("Master workspace is internal");
850cdf0e10cSrcweir            }
851cdf0e10cSrcweir        }
852cdf0e10cSrcweir    }
853cdf0e10cSrcweir    else {
854cdf0e10cSrcweir        print_error("Can't determine isPublicMaster flag of '$masterws'.", 3);
855cdf0e10cSrcweir    }
856cdf0e10cSrcweir
857cdf0e10cSrcweir    return;
858cdf0e10cSrcweir}
859cdf0e10cSrcweir
860cdf0e10cSrcweirsub query_buildid
861cdf0e10cSrcweir{
862cdf0e10cSrcweir    my $cws       = shift;
863cdf0e10cSrcweir    my $milestone = shift;
864cdf0e10cSrcweir
865cdf0e10cSrcweir    my $masterws = $cws->master();
866cdf0e10cSrcweir    if ( $milestone eq 'latest' ) {
867cdf0e10cSrcweir        $milestone = $cws->get_current_milestone($masterws);
868cdf0e10cSrcweir    }
869cdf0e10cSrcweir
870cdf0e10cSrcweir    if ( !$milestone ) {
871cdf0e10cSrcweir        print_error("Can't determine latest milestone of '$masterws'.", 3);
872cdf0e10cSrcweir    }
873cdf0e10cSrcweir
874cdf0e10cSrcweir    if ( !$cws->is_milestone($masterws, $milestone) ) {
875cdf0e10cSrcweir        print_error("Milestone '$milestone' is no a valid milestone of '$masterws'.", 3);
876cdf0e10cSrcweir    }
877cdf0e10cSrcweir
878cdf0e10cSrcweir    my $buildid = $cws->get_buildid($masterws, $milestone);
879cdf0e10cSrcweir
880cdf0e10cSrcweir
881cdf0e10cSrcweir    if ( $buildid ) {
882cdf0e10cSrcweir        print_message("Master workspace '$masterws':");
883cdf0e10cSrcweir        print_message("BuildId for milestone '$milestone':");
884cdf0e10cSrcweir        print("$buildid\n");
885cdf0e10cSrcweir    }
886cdf0e10cSrcweir
887cdf0e10cSrcweir    return;
888cdf0e10cSrcweir}
889cdf0e10cSrcweir
890cdf0e10cSrcweirsub query_integrated
891cdf0e10cSrcweir{
892cdf0e10cSrcweir    my $cws       = shift;
893cdf0e10cSrcweir    my $milestone = shift;
894cdf0e10cSrcweir
895cdf0e10cSrcweir    my $masterws = $cws->master();
896cdf0e10cSrcweir    if ( $milestone eq 'latest' ) {
897cdf0e10cSrcweir        $milestone = $cws->get_current_milestone($masterws);
898cdf0e10cSrcweir    }
899cdf0e10cSrcweir
900cdf0e10cSrcweir    if ( !$milestone ) {
901cdf0e10cSrcweir        print_error("Can't determine latest milestone of '$masterws'.", 3);
902cdf0e10cSrcweir    }
903cdf0e10cSrcweir
904cdf0e10cSrcweir    if ( !$cws->is_milestone($masterws, $milestone) ) {
905cdf0e10cSrcweir        print_error("Milestone '$milestone' is no a valid milestone of '$masterws'.", 3);
906cdf0e10cSrcweir    }
907cdf0e10cSrcweir
908cdf0e10cSrcweir    my @integrated_cws = $cws->get_integrated_cws($masterws, $milestone);
909cdf0e10cSrcweir
910cdf0e10cSrcweir
911cdf0e10cSrcweir    if ( @integrated_cws ) {
912cdf0e10cSrcweir        print_message("Master workspace '$masterws':");
913cdf0e10cSrcweir        print_message("Integrated CWSs for milestone '$milestone':");
914cdf0e10cSrcweir        foreach (@integrated_cws) {
915cdf0e10cSrcweir            print "$_\n";
916cdf0e10cSrcweir        }
917cdf0e10cSrcweir    }
918cdf0e10cSrcweir
919cdf0e10cSrcweir    return;
920cdf0e10cSrcweir}
921cdf0e10cSrcweir
922cdf0e10cSrcweirsub query_approved
923cdf0e10cSrcweir{
924cdf0e10cSrcweir    my $cws       = shift;
925cdf0e10cSrcweir
926cdf0e10cSrcweir    my $masterws = $cws->master();
927cdf0e10cSrcweir
928cdf0e10cSrcweir    my @approved_cws = $cws->get_cws_with_state($masterws, 'approved by QA');
929cdf0e10cSrcweir
930cdf0e10cSrcweir    if ( @approved_cws ) {
931cdf0e10cSrcweir        print_message("Master workspace '$masterws':");
932cdf0e10cSrcweir        print_message("CWSs approved by QA:");
933cdf0e10cSrcweir        foreach (@approved_cws) {
934cdf0e10cSrcweir            print "$_\n";
935cdf0e10cSrcweir        }
936cdf0e10cSrcweir    }
937cdf0e10cSrcweir
938cdf0e10cSrcweir    return;
939cdf0e10cSrcweir}
940cdf0e10cSrcweir
941cdf0e10cSrcweirsub query_nominated
942cdf0e10cSrcweir{
943cdf0e10cSrcweir    my $cws       = shift;
944cdf0e10cSrcweir
945cdf0e10cSrcweir    my $masterws = $cws->master();
946cdf0e10cSrcweir
947cdf0e10cSrcweir    my @nominated_cws = $cws->get_cws_with_state($masterws, 'nominated');
948cdf0e10cSrcweir
949cdf0e10cSrcweir    if ( @nominated_cws ) {
950cdf0e10cSrcweir        print_message("Master workspace '$masterws':");
951cdf0e10cSrcweir        print_message("Nominated CWSs:");
952cdf0e10cSrcweir        foreach (@nominated_cws) {
953cdf0e10cSrcweir            print "$_\n";
954cdf0e10cSrcweir        }
955cdf0e10cSrcweir    }
956cdf0e10cSrcweir
957cdf0e10cSrcweir    return;
958cdf0e10cSrcweir}
959cdf0e10cSrcweir
960cdf0e10cSrcweirsub query_ready
961cdf0e10cSrcweir{
962cdf0e10cSrcweir    my $cws       = shift;
963cdf0e10cSrcweir
964cdf0e10cSrcweir    my $masterws = $cws->master();
965cdf0e10cSrcweir
966cdf0e10cSrcweir    my @ready_cws = $cws->get_cws_with_state($masterws, 'ready for QA');
967cdf0e10cSrcweir
968cdf0e10cSrcweir    if ( @ready_cws ) {
969cdf0e10cSrcweir        print_message("Master workspace '$masterws':");
970cdf0e10cSrcweir        print_message("CWSs ready for QA:");
971cdf0e10cSrcweir        foreach (@ready_cws) {
972cdf0e10cSrcweir            print "$_\n";
973cdf0e10cSrcweir        }
974cdf0e10cSrcweir    }
975cdf0e10cSrcweir
976cdf0e10cSrcweir    return;
977cdf0e10cSrcweir}
978cdf0e10cSrcweir
979cdf0e10cSrcweirsub query_new
980cdf0e10cSrcweir{
981cdf0e10cSrcweir    my $cws       = shift;
982cdf0e10cSrcweir
983cdf0e10cSrcweir    my $masterws = $cws->master();
984cdf0e10cSrcweir
985cdf0e10cSrcweir    my @ready_cws = $cws->get_cws_with_state($masterws, 'new');
986cdf0e10cSrcweir
987cdf0e10cSrcweir    if ( @ready_cws ) {
988cdf0e10cSrcweir        print_message("Master workspace '$masterws':");
989cdf0e10cSrcweir        print_message("CWSs with state 'new':");
990cdf0e10cSrcweir        foreach (@ready_cws) {
991cdf0e10cSrcweir            print "$_\n";
992cdf0e10cSrcweir        }
993cdf0e10cSrcweir    }
994cdf0e10cSrcweir
995cdf0e10cSrcweir    return;
996cdf0e10cSrcweir}
997cdf0e10cSrcweir
998cdf0e10cSrcweirsub query_planned
999cdf0e10cSrcweir{
1000cdf0e10cSrcweir    my $cws       = shift;
1001cdf0e10cSrcweir
1002cdf0e10cSrcweir    my $masterws = $cws->master();
1003cdf0e10cSrcweir
1004cdf0e10cSrcweir    my @ready_cws = $cws->get_cws_with_state($masterws, 'planned');
1005cdf0e10cSrcweir
1006cdf0e10cSrcweir    if ( @ready_cws ) {
1007cdf0e10cSrcweir        print_message("Master workspace '$masterws':");
1008cdf0e10cSrcweir        print_message("CWSs with state 'planned':");
1009cdf0e10cSrcweir        foreach (@ready_cws) {
1010cdf0e10cSrcweir            print "$_\n";
1011cdf0e10cSrcweir        }
1012cdf0e10cSrcweir    }
1013cdf0e10cSrcweir
1014cdf0e10cSrcweir    return;
1015cdf0e10cSrcweir}
1016cdf0e10cSrcweir
1017cdf0e10cSrcweirsub is_valid_cws
1018cdf0e10cSrcweir{
1019cdf0e10cSrcweir    my $cws = shift;
1020cdf0e10cSrcweir
1021cdf0e10cSrcweir    my $masterws = $cws->master();
1022cdf0e10cSrcweir    my $childws  = $cws->child();
1023cdf0e10cSrcweir    # check if we got a valid child workspace
1024cdf0e10cSrcweir    my $id = $cws->eis_id();
1025cdf0e10cSrcweir    if ( !$id ) {
1026cdf0e10cSrcweir        print_error("Child workspace '$childws' for master workspace '$masterws' not found in EIS database.", 2);
1027cdf0e10cSrcweir    }
1028cdf0e10cSrcweir    print STDERR "Master workspace '$masterws', child workspace '$childws'\n";
1029cdf0e10cSrcweir    return 1;
1030cdf0e10cSrcweir}
1031cdf0e10cSrcweir
1032cdf0e10cSrcweirsub query_release
1033cdf0e10cSrcweir{
1034cdf0e10cSrcweir    my $cws = shift;
1035cdf0e10cSrcweir
1036cdf0e10cSrcweir    if ( is_valid_cws($cws) ) {
1037cdf0e10cSrcweir        my $release = $cws->get_release();
1038cdf0e10cSrcweir            print_message("Release target:");
1039cdf0e10cSrcweir        if ( !$release ) {
1040cdf0e10cSrcweir            print "not set\n";
1041cdf0e10cSrcweir        } else {
1042cdf0e10cSrcweir            print "$release\n";
1043cdf0e10cSrcweir        }
1044cdf0e10cSrcweir    }
1045cdf0e10cSrcweir    return;
1046cdf0e10cSrcweir}
1047cdf0e10cSrcweir
1048cdf0e10cSrcweirsub query_due
1049cdf0e10cSrcweir{
1050cdf0e10cSrcweir    my $cws = shift;
1051cdf0e10cSrcweir
1052cdf0e10cSrcweir    if ( is_valid_cws($cws) ) {
1053cdf0e10cSrcweir        my $due = $cws->get_due_date();
1054cdf0e10cSrcweir            print_message("Due date:");
1055cdf0e10cSrcweir        if ( !$due ) {
1056cdf0e10cSrcweir            print "not set\n";
1057cdf0e10cSrcweir        } else {
1058cdf0e10cSrcweir            print "$due\n";
1059cdf0e10cSrcweir        }
1060cdf0e10cSrcweir    }
1061cdf0e10cSrcweir    return;
1062cdf0e10cSrcweir}
1063cdf0e10cSrcweir
1064cdf0e10cSrcweirsub query_due_qa
1065cdf0e10cSrcweir{
1066cdf0e10cSrcweir    my $cws = shift;
1067cdf0e10cSrcweir
1068cdf0e10cSrcweir    if ( is_valid_cws($cws) ) {
1069cdf0e10cSrcweir        my $due_qa = $cws->get_due_date_qa();
1070cdf0e10cSrcweir            print_message("Due date (QA):");
1071cdf0e10cSrcweir        if ( !$due_qa ) {
1072cdf0e10cSrcweir            print "not set\n";
1073cdf0e10cSrcweir        } else {
1074cdf0e10cSrcweir            print "$due_qa\n";
1075cdf0e10cSrcweir        }
1076cdf0e10cSrcweir    }
1077cdf0e10cSrcweir    return;
1078cdf0e10cSrcweir}
1079cdf0e10cSrcweir
1080cdf0e10cSrcweirsub query_help
1081cdf0e10cSrcweir{
1082cdf0e10cSrcweir    my $cws = shift;
1083cdf0e10cSrcweir
1084cdf0e10cSrcweir    if ( is_valid_cws($cws) ) {
1085cdf0e10cSrcweir        my $help = $cws->is_helprelevant();
1086cdf0e10cSrcweir            print_message("Help relevant:");
1087cdf0e10cSrcweir        if ( !$help ) {
1088cdf0e10cSrcweir            print "false\n";
1089cdf0e10cSrcweir        } else {
1090cdf0e10cSrcweir            print "true\n";
1091cdf0e10cSrcweir        }
1092cdf0e10cSrcweir    }
1093cdf0e10cSrcweir    return;
1094cdf0e10cSrcweir}
1095cdf0e10cSrcweir
1096cdf0e10cSrcweirsub query_ui
1097cdf0e10cSrcweir{
1098cdf0e10cSrcweir    my $cws = shift;
1099cdf0e10cSrcweir
1100cdf0e10cSrcweir    if ( is_valid_cws($cws) ) {
1101cdf0e10cSrcweir        my $help = $cws->is_uirelevant();
1102cdf0e10cSrcweir            print_message("UI relevant:");
1103cdf0e10cSrcweir        if ( !$help ) {
1104cdf0e10cSrcweir            print "false\n";
1105cdf0e10cSrcweir        } else {
1106cdf0e10cSrcweir            print "true\n";
1107cdf0e10cSrcweir        }
1108cdf0e10cSrcweir    }
1109cdf0e10cSrcweir    return;
1110cdf0e10cSrcweir}
1111cdf0e10cSrcweir
1112cdf0e10cSrcweirsub verify_milestone
1113cdf0e10cSrcweir{
1114cdf0e10cSrcweir    my $cws = shift;
1115cdf0e10cSrcweir    my $qualified_milestone = shift;
1116cdf0e10cSrcweir
1117cdf0e10cSrcweir    my $invalid = 0;
1118cdf0e10cSrcweir    my ($master, $milestone);
1119cdf0e10cSrcweir    $invalid++ if $qualified_milestone =~ /-/;
1120cdf0e10cSrcweir
1121cdf0e10cSrcweir    if ( $qualified_milestone =~ /:/ ) {
1122cdf0e10cSrcweir        ($master, $milestone) = split(/:/, $qualified_milestone);
1123cdf0e10cSrcweir        $invalid++ unless ( $master && $milestone );
1124cdf0e10cSrcweir    }
1125cdf0e10cSrcweir    else {
1126cdf0e10cSrcweir        $milestone = $qualified_milestone;
1127cdf0e10cSrcweir    }
1128cdf0e10cSrcweir
1129cdf0e10cSrcweir    if ( $invalid ) {
1130cdf0e10cSrcweir        print_error("Invalid milestone", 0);
1131cdf0e10cSrcweir        usage();
1132cdf0e10cSrcweir        exit(1);
1133cdf0e10cSrcweir    }
1134cdf0e10cSrcweir
1135cdf0e10cSrcweir    $master = $cws->master() if !$master;
1136cdf0e10cSrcweir    if ( !$cws->is_milestone($master, $milestone) ) {
1137cdf0e10cSrcweir        print_error("Milestone '$milestone' is not registered with master workspace '$master'.", 21);
1138cdf0e10cSrcweir    }
1139cdf0e10cSrcweir    return ($master, $milestone);
1140cdf0e10cSrcweir}
1141cdf0e10cSrcweir
1142cdf0e10cSrcweirsub relink_workspace {
1143cdf0e10cSrcweir    my $linkdir = shift;
1144cdf0e10cSrcweir    my $restore = shift;
1145cdf0e10cSrcweir
1146cdf0e10cSrcweir    # The list of obligatorily added modules, build will not work
1147cdf0e10cSrcweir    # if these are not present.
1148cdf0e10cSrcweir    my %added_modules_hash;
1149cdf0e10cSrcweir    if (defined $ENV{ADDED_MODULES}) {
1150cdf0e10cSrcweir        for ( split(/\s/, $ENV{ADDED_MODULES}) ) {
1151cdf0e10cSrcweir            $added_modules_hash{$_}++;
1152cdf0e10cSrcweir        }
1153cdf0e10cSrcweir    }
1154cdf0e10cSrcweir
1155cdf0e10cSrcweir    # clean out pre-existing linkdir
1156cdf0e10cSrcweir    my $bd = dirname($linkdir);
1157cdf0e10cSrcweir    if ( !opendir(DIR, $bd) ) {
1158cdf0e10cSrcweir        print_error("Can't open directory '$bd': $!.", 44);
1159cdf0e10cSrcweir    }
1160cdf0e10cSrcweir    my @old_link_dirs = grep { /^src.m\d+/ } readdir(DIR);
1161cdf0e10cSrcweir    close(DIR);
1162cdf0e10cSrcweir
1163cdf0e10cSrcweir    if ( @old_link_dirs > 1 ) {
1164cdf0e10cSrcweir        print_error("Found more than one old link directories:", 0);
1165cdf0e10cSrcweir        foreach (@old_link_dirs) {
1166cdf0e10cSrcweir            print STDERR "@old_link_dirs\n";
1167cdf0e10cSrcweir        }
1168cdf0e10cSrcweir        if ( $restore ) {
1169cdf0e10cSrcweir            print_error("Please remove all old link directories but the last one", 67);
1170cdf0e10cSrcweir        }
1171cdf0e10cSrcweir    }
1172cdf0e10cSrcweir
1173cdf0e10cSrcweir    # Originally the extension .lnk indicated a linked module. This turned out to be
1174cdf0e10cSrcweir    # not an overly smart choice. Cygwin has some heuristics which regards .lnk
1175cdf0e10cSrcweir    # files as Windows shortcuts, breaking the build. Use .link instead.
1176cdf0e10cSrcweir    # When in restoring mode still consider .lnk as link to modules (for old CWSs)
1177cdf0e10cSrcweir    my $old_link_dir = "$bd/" . $old_link_dirs[0];
1178cdf0e10cSrcweir    if ( $restore ) {
1179cdf0e10cSrcweir        if ( !opendir(DIR, $old_link_dir) ) {
1180cdf0e10cSrcweir            print_error("Can't open directory '$old_link_dir': $!.", 44);
1181cdf0e10cSrcweir        }
1182cdf0e10cSrcweir        my @links = grep { !(/\.lnk/ || /\.link/)   } readdir(DIR);
1183cdf0e10cSrcweir        close(DIR);
1184cdf0e10cSrcweir        # everything which is not a link to a directory can't be an "added" module
1185cdf0e10cSrcweir        foreach (@links) {
1186cdf0e10cSrcweir            next if /^\./;
1187cdf0e10cSrcweir            my $link = "$old_link_dir/$_";
1188cdf0e10cSrcweir            if ( -s $link && -d $link ) {
1189cdf0e10cSrcweir                $added_modules_hash{$_} = 1;
1190cdf0e10cSrcweir            }
1191cdf0e10cSrcweir        }
1192cdf0e10cSrcweir    }
1193cdf0e10cSrcweir    print_message("... removing '$old_link_dir'");
1194cdf0e10cSrcweir    rmtree([$old_link_dir], 0);
1195cdf0e10cSrcweir
1196cdf0e10cSrcweir    print_message("... (re)create '$linkdir'");
1197cdf0e10cSrcweir    if ( !mkdir("$linkdir") ) {
1198cdf0e10cSrcweir        print_error("Can't create directory '$linkdir': $!.", 44);
1199cdf0e10cSrcweir    }
1200cdf0e10cSrcweir    if ( !opendir(DIR, "$bd/ooo") ) {
1201cdf0e10cSrcweir        print_error("Can't open directory '$bd/sun': $!.", 44);
1202cdf0e10cSrcweir    }
1203cdf0e10cSrcweir    my @ooo_top_level_dirs = grep { !/^\./ } readdir(DIR);
1204cdf0e10cSrcweir    close(DIR);
1205cdf0e10cSrcweir    if ( !opendir(DIR, "$bd/sun") ) {
1206cdf0e10cSrcweir        print_error("Can't open directory '$bd/sun': $!.", 44);
1207cdf0e10cSrcweir    }
1208cdf0e10cSrcweir    my @so_top_level_dirs = grep { !/^\./ } readdir(DIR);
1209cdf0e10cSrcweir    close(DIR);
1210cdf0e10cSrcweir    my $savedir = getcwd();
1211cdf0e10cSrcweir    if ( !chdir($linkdir) ) {
1212cdf0e10cSrcweir        print_error("Can't chdir() to directory '$linkdir': $!.", 44);
1213cdf0e10cSrcweir    }
1214cdf0e10cSrcweir    my $suffix = '.link';
1215cdf0e10cSrcweir    foreach(@ooo_top_level_dirs) {
1216cdf0e10cSrcweir        if ( $_ eq 'REBASE.LOG' || $_ eq 'REBASE.CONFIG_DONT_DELETE'  ) {
1217cdf0e10cSrcweir            next;
1218cdf0e10cSrcweir        }
1219cdf0e10cSrcweir        my $target = $_;
1220cdf0e10cSrcweir        if ( -d "../ooo/$_" && !exists $added_modules_hash{$_} ) {
1221cdf0e10cSrcweir            $target .= $suffix;
1222cdf0e10cSrcweir        }
1223cdf0e10cSrcweir        if ( !symlink("../ooo/$_", $target) ) {
1224cdf0e10cSrcweir            print_error("Can't symlink directory '../ooo/$_ -> $target': $!.", 44);
1225cdf0e10cSrcweir        }
1226cdf0e10cSrcweir    }
1227cdf0e10cSrcweir    foreach(@so_top_level_dirs) {
1228cdf0e10cSrcweir        if ( $_ eq 'REBASE.LOG' || $_ eq 'REBASE.CONFIG_DONT_DELETE'  ) {
1229cdf0e10cSrcweir            next;
1230cdf0e10cSrcweir        }
1231cdf0e10cSrcweir        my $target = $_;
1232cdf0e10cSrcweir        if ( -d "../sun/$_" && !exists $added_modules_hash{$_} ) {
1233cdf0e10cSrcweir            $target .= $suffix;
1234cdf0e10cSrcweir        }
1235cdf0e10cSrcweir        if ( !symlink("../sun/$_", $target) ) {
1236cdf0e10cSrcweir            print_error("Can't symlink directory '../sun/$_ -> $target': $!.", 44);
1237cdf0e10cSrcweir        }
1238cdf0e10cSrcweir    }
1239cdf0e10cSrcweir    if ( !chdir($savedir) ) {
1240cdf0e10cSrcweir        print_error("Can't chdir() to directory '$linkdir': $!.", 44);
1241cdf0e10cSrcweir    }
1242cdf0e10cSrcweir}
1243cdf0e10cSrcweir
1244cdf0e10cSrcweirsub fetch_external_tarballs
1245cdf0e10cSrcweir{
1246cdf0e10cSrcweir    my $source_root_dir = shift;
1247cdf0e10cSrcweir    my $external_tarballs_source = shift;
1248cdf0e10cSrcweir
1249cdf0e10cSrcweir    my $ooo_external_file = "$source_root_dir/ooo/ooo.lst";
1250cdf0e10cSrcweir    my $sun_external_file = "$source_root_dir/sun/sun.lst";
1251cdf0e10cSrcweir    my $sun_path          = "$source_root_dir/sun";
1252cdf0e10cSrcweir
1253cdf0e10cSrcweir    my @external_sources_list;
1254cdf0e10cSrcweir    push(@external_sources_list, read_external_file($ooo_external_file));
1255cdf0e10cSrcweir    if ( -d $sun_path ) {
1256cdf0e10cSrcweir        if ( -e $sun_external_file ) {
1257cdf0e10cSrcweir            push(@external_sources_list, read_external_file($sun_external_file));
1258cdf0e10cSrcweir        }
1259cdf0e10cSrcweir        else {
1260cdf0e10cSrcweir            print_error("Can't find external file list '$sun_external_file'.", 8);
1261cdf0e10cSrcweir        }
1262cdf0e10cSrcweir    }
1263cdf0e10cSrcweir
1264cdf0e10cSrcweir    my $ext_sources_dir = "$source_root_dir/ext_sources";
1265cdf0e10cSrcweir    print_message("Copy external tarballs to '$ext_sources_dir'");
1266cdf0e10cSrcweir    if ( ! -d $ext_sources_dir) {
1267cdf0e10cSrcweir        if ( !mkdir($ext_sources_dir) ) {
1268cdf0e10cSrcweir            print_error("Can't create directory '$ext_sources_dir': $!.", 44);
1269cdf0e10cSrcweir        }
1270cdf0e10cSrcweir    }
1271cdf0e10cSrcweir    foreach (@external_sources_list) {
1272cdf0e10cSrcweir        if ( ! copy("$external_tarballs_source/$_", $ext_sources_dir) ) {
1273cdf0e10cSrcweir            print_error("Can't copy file '$external_tarballs_source' -> '$ext_sources_dir': $!", 0);
1274cdf0e10cSrcweir        }
1275cdf0e10cSrcweir    }
1276cdf0e10cSrcweir    return;
1277cdf0e10cSrcweir}
1278cdf0e10cSrcweir
1279cdf0e10cSrcweirsub read_external_file
1280cdf0e10cSrcweir{
1281cdf0e10cSrcweir    my $external_file = shift;
1282cdf0e10cSrcweir
1283cdf0e10cSrcweir    my @external_sources;
1284cdf0e10cSrcweir    open(EXT, "<$external_file") or print_error("Can't open file '$external_file' for reading: $!", 98);
1285cdf0e10cSrcweir    while(<EXT>) {
1286cdf0e10cSrcweir        if ( !/^http:/ ) {
1287cdf0e10cSrcweir            chomp;
1288cdf0e10cSrcweir            push(@external_sources, $_);
1289cdf0e10cSrcweir        }
1290cdf0e10cSrcweir    }
1291cdf0e10cSrcweir    close(EXT);
1292cdf0e10cSrcweir    return @external_sources;
1293cdf0e10cSrcweir}
1294cdf0e10cSrcweir
1295cdf0e10cSrcweirsub update_solver
1296cdf0e10cSrcweir{
1297cdf0e10cSrcweir    my $platform      = shift;
1298cdf0e10cSrcweir    my $source        = shift;
1299cdf0e10cSrcweir    my $solver        = shift;
1300cdf0e10cSrcweir    my $milestone     = shift;
1301cdf0e10cSrcweir    my $source_config = shift;
1302cdf0e10cSrcweir
1303cdf0e10cSrcweir    my @zip_sub_dirs = ('bin', 'doc', 'idl', 'inc', 'lib', 'par', 'pck', 'pdb', 'pus', 'rdb', 'res', 'xml', 'sdf');
1304cdf0e10cSrcweir
1305cdf0e10cSrcweir    use Archive::Zip qw( :ERROR_CODES :CONSTANTS );
1306cdf0e10cSrcweir
1307cdf0e10cSrcweir    my $platform_solver = "$solver/$platform";
1308cdf0e10cSrcweir
1309cdf0e10cSrcweir    if ( -d $platform_solver ) {
1310cdf0e10cSrcweir        print_message("... removing old solver for platform '$platform'");
1311cdf0e10cSrcweir        if ( !rmtree([$platform_solver]) ) {
1312cdf0e10cSrcweir            print_error("Can't remove directory '$platform_solver': $!.", 44);
1313cdf0e10cSrcweir        }
1314cdf0e10cSrcweir    }
1315cdf0e10cSrcweir
1316cdf0e10cSrcweir    if ( !mkdir("$platform_solver") ) {
1317cdf0e10cSrcweir        print_error("Can't create directory '$platform_solver': $!.", 44);
1318cdf0e10cSrcweir    }
1319cdf0e10cSrcweir
1320cdf0e10cSrcweir    my $platform_source = "$source/$platform/zip.$milestone";
1321cdf0e10cSrcweir    if ( !opendir(DIR, "$platform_source") ) {
1322cdf0e10cSrcweir        print_error("Can't open directory '$platform_source': $!.", 44);
1323cdf0e10cSrcweir    }
1324cdf0e10cSrcweir    my @zips = grep { /\.zip$/ } readdir(DIR);
1325cdf0e10cSrcweir    close(DIR);
1326cdf0e10cSrcweir
1327cdf0e10cSrcweir    my $nzips = @zips;
1328cdf0e10cSrcweir    print_message("... unzipping $nzips zip archives for platform '$platform'");
1329cdf0e10cSrcweir
1330cdf0e10cSrcweir
1331cdf0e10cSrcweir    foreach(@zips) {
1332cdf0e10cSrcweir        my $zip = Archive::Zip->new();
1333cdf0e10cSrcweir        unless ( $zip->read( "$platform_source/$_" ) == AZ_OK ) {
1334cdf0e10cSrcweir            print_error("Can't read zip file '$platform_source/$_': $!.", 44);
1335cdf0e10cSrcweir        }
1336cdf0e10cSrcweir        # TODO: check for erorrs
1337cdf0e10cSrcweir        foreach (@zip_sub_dirs) {
1338cdf0e10cSrcweir            my $extract_destination = $source_config ? "$platform_solver/$_" : "$platform_solver/$_.$milestone";
1339cdf0e10cSrcweir            unless ( $zip->extractTree($_, $extract_destination) == AZ_OK ) {
1340cdf0e10cSrcweir                print_error("Can't extract stream from zip file '$platform_source/$_': $!.", 44);
1341cdf0e10cSrcweir            }
1342cdf0e10cSrcweir        }
1343cdf0e10cSrcweir     }
1344cdf0e10cSrcweir}
1345cdf0e10cSrcweir
1346cdf0e10cSrcweir# TODO: special provisions for "source_config" migration, remove this
1347cdf0e10cSrcweir# some time after migration
1348cdf0e10cSrcweirsub get_source_config_for_milestone
1349cdf0e10cSrcweir{
1350cdf0e10cSrcweir    my $masterws = shift;
1351cdf0e10cSrcweir    my $milestone = shift;
1352cdf0e10cSrcweir
1353cdf0e10cSrcweir    my $milestone_sequence_number = extract_milestone_sequence_number($milestone);
1354cdf0e10cSrcweir    my $ooo320_migration_sequence_number = extract_milestone_sequence_number($ooo320_source_config_milestone);
1355cdf0e10cSrcweir
1356cdf0e10cSrcweir    my $source_config = 1;
1357cdf0e10cSrcweir    if ( $masterws eq 'OOO320' ) {
1358cdf0e10cSrcweir        if ( $milestone_sequence_number < $ooo320_migration_sequence_number ) {
1359cdf0e10cSrcweir            $source_config = 0;
1360cdf0e10cSrcweir        }
1361cdf0e10cSrcweir    }
1362cdf0e10cSrcweir    return $source_config;
1363cdf0e10cSrcweir}
1364cdf0e10cSrcweir
1365cdf0e10cSrcweirsub extract_milestone_sequence_number
1366cdf0e10cSrcweir{
1367cdf0e10cSrcweir    my $milestone = shift;
1368cdf0e10cSrcweir
1369cdf0e10cSrcweir    my $milestone_sequence_number;
1370cdf0e10cSrcweir    if ( $milestone =~ /m(\d+)/ ) {
1371cdf0e10cSrcweir        $milestone_sequence_number = $1;
1372cdf0e10cSrcweir    }
1373cdf0e10cSrcweir    else {
1374cdf0e10cSrcweir        print_error("can't extract milestone sequence number from milestone '$milestone'", 99);
1375cdf0e10cSrcweir    }
1376cdf0e10cSrcweir    return $milestone_sequence_number;
1377cdf0e10cSrcweir}
1378cdf0e10cSrcweir
1379cdf0e10cSrcweir# Executes the help command.
1380cdf0e10cSrcweirsub do_help
1381cdf0e10cSrcweir{
1382cdf0e10cSrcweir    my $args_ref    = shift;
1383cdf0e10cSrcweir    my $options_ref = shift;
1384cdf0e10cSrcweir
1385cdf0e10cSrcweir    if (@{$args_ref} == 0) {
1386cdf0e10cSrcweir        print STDERR "usage: cws <subcommand> [options] [args]\n";
1387cdf0e10cSrcweir        print STDERR "Type 'cws help <subcommand>' for help on a specific subcommand.\n";
1388cdf0e10cSrcweir        print STDERR "\n";
1389cdf0e10cSrcweir        print STDERR "Available subcommands:\n";
1390cdf0e10cSrcweir        print STDERR "\thelp (h,?)\n";
1391cdf0e10cSrcweir        print STDERR "\tcreate\n";
1392cdf0e10cSrcweir        print STDERR "\tfetch (f)\n";
1393cdf0e10cSrcweir        print STDERR "\tquery (q)\n";
1394cdf0e10cSrcweir        print STDERR "\ttask (t)\n";
1395cdf0e10cSrcweir        print STDERR "\tsetcurrent\n";
1396cdf0e10cSrcweir        print STDERR "\teisclone *** release engineers only ***\n";
1397cdf0e10cSrcweir    }
1398cdf0e10cSrcweir
1399cdf0e10cSrcweir    my $arg = $args_ref->[0];
1400cdf0e10cSrcweir
1401cdf0e10cSrcweir    if (!defined($arg) || $arg eq 'help') {
1402cdf0e10cSrcweir        print STDERR "help (h, ?): Describe the usage of this script or its subcommands\n";
1403cdf0e10cSrcweir        print STDERR "usage: help [subcommand]\n";
1404cdf0e10cSrcweir    }
1405cdf0e10cSrcweir    elsif ($arg eq 'create') {
1406cdf0e10cSrcweir        print STDERR "create: Create a new child workspace\n";
1407cdf0e10cSrcweir        print STDERR "usage: create [-m milestone] <master workspace> <child workspace>\n";
1408cdf0e10cSrcweir        print STDERR "\t-m milestone:          Milestone to base the child workspace on. If ommitted the\n";
1409cdf0e10cSrcweir        print STDERR "\t                       last published milestone will be used.\n";
1410cdf0e10cSrcweir        print STDERR "\t--milestone milestone: Same as -m milestone.\n";
1411cdf0e10cSrcweir    }
1412cdf0e10cSrcweir    elsif ($arg eq 'task') {
1413cdf0e10cSrcweir        print STDERR "task: Add a task to a child workspace\n";
1414cdf0e10cSrcweir        print STDERR "usage: task <task id> [task id ...]\n";
1415cdf0e10cSrcweir    }
1416cdf0e10cSrcweir    elsif ($arg eq 'query') {
1417cdf0e10cSrcweir        print STDERR "query: Query child workspace for miscellaneous information\n";
1418cdf0e10cSrcweir        print STDERR "usage: query [-M master] [-c child] <current|integratedinto|incompatible|owner|qarep|status|taskids>\n";
1419cdf0e10cSrcweir        print STDERR "       query [-M master] [-c child] <release|due|due_qa|help|ui|ispublic|scm|build>\n";
1420cdf0e10cSrcweir        print STDERR "       query [-M master] <latest|milestones|ispublicmaster>\n";
1421cdf0e10cSrcweir        print STDERR "       query  <masters>\n";
1422cdf0e10cSrcweir        print STDERR "       query [-M master] [-m milestone] <integrated|buildid>\n";
1423cdf0e10cSrcweir        print STDERR "       query [-M master] <planned|new|approved|nominated|ready>\n";
1424cdf0e10cSrcweir        print STDERR "\t-M master:\t\toverride MWS specified in environment\n";
1425cdf0e10cSrcweir        print STDERR "\t-c child:\t\toverride CWS specified in environment\n";
1426cdf0e10cSrcweir        print STDERR "\t-m milestone:\t\toverride latest milestone with specified one\n";
1427cdf0e10cSrcweir        print STDERR "\t--master master:\tSame as -M master\t\n";
1428cdf0e10cSrcweir        print STDERR "\t--child child:\t\tSame -c child\n";
1429cdf0e10cSrcweir        print STDERR "\t--milestone milestone:\tSame as -m milestone\n";
1430cdf0e10cSrcweir        print STDERR "Modes:\n";
1431cdf0e10cSrcweir        print STDERR "\tcurrent\t\tquery current milestone of CWS\n";
1432cdf0e10cSrcweir        print STDERR "\tincompatible\tquery modules which should be build incompatible\n";
1433cdf0e10cSrcweir        print STDERR "\towner\t\tquery CWS owner\n";
1434cdf0e10cSrcweir        print STDERR "\tqarep\t\tquery CWS QA Representative\n";
1435cdf0e10cSrcweir        print STDERR "\tstatus\t\tquery approval status of CWS\n";
1436cdf0e10cSrcweir        print STDERR "\ttaskids\t\tquery taskids to be handled on the CWS\n";
1437cdf0e10cSrcweir        print STDERR "\trelease\t\tquery for target release of CWS\n";
1438cdf0e10cSrcweir        print STDERR "\tdue\t\tquery for due date of CWS\n";
1439cdf0e10cSrcweir        print STDERR "\tdue_qa\t\tquery for due date (QA) of CWS\n";
1440cdf0e10cSrcweir        print STDERR "\thelp\t\tquery if the CWS is help relevant\n";
1441cdf0e10cSrcweir        print STDERR "\tui\t\tquery if the CWS is UI relevant\n";
1442cdf0e10cSrcweir        print STDERR "\tbuild\t\tquery build String for CWS\n";
1443cdf0e10cSrcweir        print STDERR "\tlatest\t\tquery the latest milestone available for resync\n";
1444cdf0e10cSrcweir        print STDERR "\tbuildid\t\tquery build ID for milestone\n";
1445cdf0e10cSrcweir        print STDERR "\tintegrated\tquery integrated CWSs for milestone\n";
1446cdf0e10cSrcweir        print STDERR "\tintegratedinto\tquery milestone which CWS was integrated into\n";
1447cdf0e10cSrcweir        print STDERR "\tplanned\t\tquery for planned CWSs\n";
1448cdf0e10cSrcweir        print STDERR "\tnew\t\tquery for new CWSs\n";
1449cdf0e10cSrcweir        print STDERR "\tapproved\tquery CWSs approved by QA\n";
1450cdf0e10cSrcweir        print STDERR "\tnominated\tquery nominated CWSs\n";
1451cdf0e10cSrcweir        print STDERR "\tready\t\tquery CWSs ready for QA\n";
1452cdf0e10cSrcweir        print STDERR "\tispublic\tquery public flag of CWS\n";
1453cdf0e10cSrcweir        print STDERR "\tscm\t\tquery Source Control Management (SCM) system used for CWS\n";
1454cdf0e10cSrcweir        print STDERR "\tmasters\t\tquery available MWS\n";
1455cdf0e10cSrcweir        print STDERR "\tmilestones\tquery which milestones are know on the given MWS\n";
1456cdf0e10cSrcweir        print STDERR "\tispublicmaster\tquery public flag of MWS\n";
1457cdf0e10cSrcweir
1458cdf0e10cSrcweir     }
1459cdf0e10cSrcweir    elsif ($arg eq 'fetch') {
1460cdf0e10cSrcweir        print STDERR "fetch: fetch a milestone or CWS\n";
1461cdf0e10cSrcweir        print STDERR "usage: fetch [-q] [-p platforms] [-r additionalrepositories] [-o] <-m milestone> <workspace>\n";
1462cdf0e10cSrcweir        print STDERR "usage: fetch [-q] [-p platforms] [-r additionalrepositories] [-o] <-c cws> <workspace>\n";
1463cdf0e10cSrcweir        print STDERR "usage: fetch [-q] [-x platforms] [-r additionalrepositories] [-o] <-m milestone> <workspace>\n";
1464cdf0e10cSrcweir        print STDERR "usage: fetch [-q] [-x platforms] [-r additionalrepositories] [-o] <-c cws> <workspace>\n";
1465cdf0e10cSrcweir        print STDERR "usage: fetch [-q] <-m milestone> <workspace>\n";
1466cdf0e10cSrcweir        print STDERR "usage: fetch [-q] <-c cws> <workspace>\n";
1467cdf0e10cSrcweir        print STDERR "\t-m milestone:            Checkout milestone <milestone> to workspace <workspace>\n";
1468cdf0e10cSrcweir        print STDERR "\t                         Use 'latest' for the for lastest published milestone on the current master\n";
1469cdf0e10cSrcweir        print STDERR "\t                         For cross master checkouts use the form <MWS>:<milestone>\n";
1470cdf0e10cSrcweir        print STDERR "\t--milestone milestone:   Same as -m milestone\n";
1471cdf0e10cSrcweir        print STDERR "\t-c childworkspace:       Checkout CWS <childworkspace> to workspace <workspace>\n";
1472cdf0e10cSrcweir        print STDERR "\t--child childworkspace:  Same as -c childworkspace\n";
1473cdf0e10cSrcweir        print STDERR "\t-p platform:             Copy one or more prebuilt platforms 'platform'. \n";
1474cdf0e10cSrcweir        print STDERR "\t                         Separate multiple platforms with commas.\n";
1475cdf0e10cSrcweir        print STDERR "\t                         Automatically adds 'common[.pro]' as required.\n";
1476cdf0e10cSrcweir        print STDERR "\t--platforms platform:    Same as -p\n";
1477cdf0e10cSrcweir        print STDERR "\t-x platform:             Copy one or more prebuilt platforms 'platform'. \n";
1478cdf0e10cSrcweir        print STDERR "\t                         Separate multiple platforms with commas.\n";
1479cdf0e10cSrcweir        print STDERR "\t                         Does not automatically adds 'common[.pro]'.\n";
1480cdf0e10cSrcweir        print STDERR "\t-r additionalrepositories Checkout additional repositories. \n";
1481cdf0e10cSrcweir        print STDERR "\t                         Separate multiple repositories with commas.\n";
1482cdf0e10cSrcweir        print STDERR "\t--noautocommon platform: Same as -x\n";
1483cdf0e10cSrcweir        print STDERR "\t-o:                      Omit checkout of sources, copy only solver. \n";
1484cdf0e10cSrcweir        print STDERR "\t--onlysolver:            Same as -o\n";
1485cdf0e10cSrcweir        print STDERR "\t-q:                      Silence some of the output of the command.\n";
1486cdf0e10cSrcweir        print STDERR "\t--quiet:                 Same as -q\n";
1487cdf0e10cSrcweir    }
1488cdf0e10cSrcweir    elsif ($arg eq 'setcurrent') {
1489cdf0e10cSrcweir        print STDERR "setcurrent: Set the current milestone for the CWS (only hg based CWSs)\n";
1490cdf0e10cSrcweir        print STDERR "usage: setcurrent [-m milestone]\n";
1491cdf0e10cSrcweir        print STDERR "\t-m milestone:           Set milestone to <milestone> to workspace <workspace>\n";
1492cdf0e10cSrcweir        print STDERR "\t                        Use 'latest' for the for lastest published milestone on the current master\n";
1493cdf0e10cSrcweir        print STDERR "\t                        For cross master change use the form <MWS>:<milestone>\n";
1494cdf0e10cSrcweir        print STDERR "\t--milestone milestone:  Same as -m milestone\n";
1495cdf0e10cSrcweir    }
1496cdf0e10cSrcweir    else {
1497cdf0e10cSrcweir        print STDERR "'$arg': unknown subcommand\n";
1498cdf0e10cSrcweir        exit(1);
1499cdf0e10cSrcweir    }
1500cdf0e10cSrcweir    exit(0);
1501cdf0e10cSrcweir}
1502cdf0e10cSrcweir
1503cdf0e10cSrcweir# Executes the create command.
1504cdf0e10cSrcweirsub do_create
1505cdf0e10cSrcweir{
1506cdf0e10cSrcweir    my $args_ref    = shift;
1507cdf0e10cSrcweir    my $options_ref = shift;
1508cdf0e10cSrcweir
1509cdf0e10cSrcweir    if ( exists $options_ref->{'help'} || @{$args_ref} != 2) {
1510cdf0e10cSrcweir        do_help(['create']);
1511cdf0e10cSrcweir    }
1512cdf0e10cSrcweir
1513cdf0e10cSrcweir    if ( exists $options_ref->{'hg'} ) {
1514cdf0e10cSrcweir        print_warning("All childworkspaces are now hosted on Mercurial. The switch --hg is obsolete.");
1515cdf0e10cSrcweir    }
1516cdf0e10cSrcweir
1517cdf0e10cSrcweir    my $master   = uc $args_ref->[0];
1518cdf0e10cSrcweir    my $cws_name = $args_ref->[1];
1519cdf0e10cSrcweir
1520cdf0e10cSrcweir    if (!is_master($master)) {
1521cdf0e10cSrcweir        print_error("'$master' is not a valid master workspace.", 7);
1522cdf0e10cSrcweir    }
1523cdf0e10cSrcweir
1524cdf0e10cSrcweir    # check if cws name fits the convention
1525cdf0e10cSrcweir    if ( $cws_name !~ /^\w[\w\.\#]*$/ ) {
1526cdf0e10cSrcweir        print_error("Invalid child workspace name '$cws_name'.\nCws names should consist of alphanumeric characters, preferable all lowercase and starting with a letter.\nThe characters . and # are allowed if they are not the first character.", 7);
1527cdf0e10cSrcweir    }
1528cdf0e10cSrcweir
1529cdf0e10cSrcweir    my $cws = get_this_cws();
1530cdf0e10cSrcweir    $cws->master($master);
1531cdf0e10cSrcweir    $cws->child($cws_name);
1532cdf0e10cSrcweir
1533cdf0e10cSrcweir    # check if child workspace already exists
1534cdf0e10cSrcweir    my $eis_id = $cws->eis_id();
1535cdf0e10cSrcweir    if ( !defined($eis_id) ) {
1536cdf0e10cSrcweir        print_error("Connection with EIS database failed.", 8);
1537cdf0e10cSrcweir    }
1538cdf0e10cSrcweir
1539cdf0e10cSrcweir    my $is_promotion = 0;
1540cdf0e10cSrcweir    if ( $eis_id > 0 ) {
1541cdf0e10cSrcweir        if ( $cws->get_approval() eq 'planned' ) {
1542cdf0e10cSrcweir            print "Promote child workspace '$cws_name' from 'planned' to 'new'.\n";
1543cdf0e10cSrcweir            $is_promotion++;
1544cdf0e10cSrcweir        }
1545cdf0e10cSrcweir        else {
1546cdf0e10cSrcweir            print_error("Child workspace '$cws_name' already exists.", 7);
1547cdf0e10cSrcweir        }
1548cdf0e10cSrcweir    }
1549cdf0e10cSrcweir    else {
1550cdf0e10cSrcweir        # check if child workspace name is still available
1551cdf0e10cSrcweir        if ( !$cws->is_cws_name_available()) {
1552cdf0e10cSrcweir            print_error("Child workspace name '$cws_name' is already in use.", 7);
1553cdf0e10cSrcweir        }
1554cdf0e10cSrcweir    }
1555cdf0e10cSrcweir
1556cdf0e10cSrcweir    my $milestone;
1557cdf0e10cSrcweir    # verify milestone or query latest milestone
1558cdf0e10cSrcweir    if ( exists $options_ref->{'milestone'} ) {
1559cdf0e10cSrcweir        $milestone=$options_ref->{'milestone'};
1560cdf0e10cSrcweir        # check if milestone exists
1561cdf0e10cSrcweir        if ( !$cws->is_milestone($master, $milestone) ) {
1562cdf0e10cSrcweir            print_error("Milestone '$milestone' is not registered with master workspace '$master'.", 8);
1563cdf0e10cSrcweir        }
1564cdf0e10cSrcweir    }
1565cdf0e10cSrcweir    else {
1566cdf0e10cSrcweir        $milestone=$cws->get_current_milestone($cws->master());
1567cdf0e10cSrcweir    }
1568cdf0e10cSrcweir
1569cdf0e10cSrcweir    # set milestone
1570cdf0e10cSrcweir    $cws->milestone($milestone);
1571cdf0e10cSrcweir
1572cdf0e10cSrcweir    register_child_workspace($cws, 'hg', $is_promotion);
1573cdf0e10cSrcweir
1574cdf0e10cSrcweir    return;
1575cdf0e10cSrcweir}
1576cdf0e10cSrcweir
1577cdf0e10cSrcweir# Executes the fetch command.
1578cdf0e10cSrcweirsub do_fetch
1579cdf0e10cSrcweir{
1580cdf0e10cSrcweir    my $args_ref    = shift;
1581cdf0e10cSrcweir    my $options_ref = shift;
1582cdf0e10cSrcweir
1583cdf0e10cSrcweir    my $time_fetch_start = Benchmark->new();
1584cdf0e10cSrcweir    if ( exists $options_ref->{'help'} || @{$args_ref} != 1) {
1585cdf0e10cSrcweir        do_help(['fetch']);
1586cdf0e10cSrcweir    }
1587cdf0e10cSrcweir
1588cdf0e10cSrcweir    my $milestone_opt = $options_ref->{'milestone'};
1589cdf0e10cSrcweir    my $additional_repositories_opt = $options_ref->{'additionalrepositories'};
1590cdf0e10cSrcweir    $additional_repositories_opt = "", if ( !defined $additional_repositories_opt );
1591cdf0e10cSrcweir    my $child = $options_ref->{'childworkspace'};
1592cdf0e10cSrcweir    my $platforms = $options_ref->{'platforms'};
1593cdf0e10cSrcweir    my $noautocommon = $options_ref->{'noautocommon'};
1594cdf0e10cSrcweir    my $quiet  = $options_ref->{'quiet'}  ? 1 : 0 ;
1595cdf0e10cSrcweir    my $switch = $options_ref->{'switch'} ? 1 : 0 ;
1596cdf0e10cSrcweir    my $onlysolver = $options_ref->{'onlysolver'} ? 1 : 0 ;
1597cdf0e10cSrcweir
1598cdf0e10cSrcweir    if ( !defined($milestone_opt) && !defined($child) ) {
1599cdf0e10cSrcweir        print_error("Specify one of these options: -m or -c", 0);
1600cdf0e10cSrcweir        do_help(['fetch']);
1601cdf0e10cSrcweir    }
1602cdf0e10cSrcweir
1603cdf0e10cSrcweir    if ( defined($milestone_opt) && defined($child) ) {
1604cdf0e10cSrcweir        print_error("Options -m and -c are mutally exclusive", 0);
1605cdf0e10cSrcweir        do_help(['fetch']);
1606cdf0e10cSrcweir    }
1607cdf0e10cSrcweir
1608cdf0e10cSrcweir    if ( defined($platforms) && defined($noautocommon) ) {
1609cdf0e10cSrcweir        print_error("Options -p and -x are mutally exclusive", 0);
1610cdf0e10cSrcweir        do_help(['fetch']);
1611cdf0e10cSrcweir    }
1612cdf0e10cSrcweir
1613cdf0e10cSrcweir    if ( $onlysolver && !(defined($platforms) || defined($noautocommon)) ) {
1614cdf0e10cSrcweir        print_error("Option '-o' is Only usuable combination with option '-p' or '-x'.", 0);
1615cdf0e10cSrcweir        do_help(['fetch']);
1616cdf0e10cSrcweir    }
1617cdf0e10cSrcweir
1618cdf0e10cSrcweir    my $cws = get_this_cws();
1619cdf0e10cSrcweir    my $masterws = $ENV{WORK_STAMP};
1620cdf0e10cSrcweir    if ( !defined($masterws) ) {
1621cdf0e10cSrcweir        print_error("Can't determine current master workspace: check environment variable WORK_STAMP", 21);
1622cdf0e10cSrcweir    }
1623cdf0e10cSrcweir    $cws->master($masterws);
1624cdf0e10cSrcweir    my $milestone;
1625cdf0e10cSrcweir    if( defined($milestone_opt) ) {
1626cdf0e10cSrcweir        if ( $milestone_opt eq 'latest' ) {
1627cdf0e10cSrcweir            $cws->master($masterws);
1628cdf0e10cSrcweir            my $latest = $cws->get_current_milestone($masterws);
1629cdf0e10cSrcweir
1630cdf0e10cSrcweir            if ( !$latest ) {
1631cdf0e10cSrcweir                print_error("Can't determine latest milestone of master workspace '$masterws'.", 22);
1632cdf0e10cSrcweir            }
1633cdf0e10cSrcweir            $milestone = $cws->get_current_milestone($masterws);
1634cdf0e10cSrcweir        }
1635cdf0e10cSrcweir        else {
1636cdf0e10cSrcweir            ($masterws, $milestone) =  verify_milestone($cws, $milestone_opt);
1637cdf0e10cSrcweir        }
1638cdf0e10cSrcweir    }
1639cdf0e10cSrcweir    elsif ( defined($child) ) {
1640cdf0e10cSrcweir        $cws = get_cws_by_name($child);
1641cdf0e10cSrcweir        $masterws = $cws->master(); # CWS can have another master than specified in ENV
1642cdf0e10cSrcweir        $milestone = $cws->milestone();
1643cdf0e10cSrcweir    }
1644cdf0e10cSrcweir    else {
1645cdf0e10cSrcweir        do_help(['fetch']);
1646cdf0e10cSrcweir    }
1647cdf0e10cSrcweir
1648cdf0e10cSrcweir    my $config = CwsConfig->new();
1649cdf0e10cSrcweir    # $so_svn_server is still required to determine if we are in SO environment
1650cdf0e10cSrcweir    # TODO: change this configuration setting to something more meaningful
1651cdf0e10cSrcweir    my $so_svn_server = $config->get_so_svn_server();
1652cdf0e10cSrcweir    my $prebuild_dir = $config->get_prebuild_binaries_location();
1653cdf0e10cSrcweir    my $external_tarball_source = $prebuild_dir;
1654cdf0e10cSrcweir    # Check early for platforms so we can bail out before anything time consuming is done
1655cdf0e10cSrcweir    # in case of a missing platform
1656cdf0e10cSrcweir    my @platforms;
1657cdf0e10cSrcweir    if ( defined($platforms) || defined($noautocommon) ) {
1658cdf0e10cSrcweir        use Archive::Zip; # warn early if module is missing
1659cdf0e10cSrcweir        if ( !defined($prebuild_dir ) ) {
1660cdf0e10cSrcweir            print_error("PREBUILD_BINARIES not configured, can't find platform solvers", 99);
1661cdf0e10cSrcweir        }
1662cdf0e10cSrcweir        $prebuild_dir = "$prebuild_dir/$masterws";
1663cdf0e10cSrcweir
1664cdf0e10cSrcweir        if ( defined($platforms) ) {
1665cdf0e10cSrcweir            @platforms = split(/,/, $platforms);
1666cdf0e10cSrcweir
1667cdf0e10cSrcweir            my $added_product = 0;
1668cdf0e10cSrcweir            my $added_nonproduct = 0;
1669cdf0e10cSrcweir            foreach(@platforms) {
1670cdf0e10cSrcweir                if ( $_ eq 'common.pro' ) {
1671cdf0e10cSrcweir                    $added_product = 1;
1672cdf0e10cSrcweir                    print_warning("'$_' is added automatically to the platform list, don't specify it explicit");
1673cdf0e10cSrcweir                }
1674cdf0e10cSrcweir                if ( $_ eq 'common' ) {
1675cdf0e10cSrcweir                    $added_nonproduct = 1;
1676cdf0e10cSrcweir                    print_warning("'$_' is added automatically to the platform list, don't specify it explicit");
1677cdf0e10cSrcweir                }
1678cdf0e10cSrcweir            }
1679cdf0e10cSrcweir
1680cdf0e10cSrcweir            # add common.pro/common to platform list
1681cdf0e10cSrcweir            if ( $so_svn_server ) {
1682cdf0e10cSrcweir                my $product = 0;
1683cdf0e10cSrcweir                my $nonproduct = 0;
1684cdf0e10cSrcweir                foreach(@platforms) {
1685cdf0e10cSrcweir                    if ( /\.pro$/ ) {
1686cdf0e10cSrcweir                        $product = 1;
1687cdf0e10cSrcweir                    }
1688cdf0e10cSrcweir                    else {
1689cdf0e10cSrcweir                        $nonproduct = 1;
1690cdf0e10cSrcweir                    }
1691cdf0e10cSrcweir                }
1692cdf0e10cSrcweir                unshift(@platforms, 'common.pro') if ($product && !$added_product);
1693cdf0e10cSrcweir                unshift(@platforms, 'common') if ($nonproduct && !$added_nonproduct);
1694cdf0e10cSrcweir            }
1695cdf0e10cSrcweir        }
1696cdf0e10cSrcweir        else {
1697cdf0e10cSrcweir            @platforms = split(/,/, $noautocommon);
1698cdf0e10cSrcweir        }
1699cdf0e10cSrcweir
1700cdf0e10cSrcweir        foreach(@platforms) {
1701cdf0e10cSrcweir            if ( ! -d "$prebuild_dir/$_") {
1702cdf0e10cSrcweir                print_error("Can't find prebuild binaries for platform '$_'.", 22);
1703cdf0e10cSrcweir            }
1704cdf0e10cSrcweir        }
1705cdf0e10cSrcweir
1706cdf0e10cSrcweir    }
1707cdf0e10cSrcweir
1708cdf0e10cSrcweir    my $cwsname = $cws->child();
1709cdf0e10cSrcweir    my $linkdir = $milestone_opt ? "src.$milestone" : "src." . $cws->milestone;
1710cdf0e10cSrcweir
1711cdf0e10cSrcweir    my $workspace = $args_ref->[0];
1712cdf0e10cSrcweir
1713cdf0e10cSrcweir    if ( !$onlysolver ) {
1714cdf0e10cSrcweir        if ( -e $workspace ) {
1715cdf0e10cSrcweir            print_error("File or directory '$workspace' already exists.", 8);
1716cdf0e10cSrcweir        }
1717cdf0e10cSrcweir
1718cdf0e10cSrcweir        my $clone_milestone_only = $milestone_opt ? $milestone : 0;
1719cdf0e10cSrcweir        if ( defined($so_svn_server) ) {
1720cdf0e10cSrcweir            if ( !mkdir($workspace) ) {
1721cdf0e10cSrcweir                print_error("Can't create directory '$workspace': $!.", 8);
1722cdf0e10cSrcweir            }
1723cdf0e10cSrcweir            my $work_master = "$workspace/$masterws";
1724cdf0e10cSrcweir            if ( !mkdir($work_master) ) {
1725cdf0e10cSrcweir                print_error("Can't create directory '$work_master': $!.", 8);
1726cdf0e10cSrcweir            }
1727cdf0e10cSrcweir
1728cdf0e10cSrcweir            my %unique = map { $_ => 1 } split( /,/ , $additional_repositories_opt);
1729cdf0e10cSrcweir            my @unique_repo_list = keys %unique;
1730cdf0e10cSrcweir
1731cdf0e10cSrcweir            if (defined($additional_repositories_opt))
1732cdf0e10cSrcweir            {
1733cdf0e10cSrcweir                foreach my $repo(@unique_repo_list)
1734cdf0e10cSrcweir                {
1735cdf0e10cSrcweir                    # do not double clone ooo and sun
1736cdf0e10cSrcweir                    hg_clone_cws_or_milestone($repo, $cws, "$work_master/".$repo, $clone_milestone_only), if $repo ne "ooo" && $repo ne "sun";
1737cdf0e10cSrcweir                }
1738cdf0e10cSrcweir
1739cdf0e10cSrcweir            }
1740cdf0e10cSrcweir
1741cdf0e10cSrcweir            hg_clone_cws_or_milestone('ooo', $cws, "$work_master/ooo", $clone_milestone_only);
1742cdf0e10cSrcweir            hg_clone_cws_or_milestone('so', $cws, "$work_master/sun", $clone_milestone_only);
1743cdf0e10cSrcweir
1744cdf0e10cSrcweir            if ( get_source_config_for_milestone($masterws, $milestone) ) {
1745cdf0e10cSrcweir                # write source_config file
1746cdf0e10cSrcweir                my $source_config_file = "$work_master/source_config";
1747cdf0e10cSrcweir                if ( !open(SOURCE_CONFIG, ">$source_config_file") ) {
1748cdf0e10cSrcweir                    print_error("Can't create source_config file '$source_config_file': $!.", 8);
1749cdf0e10cSrcweir                }
1750cdf0e10cSrcweir                print SOURCE_CONFIG "[repositories]\n";
1751cdf0e10cSrcweir                print SOURCE_CONFIG "ooo=active\n";
1752cdf0e10cSrcweir                print SOURCE_CONFIG "sun=active\n";
1753cdf0e10cSrcweir                foreach my $repo(@unique_repo_list)
1754cdf0e10cSrcweir                {
1755cdf0e10cSrcweir                    print SOURCE_CONFIG $repo."=active\n", if $repo ne "ooo" || $repo ne "sun";
1756cdf0e10cSrcweir                }
1757cdf0e10cSrcweir                close(SOURCE_CONFIG);
1758cdf0e10cSrcweir            }
1759cdf0e10cSrcweir            else {
1760cdf0e10cSrcweir                my $linkdir = "$work_master/src.$milestone";
1761cdf0e10cSrcweir                if ( !mkdir($linkdir) ) {
1762cdf0e10cSrcweir                    print_error("Can't create directory '$linkdir': $!.", 8);
1763cdf0e10cSrcweir                }
1764cdf0e10cSrcweir                relink_workspace($linkdir);
1765cdf0e10cSrcweir            }
1766cdf0e10cSrcweir        }
1767cdf0e10cSrcweir        else {
1768cdf0e10cSrcweir            hg_clone_cws_or_milestone('ooo', $cws, $workspace, $clone_milestone_only);
1769cdf0e10cSrcweir        }
1770cdf0e10cSrcweir    }
1771cdf0e10cSrcweir
1772cdf0e10cSrcweir    if ( !$onlysolver && defined($external_tarball_source) ) {
1773cdf0e10cSrcweir        my $source_root_dir = "$workspace/$masterws";
1774cdf0e10cSrcweir        $external_tarball_source .= "/$masterws/ext_sources";
1775cdf0e10cSrcweir        if ( -e "$source_root_dir/ooo/ooo.lst" && -d $external_tarball_source ) {
1776cdf0e10cSrcweir            fetch_external_tarballs($source_root_dir, $external_tarball_source);
1777cdf0e10cSrcweir        }
1778cdf0e10cSrcweir    }
1779cdf0e10cSrcweir
1780cdf0e10cSrcweir    if ( defined($platforms) || defined($noautocommon) ) {
1781cdf0e10cSrcweir        if ( !-d $workspace ) {
1782cdf0e10cSrcweir            if ( !mkdir($workspace) ) {
1783cdf0e10cSrcweir                print_error("Can't create directory '$workspace': $!.", 8);
1784cdf0e10cSrcweir            }
1785cdf0e10cSrcweir        }
1786cdf0e10cSrcweir        my $solver = defined($so_svn_server) ? "$workspace/$masterws" : "$workspace/solver";
1787cdf0e10cSrcweir        if ( !-d $solver ) {
1788cdf0e10cSrcweir            if ( !mkdir($solver) ) {
1789cdf0e10cSrcweir                print_error("Can't create directory '$solver': $!.", 8);
1790cdf0e10cSrcweir            }
1791cdf0e10cSrcweir        }
1792cdf0e10cSrcweir        my $source_config = get_source_config_for_milestone($masterws, $milestone);
1793cdf0e10cSrcweir        foreach(@platforms) {
1794cdf0e10cSrcweir            my $time_solver_start = Benchmark->new();
1795cdf0e10cSrcweir            print_message("... copying platform solver '$_'.");
1796cdf0e10cSrcweir            update_solver($_, $prebuild_dir, $solver, $milestone, $source_config);
1797cdf0e10cSrcweir            my $time_solver_stop = Benchmark->new();
1798cdf0e10cSrcweir            print_time_elapsed($time_solver_start, $time_solver_stop) if $profile;
1799cdf0e10cSrcweir        }
1800cdf0e10cSrcweir    }
1801cdf0e10cSrcweir    my $time_fetch_stop = Benchmark->new();
1802cdf0e10cSrcweir    my $time_fetch = timediff($time_fetch_stop, $time_fetch_start);
1803cdf0e10cSrcweir    print_message("cws fetch: total time required " . timestr($time_fetch));
1804cdf0e10cSrcweir}
1805cdf0e10cSrcweir
1806cdf0e10cSrcweirsub do_query
1807cdf0e10cSrcweir{
1808cdf0e10cSrcweir    my $args_ref    = shift;
1809cdf0e10cSrcweir    my $options_ref = shift;
1810cdf0e10cSrcweir
1811cdf0e10cSrcweir    # list of available query modes
1812cdf0e10cSrcweir    my @query_modes = qw(integratedinto incompatible taskids status latest current owner qarep build buildid integrated approved nominated ready new planned release due due_qa help ui milestones masters scm ispublic ispublicmaster);
1813cdf0e10cSrcweir    my %query_modes_hash = ();
1814cdf0e10cSrcweir    foreach (@query_modes) {
1815cdf0e10cSrcweir        $query_modes_hash{$_}++;
1816cdf0e10cSrcweir    }
1817cdf0e10cSrcweir
1818cdf0e10cSrcweir    if ( exists $options_ref->{'help'} || @{$args_ref} != 1) {
1819cdf0e10cSrcweir        do_help(['query']);
1820cdf0e10cSrcweir    }
1821cdf0e10cSrcweir    my $mode = lc($args_ref->[0]);
1822cdf0e10cSrcweir
1823cdf0e10cSrcweir    # cwquery mode 'state' has been renamed to 'status' to be more consistent
1824cdf0e10cSrcweir    # with CVS etc. 'state' is still an alias for 'status'
1825cdf0e10cSrcweir    $mode = 'status' if $mode eq 'state';
1826cdf0e10cSrcweir
1827cdf0e10cSrcweir    # cwquery mode 'vcs' has been renamed to 'scm' to be more consistent
1828cdf0e10cSrcweir    # with general use etc. 'vcs' is still an alias for 'scm'
1829cdf0e10cSrcweir    $mode = 'scm' if $mode eq 'vcs';
1830cdf0e10cSrcweir
1831cdf0e10cSrcweir    # there will be more query modes over time
1832cdf0e10cSrcweir    if ( !exists $query_modes_hash{$mode} ) {
1833cdf0e10cSrcweir        do_help(['query']);
1834cdf0e10cSrcweir    }
1835cdf0e10cSrcweir    query_cws($mode, $options_ref);
1836cdf0e10cSrcweir}
1837cdf0e10cSrcweir
1838cdf0e10cSrcweirsub do_task
1839cdf0e10cSrcweir{
1840cdf0e10cSrcweir    my $args_ref    = shift;
1841cdf0e10cSrcweir    my $options_ref = shift;
1842cdf0e10cSrcweir
1843cdf0e10cSrcweir    if ( exists $options_ref->{'help'} ) {
1844cdf0e10cSrcweir        do_help(['task']);
1845cdf0e10cSrcweir    }
1846cdf0e10cSrcweir
1847cdf0e10cSrcweir    # CWS states for which adding tasks are blocked.
1848cdf0e10cSrcweir    my @states_blocked_for_adding = (
1849cdf0e10cSrcweir                                        "integrated",
1850cdf0e10cSrcweir                                        "nominated",
1851cdf0e10cSrcweir                                        "approved by QA",
1852cdf0e10cSrcweir                                        "cancelled",
1853cdf0e10cSrcweir                                        "finished"
1854cdf0e10cSrcweir                                    );
1855cdf0e10cSrcweir    my $cws = get_cws_from_environment();
1856cdf0e10cSrcweir
1857cdf0e10cSrcweir    # register taskids with EIS database;
1858cdf0e10cSrcweir    # checks taksids for sanity, will notify user
1859cdf0e10cSrcweir    # if taskid is already registered.
1860cdf0e10cSrcweir    my $status = $cws->get_approval();
1861cdf0e10cSrcweir
1862cdf0e10cSrcweir    my $child = $cws->child();
1863cdf0e10cSrcweir    my $master = $cws->master();
1864cdf0e10cSrcweir
1865cdf0e10cSrcweir    my @registered_taskids = $cws->taskids();
1866cdf0e10cSrcweir
1867cdf0e10cSrcweir    # if called without ids to register just query for tasks
1868cdf0e10cSrcweir    if ( @{$args_ref} == 0 ) {
1869cdf0e10cSrcweir        print_message("Task ID(s):");
1870cdf0e10cSrcweir        foreach (@registered_taskids) {
1871cdf0e10cSrcweir            if ( defined($_) ) {
1872cdf0e10cSrcweir                print "$_\n";
1873cdf0e10cSrcweir            }
1874cdf0e10cSrcweir        }
1875cdf0e10cSrcweir    }
1876cdf0e10cSrcweir
1877cdf0e10cSrcweir    if ( !defined($status) ) {
1878cdf0e10cSrcweir        print_error("Can't determine status of child workspace `$child`.", 20);
1879cdf0e10cSrcweir    }
1880cdf0e10cSrcweir
1881cdf0e10cSrcweir    if ( grep($status eq $_, @states_blocked_for_adding) ) {
1882cdf0e10cSrcweir        print_error("Can't add tasks to child workspace '$child' with state '$status'.", 21);
1883cdf0e10cSrcweir    }
1884cdf0e10cSrcweir
1885cdf0e10cSrcweir    # Create hash for easier searching.
1886cdf0e10cSrcweir    my %registered_taskids_hash = ();
1887cdf0e10cSrcweir    for (@registered_taskids) {
1888cdf0e10cSrcweir        $registered_taskids_hash{$_}++;
1889cdf0e10cSrcweir    }
1890cdf0e10cSrcweir
1891cdf0e10cSrcweir    my @new_taskids = ();
1892cdf0e10cSrcweir    foreach (@{$args_ref}) {
1893cdf0e10cSrcweir        if ( $_ !~ /^([ib]?\d+)$/ ) {
1894cdf0e10cSrcweir            print_error("'$_' is an invalid task ID.", 22);
1895cdf0e10cSrcweir        }
1896cdf0e10cSrcweir        if ( exists $registered_taskids_hash{$1} ) {
1897cdf0e10cSrcweir            print_warning("Task ID '$_' already registered, skipping.");
1898cdf0e10cSrcweir            next;
1899cdf0e10cSrcweir        }
1900cdf0e10cSrcweir        push(@new_taskids, $_);
1901cdf0e10cSrcweir    }
1902cdf0e10cSrcweir
1903cdf0e10cSrcweir    # TODO: introduce a EIS_USER in the configuration, which should be used here
1904cdf0e10cSrcweir    my $config = CwsConfig->new();
1905cdf0e10cSrcweir    my $vcsid  = $config->vcsid();
1906cdf0e10cSrcweir    my $added_taskids_ref = $cws->add_taskids($vcsid, @new_taskids);
1907cdf0e10cSrcweir    if ( !$added_taskids_ref )  {
1908cdf0e10cSrcweir        my $taskids_str = join(" ", @new_taskids);
1909cdf0e10cSrcweir        print_error("Couldn't register taskID(s) '$taskids_str' with child workspace '$child'.", 23);
1910cdf0e10cSrcweir    }
1911cdf0e10cSrcweir    my @added_taskids = @{$added_taskids_ref};
1912cdf0e10cSrcweir    if ( @added_taskids ) {
1913cdf0e10cSrcweir        my $taskids_str = join(" ", @added_taskids);
1914cdf0e10cSrcweir        print_message("Registered taskID(s) '$taskids_str' with child workspace '$child'.");
1915cdf0e10cSrcweir    }
1916cdf0e10cSrcweir    return;
1917cdf0e10cSrcweir}
1918cdf0e10cSrcweir
1919cdf0e10cSrcweirsub do_setcurrent
1920cdf0e10cSrcweir{
1921cdf0e10cSrcweir    my $args_ref    = shift;
1922cdf0e10cSrcweir    my $options_ref = shift;
1923cdf0e10cSrcweir
1924cdf0e10cSrcweir    if ( exists $options_ref->{'help'} || @{$args_ref} != 0) {
1925cdf0e10cSrcweir        do_help(['setcurrent']);
1926cdf0e10cSrcweir    }
1927cdf0e10cSrcweir
1928cdf0e10cSrcweir    if ( !exists $options_ref->{'milestone'} ) {
1929cdf0e10cSrcweir        do_help(['setcurrent']);
1930cdf0e10cSrcweir    }
1931cdf0e10cSrcweir
1932cdf0e10cSrcweir    my $cws = get_cws_from_environment();
1933cdf0e10cSrcweir    my $old_masterws = $cws->master();
1934cdf0e10cSrcweir    my $new_masterws;
1935cdf0e10cSrcweir    my $new_milestone;
1936cdf0e10cSrcweir
1937cdf0e10cSrcweir    my $milestone = $options_ref->{'milestone'};
1938cdf0e10cSrcweir    if ( $milestone eq 'latest' ) {
1939cdf0e10cSrcweir        my $latest = $cws->get_current_milestone($old_masterws);
1940cdf0e10cSrcweir
1941cdf0e10cSrcweir        if ( !$latest ) {
1942cdf0e10cSrcweir            print_error("Can't determine latest milestone of '$old_masterws'.", 22);
1943cdf0e10cSrcweir        }
1944cdf0e10cSrcweir        $new_masterws  = $old_masterws;
1945cdf0e10cSrcweir        $new_milestone = $latest;
1946cdf0e10cSrcweir    }
1947cdf0e10cSrcweir    else {
1948cdf0e10cSrcweir        ($new_masterws, $new_milestone) =  verify_milestone($cws, $milestone);
1949cdf0e10cSrcweir    }
1950cdf0e10cSrcweir
1951cdf0e10cSrcweir    print_message("... updating EIS database");
1952cdf0e10cSrcweir    my $push_return = $cws->set_master_and_milestone($new_masterws, $new_milestone);
1953cdf0e10cSrcweir    # sanity check
1954cdf0e10cSrcweir    if ( $$push_return[1] ne $new_milestone) {
1955cdf0e10cSrcweir        print_error("Couldn't push new milestone '$new_milestone' to database", 0);
1956cdf0e10cSrcweir    }
1957cdf0e10cSrcweir}
1958cdf0e10cSrcweir
1959cdf0e10cSrcweirsub do_eisclone
1960cdf0e10cSrcweir{
1961cdf0e10cSrcweir    my $args_ref    = shift;
1962cdf0e10cSrcweir    my $options_ref = shift;
1963cdf0e10cSrcweir
1964cdf0e10cSrcweir    print_error("not yet implemented.", 2);
1965cdf0e10cSrcweir}
1966cdf0e10cSrcweir
1967cdf0e10cSrcweirsub print_message
1968cdf0e10cSrcweir{
1969cdf0e10cSrcweir    my $message     = shift;
1970cdf0e10cSrcweir
1971cdf0e10cSrcweir    print "$message\n";
1972cdf0e10cSrcweir    return;
1973cdf0e10cSrcweir}
1974cdf0e10cSrcweir
1975cdf0e10cSrcweirsub print_warning
1976cdf0e10cSrcweir{
1977cdf0e10cSrcweir    my $message     = shift;
1978cdf0e10cSrcweir    print STDERR "$script_name: ";
1979cdf0e10cSrcweir    print STDERR "WARNING: $message\n";
1980cdf0e10cSrcweir    return;
1981cdf0e10cSrcweir}
1982cdf0e10cSrcweir
1983cdf0e10cSrcweirsub print_error
1984cdf0e10cSrcweir{
1985cdf0e10cSrcweir    my $message     = shift;
1986cdf0e10cSrcweir    my $error_code  = shift;
1987cdf0e10cSrcweir
1988cdf0e10cSrcweir    print STDERR "$script_name: ";
1989cdf0e10cSrcweir    print STDERR "ERROR: $message\n";
1990cdf0e10cSrcweir
1991cdf0e10cSrcweir    if ( $error_code ) {
1992cdf0e10cSrcweir        print STDERR "\nFAILURE: $script_name aborted.\n";
1993cdf0e10cSrcweir        exit($error_code);
1994cdf0e10cSrcweir    }
1995cdf0e10cSrcweir    return;
1996cdf0e10cSrcweir}
1997cdf0e10cSrcweir
1998cdf0e10cSrcweirsub usage
1999cdf0e10cSrcweir{
2000cdf0e10cSrcweir        print STDERR "Type 'cws help' for usage.\n";
2001cdf0e10cSrcweir}
2002cdf0e10cSrcweir
2003cdf0e10cSrcweir### HG glue ###
2004cdf0e10cSrcweir
2005cdf0e10cSrcweirsub hg_clone
2006cdf0e10cSrcweir{
2007cdf0e10cSrcweir    my $source  = shift;
2008cdf0e10cSrcweir    my $dest    = shift;
2009cdf0e10cSrcweir    my $options = shift;
2010cdf0e10cSrcweir
2011cdf0e10cSrcweir    if ( $debug ) {
2012cdf0e10cSrcweir        print STDERR "CWS-DEBUG: ... hg clone: '$source -> $dest', options: '$options'\n";
2013cdf0e10cSrcweir    }
2014cdf0e10cSrcweir
2015cdf0e10cSrcweir    # The to be cloned revision might not yet be avaliable. In this case clone
2016cdf0e10cSrcweir    # the available tip.
2017cdf0e10cSrcweir    my @result = execute_hg_command(0, 'clone', $options, $source, $dest);
2018cdf0e10cSrcweir    if ( defined($result[0]) && $result[0] =~ /abort: unknown revision/ ) {
2019cdf0e10cSrcweir        $options =~ s/-r \w+//;
2020cdf0e10cSrcweir        @result = execute_hg_command(1, 'clone', $options, $source, $dest);
2021cdf0e10cSrcweir    }
2022cdf0e10cSrcweir    return @result;
2023cdf0e10cSrcweir}
2024cdf0e10cSrcweir
2025cdf0e10cSrcweirsub hg_parent
2026cdf0e10cSrcweir{
2027cdf0e10cSrcweir    my $repository  = shift;
2028cdf0e10cSrcweir    my $rev_id = shift;
2029cdf0e10cSrcweir    my $options = shift;
2030cdf0e10cSrcweir
2031cdf0e10cSrcweir    if ( $debug ) {
2032cdf0e10cSrcweir        print STDERR "CWS-DEBUG: ... hg parent: 'repository', revision: '$rev_id', options: $options\n";
2033cdf0e10cSrcweir    }
2034cdf0e10cSrcweir
2035cdf0e10cSrcweir    my @result = execute_hg_command(0, 'parent', "--cwd $repository", "-r $rev_id", $options);
2036cdf0e10cSrcweir    my $line = $result[0];
2037cdf0e10cSrcweir    chomp($line);
2038cdf0e10cSrcweir    return $line;
2039cdf0e10cSrcweir}
2040cdf0e10cSrcweir
2041cdf0e10cSrcweirsub hg_pull
2042cdf0e10cSrcweir{
2043cdf0e10cSrcweir    my $repository  = shift;
2044cdf0e10cSrcweir    my $remote = shift;
2045cdf0e10cSrcweir
2046cdf0e10cSrcweir    if ( $debug ) {
2047cdf0e10cSrcweir        print STDERR "CWS-DEBUG: ... hg pull: 'repository', remote: '$remote'\n";
2048cdf0e10cSrcweir    }
2049cdf0e10cSrcweir
2050cdf0e10cSrcweir    my @result = execute_hg_command(0, 'pull', "--cwd $repository", $remote);
2051cdf0e10cSrcweir    my $line = $result[0];
2052cdf0e10cSrcweir    if ($line =~ /abort: /) {
2053cdf0e10cSrcweir        return undef;
2054cdf0e10cSrcweir    }
2055cdf0e10cSrcweir}
2056cdf0e10cSrcweir
2057cdf0e10cSrcweirsub hg_update
2058cdf0e10cSrcweir{
2059cdf0e10cSrcweir    my $repository  = shift;
2060cdf0e10cSrcweir
2061cdf0e10cSrcweir    if ( $debug ) {
2062cdf0e10cSrcweir        print STDERR "CWS-DEBUG: ... hg update: 'repository'\n";
2063cdf0e10cSrcweir    }
2064cdf0e10cSrcweir
2065cdf0e10cSrcweir    my @result = execute_hg_command(1, 'update', "--cwd $repository");
2066cdf0e10cSrcweir    return @result;
2067cdf0e10cSrcweir}
2068cdf0e10cSrcweir
2069cdf0e10cSrcweirsub hg_show
2070cdf0e10cSrcweir{
2071cdf0e10cSrcweir    if ( $debug ) {
2072cdf0e10cSrcweir        print STDERR "CWS-DEBUG: ... hg show\n";
2073cdf0e10cSrcweir    }
2074cdf0e10cSrcweir    my $result = execute_hg_command(0, 'show', '');
2075cdf0e10cSrcweir    return $result;
2076cdf0e10cSrcweir}
2077cdf0e10cSrcweir
2078cdf0e10cSrcweirsub execute_hg_command
2079cdf0e10cSrcweir{
2080cdf0e10cSrcweir    my $terminate_on_rc = shift;
2081cdf0e10cSrcweir    my $command = shift;
2082cdf0e10cSrcweir    my $options = shift;
2083cdf0e10cSrcweir    my @args = @_;
2084cdf0e10cSrcweir
2085cdf0e10cSrcweir    my $args_str = join(" ", @args);
2086cdf0e10cSrcweir
2087cdf0e10cSrcweir    # we can only parse english strings, hopefully a C locale is available everywhere
2088cdf0e10cSrcweir    $ENV{LC_ALL}='C';
2089cdf0e10cSrcweir    $command = "hg $command $options $args_str";
2090cdf0e10cSrcweir
2091cdf0e10cSrcweir    if ( $debug ) {
2092cdf0e10cSrcweir        print STDERR "CWS-DEBUG: ... execute command line: '$command'\n";
2093cdf0e10cSrcweir    }
2094cdf0e10cSrcweir
2095cdf0e10cSrcweir    my @result;
2096cdf0e10cSrcweir    open(OUTPUT, "$command 2>&1 |") or print_error("Can't execute mercurial command line client", 98);
2097cdf0e10cSrcweir    while (<OUTPUT>) {
2098cdf0e10cSrcweir        push(@result, $_);
2099cdf0e10cSrcweir    }
2100cdf0e10cSrcweir    close(OUTPUT);
2101cdf0e10cSrcweir
2102cdf0e10cSrcweir    my $rc = $? >> 8;
2103cdf0e10cSrcweir
2104cdf0e10cSrcweir    if ( $rc > 0 && $terminate_on_rc) {
2105cdf0e10cSrcweir        print STDERR @result;
2106cdf0e10cSrcweir        print_error("The mercurial command line client failed with exit status '$rc'", 99);
2107cdf0e10cSrcweir    }
2108cdf0e10cSrcweir    return wantarray ? @result : \@result;
2109cdf0e10cSrcweir}
2110cdf0e10cSrcweir
2111cdf0e10cSrcweir
2112cdf0e10cSrcweir# vim: set ts=4 shiftwidth=4 expandtab syntax=perl:
2113