diff options
author | Kurt Zenker <kz@openoffice.org> | 2010-08-11 14:03:45 +0200 |
---|---|---|
committer | Kurt Zenker <kz@openoffice.org> | 2010-08-11 14:03:45 +0200 |
commit | 64a49647b30bb69f3cbac99b80dde300d69b8d1f (patch) | |
tree | be1687fac318fd6748e48bbdf055318cb94b04f9 /solenv | |
parent | f07651b1409375d2e75e283e4ee295ee8fcad880 (diff) | |
parent | ee7fa0323dc78d994a79f41dfc5d5f41bebdc5f7 (diff) |
CWS-TOOLING: integrate CWS vgbugs10_OOO330
Diffstat (limited to 'solenv')
-rwxr-xr-x | solenv/bin/build.pl | 221 | ||||
-rw-r--r-- | solenv/bin/modules/RepositoryHelper.pm | 205 | ||||
-rwxr-xr-x[-rw-r--r--] | solenv/bin/modules/SourceConfig.pm | 146 |
3 files changed, 423 insertions, 149 deletions
diff --git a/solenv/bin/build.pl b/solenv/bin/build.pl index 66afeec6e2c7..d7bc7df26442 100755 --- a/solenv/bin/build.pl +++ b/solenv/bin/build.pl @@ -45,6 +45,7 @@ use lib ("$ENV{SOLARENV}/bin/modules"); use SourceConfig; + use RepositoryHelper; my $in_so_env = 0; if (defined $ENV{COMMON_ENV_TOOLS}) { @@ -139,6 +140,8 @@ $html = ''; @ignored_errors = (); %incompatibles = (); + %skip_modules = (); + %exclude_branches = (); $only_platform = ''; # the only platform to prepare $only_common = ''; # the only common output tree to delete when preparing %build_modes = (); @@ -167,8 +170,8 @@ $html_last_updated = 0; %jobs_hash = (); $html_path = undef; - $html_file = CorrectPath($ENV{SOLARSRC} . '/' . $ENV{INPATH}. '.build.html'); $build_finished = 0; + $html_file = ''; %had_error = (); # hack for misteriuos windows problems - try run dmake 2 times if first time there was an error $mkout = CorrectPath("$ENV{SOLARENV}/bin/mkout.pl"); %weights_hash = (); # hash contains info about how many modules are dependent from one module @@ -209,7 +212,6 @@ get_options(); - $html_file = CorrectPath($html_path . '/' . $ENV{INPATH}. '.build.html') if (defined $html_path); # my $temp_html_file = CorrectPath($tmp_dir. '/' . $ENV{INPATH}. '.build.html'); get_build_modes(); %deliver_env = (); @@ -225,12 +227,26 @@ $deliver_env{'OUTPATH'}++; $deliver_env{'L10N_framework'}++; }; + $StandDir = get_stand_dir(); # This also sets $initial_module + $source_config = SourceConfig -> new($StandDir); + + if ($html) { + if (defined $html_path) { + $html_file = CorrectPath($html_path . '/' . $ENV{INPATH}. '.build.html'); + } else { + my $log_directory = Cwd::realpath(CorrectPath($StandDir . '/../log')); + if ((!-d $log_directory) && (!mkdir($log_directory))) { + print_error("Cannot create $log_directory for writing html file\n"); + }; + $html_file = $log_directory . '/' . $ENV{INPATH}. '.build.html'; + print "\nPath to html status page: $html_file\n"; + }; + }; if ($generate_config && ($clear_config || (scalar keys %remove_from_config)||(scalar keys %add_to_config))) { generate_config_file(); exit 0; } - $StandDir = get_stand_dir(); # This also sets $initial_module get_module_and_buildlist_paths(); provide_consistency() if (defined $ENV{CWS_WORK_STAMP} && defined($ENV{COMMON_ENV_TOOLS})); @@ -342,7 +358,6 @@ sub rename_file { }; sub generate_config_file { - my $source_config = SourceConfig->new(); $source_config->add_active_modules([keys %add_to_config], 1) if (scalar %add_to_config); $source_config->remove_activated_modules([keys %remove_from_config], 1) if (scalar %remove_from_config); $source_config->remove_all_activated_modules() if ($clear_config); @@ -556,23 +571,36 @@ sub get_build_list_path { # Get dependencies hash of the current and all parent projects # sub get_parent_deps { - my (%parents_deps_hash, $module, $parent); my $prj_dir = shift; my $deps_hash = shift; - my @unresolved_parents = get_parents_array($prj_dir); - $parents_deps_hash{$_}++ foreach (@unresolved_parents); - $$deps_hash{$prj_dir} = \%parents_deps_hash; - while ($module = pop(@unresolved_parents)) { + my @unresolved_parents = ($prj_dir); + my %skipped_branches = (); + while (my $module = pop(@unresolved_parents)) { + next if (defined $$deps_hash{$module}); my %parents_deps_hash = (); - $parents_deps_hash{$_}++ foreach (get_parents_array($module)); + foreach (get_parents_array($module)) { + if (defined $exclude_branches{$_}) { + $skipped_branches{$_}++; + next; + }; + $parents_deps_hash{$_}++; + } $$deps_hash{$module} = \%parents_deps_hash; foreach $Parent (keys %parents_deps_hash) { - if (!defined($$deps_hash{$Parent})) { + if (!defined($$deps_hash{$Parent}) && (!defined $exclude_branches{$module})) { push (@unresolved_parents, $Parent); }; }; }; check_deps_hash($deps_hash); + foreach (keys %skipped_branches) { + print $echo . "Skipping module's $_ branch\n"; + delete $exclude_branches{$_}; + }; + my @missing_branches = keys %exclude_branches; + if (scalar @missing_branches) { + print_error("For $prj_dir branche(s): \"@missing_branches\" not found\n"); + }; }; sub store_weights { @@ -605,18 +633,18 @@ sub expand_dependencies { }; # -# This procedure fills out the %reversed_dependencies hash, -# the hash contaninig the info about modules "waiting" for the module +# This procedure fills the second hash with reversed dependencies, +# ie, with info about modules "waiting" for the module # sub reverse_dependensies { - my $deps_hash = shift; + my ($deps_hash, $reversed) = @_; foreach my $module (keys %$deps_hash) { foreach (keys %{$$deps_hash{$module}}) { - if (defined $reversed_dependencies{$_}) { - ${$reversed_dependencies{$_}}{$module}++ + if (defined $$reversed{$_}) { + ${$$reversed{$_}}{$module}++ } else { my %single_module_dep_hash = ($module => 1); - $reversed_dependencies{$_} = \%single_module_dep_hash; + $$reversed{$_} = \%single_module_dep_hash; }; }; }; @@ -635,8 +663,12 @@ sub build_all { }; modules_classify(keys %global_deps_hash); expand_dependencies (\%global_deps_hash); -# prepare_build_from(\%global_deps_hash) if (scalar keys %incompatibles); - prepare_incompatible_build(\%global_deps_hash) if ($incompatible); + prepare_incompatible_build(\%global_deps_hash) if ($incompatible && (!$build_from_with_branches)); + if ($build_from_with_branches) { + my %reversed_full_deps_hash = (); + reverse_dependensies(\%global_deps_hash, \%reversed_full_deps_hash); + prepare_build_from_with_branches(\%global_deps_hash, \%reversed_full_deps_hash); + } if ($build_all_cont || $build_since) { prepare_build_all_cont(\%global_deps_hash); }; @@ -653,13 +685,13 @@ sub build_all { print_error("There are modules:\n@missing_modules\n\nthat should be built, but they are not activated. Please, verify your $source_config_file.\n"); }; }; - foreach my $module (%dead_parents) { + foreach my $module (keys %dead_parents, keys %skip_modules) { remove_from_dependencies($module, \%global_deps_hash); delete ($global_deps_hash{$module}) if (defined $global_deps_hash{$module}); }; store_weights(\%global_deps_hash); backup_deps_hash(\%global_deps_hash, \%global_deps_hash_backup); - reverse_dependensies(\%global_deps_hash_backup); + reverse_dependensies(\%global_deps_hash_backup, \%reversed_dependencies); $modules_number = scalar keys %global_deps_hash; initialize_html_info($_) foreach (keys %global_deps_hash); if ($processes_to_run) { @@ -1100,6 +1132,7 @@ sub get_commands { while ($arg = pop(@dmake_args)) { $dmake .= ' '.$arg; }; + $dmake .= ' verbose=true' if ($html); }; # @@ -1110,34 +1143,44 @@ sub get_stand_dir { $ENV{mk_tmp} = ''; die "No environment set\n"; }; - my $StandDir; - if ( defined $ENV{PWD} ) { - $StandDir = $ENV{PWD}; - } elsif (defined $ENV{_cwd}) { - $StandDir = $ENV{_cwd}; - } else { - $StandDir = cwd(); - }; - my $previous_dir = ''; - do { - foreach (@possible_build_lists) {# ('build.lst', 'build.xlist'); - if (-e $StandDir . '/prj/'.$_) { - $initial_module = File::Basename::basename($StandDir); - $build_list_paths{$initial_module} =$StandDir . '/prj/'.$_; - $StandDir = File::Basename::dirname($StandDir); - $module_paths{$initial_module} = $StandDir . "/$initial_module"; + my $repository_helper = RepositoryHelper->new(); + my $StandDir = $repository_helper->get_repository_root(); + my $initial_dir = $repository_helper->get_initial_directory(); + if ($StandDir eq $initial_dir) { + print_error('Found no project to build'); + }; + $initial_module = substr($initial_dir, length($StandDir) + 1); + if ($initial_module =~ /\\|\//) { + $initial_module = File::Basename::dirname($initial_module); + }; + $module_paths{$initial_module} = $StandDir . "/$initial_module"; +# $build_list_paths{$initial_module} =$StandDir . '/prj/'.$_; +# if ( defined $ENV{PWD} ) { +# $StandDir = $ENV{PWD}; +# } elsif (defined $ENV{_cwd}) { +# $StandDir = $ENV{_cwd}; +# } else { +# $StandDir = cwd(); +# }; +# my $previous_dir = ''; +# do { +# foreach (@possible_build_lists) {# ('build.lst', 'build.xlist'); +# if (-e $StandDir . '/prj/'.$_) { +# $initial_module = File::Basename::basename($StandDir); +# $build_list_paths{$initial_module} =$StandDir . '/prj/'.$_; +# $StandDir = File::Basename::dirname($StandDir); +# $module_paths{$initial_module} = $StandDir . "/$initial_module"; return $StandDir; - } elsif ($StandDir eq $previous_dir) { - $ENV{mk_tmp} = ''; - print_error('Found no project to build'); - }; - }; - $previous_dir = $StandDir; - $StandDir = File::Basename::dirname(Cwd::realpath($StandDir)); - print_error('Found no project to build') if (!$StandDir); - } -# while (chdir '..'); - while (chdir "$StandDir"); +# } elsif ($StandDir eq $previous_dir) { +# $ENV{mk_tmp} = ''; +# print_error('Found no project to build'); +# }; +# }; +# $previous_dir = $StandDir; +# $StandDir = File::Basename::dirname(Cwd::realpath($StandDir)); +# print_error('Found no project to build') if (!$StandDir); +# } +# while (chdir "$StandDir"); }; # @@ -1236,7 +1279,7 @@ sub check_deps_hash { $jobs_hash{$key} = { SHORT_NAME => $string, BUILD_NUMBER => $build_number, STATUS => 'waiting', - LOG_PATH => $module . "/$ENV{INPATH}/misc/logs/$log_name", + LOG_PATH => '../' . $source_config->get_module_repository($module) . "/$module/$ENV{INPATH}/misc/logs/$log_name", LONG_LOG_PATH => CorrectPath($module_paths{$module} . "/$ENV{INPATH}/misc/logs/$log_name"), START_TIME => 0, FINISH_TIME => 0, @@ -1392,7 +1435,7 @@ sub print_error { sub usage { print STDERR "\nbuild\n"; - print STDERR "Syntax: build [--all|-a[:prj_name]]|[--from|-f prj_name1[:prj_name2] [prj_name3 [...]]]|[--since|-c prj_name] [--with_branches|-b]|[--prepare|-p][:platform] [--deliver|-d [--dlv_switch deliver_switch]]] [-P processes|--server [--setenvstring \"string\"] [--client_timeout MIN] [--port port1[:port2:...:portN]]] [--show|-s] [--help|-h] [--file|-F] [--ignore|-i] [--version|-V] [--mode|-m OOo[,SO[,EXT]] [--html [--html_path html_file_path] [--dontgraboutput]] [--pre_job=pre_job_sring] [--job=job_string|-j] [--post_job=post_job_sring] [--stoponerror] [--genconf [--removeall|--clear|--remove|--add [module1,module2[,...,moduleN]]]] [--interactive]\n"; + print STDERR "Syntax: build [--all|-a[:prj_name]]|[--from|-f prj_name1[:prj_name2] [prj_name3 [...]]]|[--since|-c prj_name] [--with_branches prj_name1[:prj_name2] [--skip prj_name1[:prj_name2] [prj_name3 [...]] [prj_name3 [...]|-b]|[--prepare|-p][:platform] [--deliver|-d [--dlv_switch deliver_switch]]] [-P processes|--server [--setenvstring \"string\"] [--client_timeout MIN] [--port port1[:port2:...:portN]]] [--show|-s] [--help|-h] [--file|-F] [--ignore|-i] [--version|-V] [--mode|-m OOo[,SO[,EXT]] [--html [--html_path html_file_path] [--dontgraboutput]] [--pre_job=pre_job_sring] [--job=job_string|-j] [--post_job=post_job_sring] [--stoponerror] [--genconf [--removeall|--clear|--remove|--add [module1,module2[,...,moduleN]]]] [--exclude_branch_from prj_name1[:prj_name2] [prj_name3 [...]]] [--interactive]\n"; print STDERR "Example1: build --from sfx2\n"; print STDERR " - build all projects dependent from sfx2, starting with sfx2, finishing with the current module\n"; print STDERR "Example2: build --all:sfx2\n"; @@ -1405,9 +1448,11 @@ sub usage { print STDERR "\nSwitches:\n"; print STDERR " --all - build all projects from very beginning till current one\n"; print STDERR " --from - build all projects dependent from the specified (including it) till current one\n"; + print STDERR " --exclude_branch_from - exclude module(s) and its branch from the build\n"; print STDERR " --mode OOo - build only projects needed for OpenOffice.org\n"; print STDERR " --prepare - clear all projects for incompatible build from prj_name till current one [for platform] (cws version)\n"; - print STDERR " --with_branches- build all projects in neighbour branches and current branch starting from actual project\n"; + print STDERR " --with_branches- the same as \"--from\" but with build all projects in neighbour branches\n"; + print STDERR " --skip - do not build certain module(s)\n"; print STDERR " --since - build all projects beginning from the specified till current one (the same as \"--all:prj_name\", but skipping prj_name)\n"; print STDERR " --checkmodules - check if all required parent projects are availlable\n"; print STDERR " --show - show what is going to be built\n"; @@ -1462,19 +1507,25 @@ sub get_options { $arg =~ /^--dlv_switch$/ and $dlv_switch = shift @ARGV and next; $arg =~ /^--file$/ and $cmd_file = shift @ARGV and next; $arg =~ /^-F$/ and $cmd_file = shift @ARGV and next; + $arg =~ /^--skip$/ and get_modules_passed(\%skip_modules) and next; - $arg =~ /^--with_branches$/ and $build_all_parents = 1 - and $build_from_with_branches = shift @ARGV and next; - $arg =~ /^-b$/ and $build_all_parents = 1 - and $build_from_with_branches = shift @ARGV and next; - + if ($arg =~ /^--with_branches$/ || $arg =~ /^-b$/) { + $build_from_with_branches = 1; + $build_all_parents = 1; + get_modules_passed(\%incompatibles); + next; + }; $arg =~ /^--all:(\S+)$/ and $build_all_parents = 1 and $build_all_cont = $1 and next; $arg =~ /^-a:(\S+)$/ and $build_all_parents = 1 and $build_all_cont = $1 and next; if ($arg =~ /^--from$/ || $arg =~ /^-f$/) { $build_all_parents = 1; - get_incomp_projects(); + get_modules_passed(\%incompatibles); + next; + }; + if ($arg =~ /^--exclude_branch_from$/) { + get_modules_passed(\%exclude_branches); next; }; $arg =~ /^--prepare$/ and $prepare = 1 and next; @@ -1527,8 +1578,12 @@ sub get_options { print_error("\"--html_path\" switch is used only with \"--html\"") if ($html_path); print_error("\"--dontgraboutput\" switch is used only with \"--html\"") if ($dont_grab_output); }; + if ((scalar keys %exclude_branches) && !$build_all_parents) { + print_error("\"--exclude_branch_from\" is not applicable for one module builds!!"); + }; $grab_output = 0 if ($dont_grab_output); print_error('Switches --with_branches and --all collision') if ($build_from_with_branches && $build_all_cont); + print_error('Switch --skip is for building multiple modules only!!') if ((scalar keys %skip_modules) && (!$build_all_parents)); # print_error('Please prepare the workspace on one of UNIX platforms') if ($prepare && ($ENV{GUI} ne 'UNX')); print_error('Switches --with_branches and --since collision') if ($build_from_with_branches && $build_since); if ($show) { @@ -1593,7 +1648,6 @@ sub get_options { sub get_module_and_buildlist_paths { if ($build_all_parents || $checkparents) { - my $source_config = SourceConfig -> new($StandDir); $source_config_file = $source_config->get_config_file_path(); $active_modules{$_}++ foreach ($source_config->get_active_modules()); my %active_modules_copy = %active_modules; @@ -1652,7 +1706,13 @@ sub cancel_build { $message_part .= "--from @broken_modules_names\n"; }; } else { - $message_part .= "--all:@broken_modules_names\n"; + if ($processes_to_run) { + $message_part .= "--from "; + } else { + $message_part .= "--all:"; + }; + $message_part .= "@broken_modules_names\n"; + }; if ($broken_modules_number && $build_all_parents) { print "\n"; @@ -2109,12 +2169,12 @@ sub modules_classify { # # This procedure provides consistency for cws -# and optimized build (ie in case of -with_branches, -all:prj_name +# and optimized build (ie in case of --with_branches, -all:prj_name # and -since switches) # sub provide_consistency { check_dir(); - foreach $var_ref (\$build_from_with_branches, \$build_all_cont, \$build_since) { + foreach $var_ref (\$build_all_cont, \$build_since) { if ($$var_ref) { return if (defined $module_paths{$$var_ref}); print_error("Cannot find module '$$var_ref'", 9); @@ -2257,6 +2317,20 @@ sub fix_permissions { chmod '0664', $file; }; +sub prepare_build_from_with_branches { + ($full_deps_hash, $reversed_full_deps_hash) = @_; + foreach my $prerequisite (keys %$full_deps_hash) { + foreach my $dependent_module (keys %incompatibles) { + if (defined ${$$reversed_full_deps_hash{$prerequisite}}{$dependent_module}) { + remove_from_dependencies($prerequisite, $full_deps_hash); + delete $$full_deps_hash{$prerequisite}; +# print "Removed $prerequisite\n"; + last; + }; + }; + }; +}; + # # Removes projects which it is not necessary to build # in incompatible build @@ -2268,7 +2342,6 @@ sub prepare_incompatible_build { if (!defined $$deps_hash{$module}) { print_error("The module $initial_module is independent from $module\n"); } - delete $incompatibles{$module}; $incompatibles{$module} = $$deps_hash{$module}; delete $$deps_hash{$module}; } @@ -2286,8 +2359,8 @@ sub prepare_incompatible_build { @modules_built = keys %$deps_hash; %add_to_config = %$deps_hash; if ($prepare) { - if ((!defined $ENV{UPDATER}) || (defined $ENV{CWS_WORK_STAMP})) { - SourceConfig->new()->add_active_modules([keys %add_to_config], 0); + if ((!(defined $ENV{UPDATER} && (!defined $ENV{CWS_WORK_STAMP}))) || (defined $ENV{CWS_WORK_STAMP})) { + $source_config->add_active_modules([keys %add_to_config], 0); } clear_delivered(); } @@ -2332,21 +2405,6 @@ sub prepare_incompatible_build { # # Removes projects which it is not necessary to build -# with -with_branches switch -# -#sub prepare_build_from { -# my ($prj, $deps_hash); -# $deps_hash = shift; -# my %from_deps_hash = (); # hash of dependencies of the -from project -# get_parent_deps($build_from_with_branches, \%from_deps_hash); -# foreach $prj (keys %from_deps_hash) { -# delete $$deps_hash{$prj}; -# remove_from_dependencies($prj, $deps_hash); -# }; -#}; - -# -# Removes projects which it is not necessary to build # with --all:prj_name or --since switch # sub prepare_build_all_cont { @@ -2412,7 +2470,8 @@ sub get_list_of_modules { # }; }; -sub get_incomp_projects { +sub get_modules_passed { + my $hash_ref = shift; my $option = ''; while ($option = shift @ARGV) { if ($option =~ /^-+/) { @@ -2424,7 +2483,7 @@ sub get_incomp_projects { print_error("\'--from\' switch collision") if ($build_all_cont); $build_all_cont = $'; }; - $incompatibles{$option}++; + $$hash_ref{$option}++; }; }; }; diff --git a/solenv/bin/modules/RepositoryHelper.pm b/solenv/bin/modules/RepositoryHelper.pm new file mode 100644 index 000000000000..7677376be70e --- /dev/null +++ b/solenv/bin/modules/RepositoryHelper.pm @@ -0,0 +1,205 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +#************************************************************************* +# +# RepositoryHelper - Perl for working with repositories and underlying SCM +# +# usage: see below +# +#************************************************************************* + +package RepositoryHelper; + +use strict; + + +use Carp; +use Cwd qw (cwd); +use File::Basename; +#use File::Temp qw(tmpnam); + +my $debug = 0; + +##### profiling ##### + +##### ctor ##### + +sub new { + my $proto = shift; + my $class = ref($proto) || $proto; + my $initial_directory = shift; + if ($initial_directory) { + $initial_directory = Cwd::realpath($initial_directory); + } else { + if ( defined $ENV{PWD} ) { + $initial_directory = $ENV{PWD}; + } elsif (defined $ENV{_cwd}) { + $initial_directory = $ENV{_cwd}; + } else { + $initial_directory = cwd(); + }; + }; + my $self = {}; + $self->{INITIAL_DIRECTORY} = $initial_directory; + $self->{REPOSITORY_ROOT} = undef; + $self->{REPOSITORY_NAME} = undef; + $self->{SCM_NAME} = undef; + detect_repository($self); + bless($self, $class); + return $self; +} + +##### methods ##### +sub get_repository_root +{ + my $self = shift; + return $self->{REPOSITORY_ROOT}; +} + +sub get_initial_directory +{ + my $self = shift; + return $self->{INITIAL_DIRECTORY}; +} + +sub get_scm_name +{ + my $self = shift; + return$self->{SCM_NAME}; +} + +##### private methods ##### +sub search_for_hg { + my $self = shift; + my $hg_root; + my $scm_name = 'hg'; + if (open(COMMAND, "$scm_name root 2>&1 |")) { + foreach (<COMMAND>) { + next if (/^Not trusting file/); + chomp; + $hg_root = $_; + last; + }; + close COMMAND; + chomp $hg_root; + if ($hg_root !~ /There is no Mercurial repository here/) { + $self->{REPOSITORY_ROOT} = $hg_root; + $self->{SCM_NAME} = $scm_name; + return 1; + }; + }; + return 0; +}; + +sub search_via_build_lst { + my $self = shift; + my @possible_build_lists = ('build.lst', 'build.xlist'); # build lists names + my $previous_dir = ''; + my $rep_root_candidate = $self->{INITIAL_DIRECTORY}; + do { + foreach (@possible_build_lists) {# ('build.lst', 'build.xlist'); + if (-e $rep_root_candidate . '/prj/'.$_) { + $self->{REPOSITORY_ROOT} = File::Basename::dirname($rep_root_candidate); + return 1; + } elsif ($rep_root_candidate eq $previous_dir) { + return 0; + }; + }; + $previous_dir = $rep_root_candidate; + $rep_root_candidate = File::Basename::dirname(Cwd::realpath($rep_root_candidate)); + return 0 if (!$rep_root_candidate); + } + while (chdir "$rep_root_candidate"); +}; + +sub detect_repository { + my $self = shift; + return if (search_via_build_lst($self)); + chdir $self->{INITIAL_DIRECTORY}; + return if (search_for_hg($self)); + croak('Cannot determine source directory/repository for ' . $self->{INITIAL_DIRECTORY}); +}; + +##### finish ##### + +1; # needed by use or require + +__END__ + +=head1 NAME + +RepositoryHelper - Perl module for working with repositories and underlying SCM + +=head1 SYNOPSIS + + # example that will analyze sources and return the source root directory + + use RepositoryHelper; + + # Create a new instance: + $a = RepositoryHelper->new(); + + # Get repositories for the actual workspace: + $a->get_repository_root(); + + +=head1 DESCRIPTION + +RepositoryHelper is a perlPerl module for working with repositories and underlying SCM +in the database. + +Methods: + +RepositoryHelper::new() + +Creates a new instance of RepositoryHelper. Can be initialized by: some path which likely to belong to a repository, default - empty, the current dir will be taken. + +RepositoryHelper::get_repository_root() + +Returns the repository root, retrieved by SCM methods or on educated guess... + +RepositoryHelper::get_initial_directory() + +Returns full path to the initialistion directory. + +=head2 EXPORT + +RepositoryHelper::new() +RepositoryHelper::get_repository_root() +RepositoryHelper::get_scm_name() +RepositoryHelper::get_initial_directory() + +=head1 AUTHOR + +Vladimir Glazunov, vg@openoffice.org + +=head1 SEE ALSO + +perl(1). + +=cut diff --git a/solenv/bin/modules/SourceConfig.pm b/solenv/bin/modules/SourceConfig.pm index 9379b7764d0a..dfaa797d8f48 100644..100755 --- a/solenv/bin/modules/SourceConfig.pm +++ b/solenv/bin/modules/SourceConfig.pm @@ -38,10 +38,11 @@ package SourceConfig; use strict; use constant SOURCE_CONFIG_FILE_NAME => 'source_config'; -use constant SOURCE_CONFIG_VERSION => 2; +use constant SOURCE_CONFIG_VERSION => 3; use Carp; use Cwd; +use RepositoryHelper; use File::Basename; use File::Temp qw(tmpnam); @@ -75,8 +76,9 @@ sub new { $source_root .= '/..'; } } else { - $source_root = Cwd::realpath($ENV{SOURCE_ROOT_DIR}); + $source_root = $ENV{SOURCE_ROOT_DIR}; }; + $source_root = Cwd::realpath($source_root); $self->{SOURCE_ROOT} = $source_root; $self->{DEBUG} = 0; $self->{VERBOSE} = 0; @@ -94,14 +96,16 @@ sub new { $self->{WARNINGS} = []; $self->{REPORT_MESSAGES} = []; $self->{CONFIG_FILE_CONTENT} = []; - $self->{DEFAULT_REPOSITORY} = undef; if (defined $self->{USER_SOURCE_ROOT}) { ${$self->{REPOSITORIES}}{File::Basename::basename($self->{USER_SOURCE_ROOT})} = $self->{USER_SOURCE_ROOT}; - $self->{DEFAULT_REPOSITORY} = File::Basename::basename($self->{USER_SOURCE_ROOT}); }; $self->{SOURCE_CONFIG_FILE} = get_config_file($self->{SOURCE_ROOT}) if (!defined $self->{SOURCE_CONFIG_FILE}); $self->{SOURCE_CONFIG_DEFAULT} = $self->{SOURCE_ROOT} .'/'.SOURCE_CONFIG_FILE_NAME; + if (defined $self->{USER_SOURCE_ROOT}) { + ${$self->{REPOSITORIES}}{File::Basename::basename($self->{USER_SOURCE_ROOT})} = $self->{USER_SOURCE_ROOT}; + }; read_config_file($self); + get_module_paths($self); bless($self, $class); return $self; } @@ -118,6 +122,19 @@ sub get_repositories return sort keys %{$self->{REPOSITORIES}}; } +sub add_repository +{ + my $self = shift; + my $new_rep_path = shift; + $new_rep_path = Cwd::realpath($new_rep_path); + my $new_rep_name = File::Basename::basename($new_rep_path); + if (defined ${$self->{REPOSITORIES}}{$new_rep_name}) { + croak("Repository $new_rep_name is already defined!!"); + }; + ${$self->{REPOSITORIES}}{$new_rep_name} = $new_rep_path; + $self -> get_repository_module_paths($new_rep_name); +} + sub get_config_file_default_path { my $self = shift; return $self->{SOURCE_CONFIG_DEFAULT}; @@ -131,7 +148,6 @@ sub get_config_file_path { sub get_module_repository { my $self = shift; my $module = shift; - $self -> get_module_paths() if (!scalar keys %{$self->{MODULE_PATHS}}); if (defined ${$self->{MODULE_REPOSITORY}}{$module}) { return ${$self->{MODULE_REPOSITORY}}{$module}; } else { @@ -143,7 +159,6 @@ sub get_module_repository { sub get_module_path { my $self = shift; my $module = shift; - $self -> get_module_paths() if (!scalar keys %{$self->{MODULE_PATHS}}); if (defined ${$self->{MODULE_PATHS}}{$module}) { return ${$self->{MODULE_PATHS}}{$module}; } else { @@ -155,10 +170,17 @@ sub get_module_path { sub get_module_build_list { my $self = shift; my $module = shift; - $self -> get_buildlist_paths() if (!scalar keys %{$self->{MODULE_BUILD_LIST_PATHS}}); if (defined ${$self->{MODULE_BUILD_LIST_PATHS}}{$module}) { return ${$self->{MODULE_BUILD_LIST_PATHS}}{$module}; } else { + my @possible_build_lists = ('build.lst', 'build.xlist'); # build lists names + foreach (@possible_build_lists) { + my $possible_path = ${$self->{MODULE_PATHS}}{$module} . "/prj/$_"; + if (-e $possible_path) { + ${$self->{MODULE_BUILD_LIST_PATHS}}{$module} = $possible_path; + return $possible_path; + }; + }; Carp::cluck("No build list in module $module found!!\n") if ($self->{DEBUG}); return undef; }; @@ -168,7 +190,6 @@ sub get_all_modules { my $self = shift; my $module = shift; - $self -> get_module_paths() if (!scalar keys %{$self->{MODULE_PATHS}}); return sort keys %{$self->{MODULE_PATHS}}; }; @@ -178,7 +199,6 @@ sub get_active_modules if (scalar keys %{$self->{ACTIVATED_MODULES}}) { return sort keys %{$self->{ACTIVATED_MODULES}}; } - $self -> get_module_paths() if (!scalar keys %{$self->{MODULE_PATHS}}); return sort keys %{$self->{REAL_MODULES}}; } @@ -189,49 +209,42 @@ sub is_active if (scalar keys %{$self->{ACTIVATED_MODULES}}) { return exists ($self->{ACTIVATED_MODULES}{$module}); } - $self -> get_module_paths() if (!scalar keys %{$self->{MODULE_PATHS}}); return exists ($self->{REAL_MODULES}{$module}); } ##### private methods ##### -sub get_buildlist_paths { +sub get_repository_module_paths { my $self = shift; - $self -> get_module_paths() if (!scalar keys %{$self->{MODULE_PATHS}}); - my @possible_build_lists = ('build.lst', 'build.xlist'); # build lists names - foreach my $module (keys %{$self->{MODULE_PATHS}}) { - foreach (@possible_build_lists) { - my $possible_path = ${$self->{MODULE_PATHS}}{$module} . "/prj/$_"; - ${$self->{MODULE_BUILD_LIST_PATHS}}{$module} = $possible_path if (-e $possible_path); + my $repository = shift; + my $repository_path = ${$self->{REPOSITORIES}}{$repository}; + if (opendir DIRHANDLE, $repository_path) { + foreach my $module (readdir(DIRHANDLE)) { + next if (($module =~ /^\.+/) || (!-d "$repository_path/$module")); + my $module_entry = $module; + if (($module !~ s/\.lnk$//) && ($module !~ s/\.link$//)) { + $self->{REAL_MODULES}{$module}++; + } + my $possible_path = "$repository_path/$module_entry"; + if (-d $possible_path) { + if (defined ${$self->{MODULE_PATHS}}{$module}) { + close DIRHANDLE; + croak("Ambiguous paths for module $module: $possible_path and " . ${$self->{MODULE_PATHS}}{$module}); + }; + ${$self->{MODULE_PATHS}}{$module} = $possible_path; + ${$self->{MODULE_REPOSITORY}}{$module} = $repository; + } }; + close DIRHANDLE; + } else { + croak("Cannot read $repository_path repository content"); }; }; sub get_module_paths { my $self = shift; foreach my $repository (keys %{$self->{REPOSITORIES}}) { - my $repository_path = ${$self->{REPOSITORIES}}{$repository}; - if (opendir DIRHANDLE, $repository_path) { - foreach my $module (readdir(DIRHANDLE)) { - next if (($module =~ /^\.+/) || (!-d "$repository_path/$module")); - my $module_entry = $module; - if (($module !~ s/\.lnk$//) && ($module !~ s/\.link$//)) { - $self->{REAL_MODULES}{$module}++; - } - my $possible_path = "$repository_path/$module_entry"; - if (-d $possible_path) { - if (defined ${$self->{MODULE_PATHS}}{$module}) { - close DIRHANDLE; - croak("Ambiguous paths for module $module: $possible_path and " . ${$self->{MODULE_PATHS}}{$module}); - }; - ${$self->{MODULE_PATHS}}{$module} = $possible_path; - ${$self->{MODULE_REPOSITORY}}{$module} = $repository; - } - }; - close DIRHANDLE; - } else { - croak("Cannot read $_ repository content"); - }; + get_repository_module_paths($self, $repository); }; my @false_actives = (); foreach (keys %{$self->{ACTIVATED_MODULES}}) { @@ -248,31 +261,21 @@ sub get_config_file { return ''; }; -sub get_hg_root { +# +# Fallback - fallback repository is based on RepositoryHelper educated guess +# +sub get_fallback_repository { my $self = shift; - return $self->{USER_SOURCE_ROOT} if (defined $self->{USER_SOURCE_ROOT}); - my $hg_root; - if (open(COMMAND, "hg root 2>&1 |")) { - foreach (<COMMAND>) { - next if (/^Not trusting file/); - chomp; - $hg_root = $_; - last; - }; - close COMMAND; - chomp $hg_root; - if ($hg_root !~ /There is no Mercurial repository here/) { - return $hg_root; - }; - }; - croak('Cannot open find source_config and/or determine hg root directory for ' . cwd()); + my $repository_root = RepositoryHelper->new()->get_repository_root(); + ${$self->{REPOSITORIES}}{File::Basename::basename($repository_root)} = $repository_root; }; sub read_config_file { my $self = shift; if (!$self->{SOURCE_CONFIG_FILE}) { - my $repository_root = get_hg_root($self); - ${$self->{REPOSITORIES}}{File::Basename::basename($repository_root)} = $repository_root; + if (!defined $self->{USER_SOURCE_ROOT}) { + get_fallback_repository($self); + }; return; }; my $repository_section = 0; @@ -304,11 +307,9 @@ sub read_config_file { my $repository_source_path = $self->{SOURCE_ROOT} . "/$1"; if (defined $ENV{UPDMINOREXT}) { $repository_source_path .= $ENV{UPDMINOREXT}; - }; - if ((defined $self->{DEFAULT_REPOSITORY}) && (${$self->{REPOSITORIES}}{$self->{DEFAULT_REPOSITORY}} eq $repository_source_path)) { - delete ${$self->{REPOSITORIES}}{$self->{DEFAULT_REPOSITORY}}; - $self->{DEFAULT_REPOSITORY} = undef; - + if (defined ${$self->{REPOSITORIES}}{$1.$ENV{UPDMINOREXT}}) { + delete ${$self->{REPOSITORIES}}{$1.$ENV{UPDMINOREXT}}; + }; }; ${$self->{REPOSITORIES}}{$1} = $repository_source_path; ${$self->{ACTIVATED_REPOSITORIES}}{$1}++; @@ -323,9 +324,7 @@ sub read_config_file { }; close SOURCE_CONFIG_FILE; if (!scalar keys %{$self->{REPOSITORIES}}) { - # Fallback - default repository is the directory where is our module... - my $hg_root = get_hg_root($self); - ${$self->{REPOSITORIES}}{File::Basename::basename($hg_root)} = $hg_root; + get_fallback_repository($self); }; } else { croak('Cannot open ' . $self->{SOURCE_CONFIG_FILE} . 'for reading'); @@ -379,15 +378,18 @@ sub remove_activated_modules { sub add_active_repositories { my $self = shift; $self->{NEW_REPOSITORIES} = shift; - croak('Empty module list passed for adding to source_config') if (!scalar @{$self->{NEW_REPOSITORIES}}); + croak('Empty repository list passed for addition to source_config') if (!scalar @{$self->{NEW_REPOSITORIES}}); $self->{VERBOSE} = shift; + foreach (@{$self->{NEW_REPOSITORIES}}) { + $self->add_repository($_); + }; generate_config_file($self); }; sub add_active_modules { my $self = shift; $self->{NEW_MODULES} = shift; - croak('Empty module list passed for adding to source_config') if (!scalar @{$self->{NEW_MODULES}}); + croak('Empty module list passed for addition to source_config') if (!scalar @{$self->{NEW_MODULES}}); $self->{VERBOSE} = shift; generate_config_file($self); }; @@ -535,6 +537,8 @@ SourceConfig - Perl extension for parsing general info databases # Get repositories for the actual workspace: $a->get_repositories(); + # Add a repository new_repository for the actual workspace (via full path): + $a->add_repository(/DEV300/new_repository); =head1 DESCRIPTION @@ -559,6 +563,11 @@ SourceConfig::get_repositories() Returns sorted list of active repositories for the actual workspace +SourceConfig::add_repository(REPOSITORY_PATH) + +Adds a repository to the list of active repositories + + SourceConfig::get_active_modules() Returns a sorted list of active modules @@ -622,6 +631,7 @@ Removes all activated repositories from the source_config file SourceConfig::new() SourceConfig::get_version() SourceConfig::get_repositories() +SourceConfig::add_repository() SourceConfig::get_active_modules() SourceConfig::get_all_modules() SourceConfig::get_module_path($module) |