diff options
Diffstat (limited to 'src/mozclient/lib/MozClient/VCS.pm')
-rw-r--r-- | src/mozclient/lib/MozClient/VCS.pm | 351 |
1 files changed, 351 insertions, 0 deletions
diff --git a/src/mozclient/lib/MozClient/VCS.pm b/src/mozclient/lib/MozClient/VCS.pm new file mode 100644 index 0000000..c1ed7d5 --- /dev/null +++ b/src/mozclient/lib/MozClient/VCS.pm @@ -0,0 +1,351 @@ +# -*- mode: Perl -*- + +# Copyright (c) 2007-2008 Fabien Tassin <fta@sofaraway.org> +# Description: MozClient::VCS - Main class +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2, or (at +# your option) any later version. +# +# This program 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 +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +############################################################################ + +package MozClient::VCS; + +# This is the main class. It should not be used directly. VCS specific classes +# should be instantiated instead. They inherit from this main class and +# overwrite some methods according to VCS requirements. + +use Carp; +use strict; + +my $nobinonly = "nobinonly"; + +# List of dependencies +my $dependencies = { + 'cvs' => '/usr/bin/cvs', + 'mercurial' => '/usr/bin/hg', + 'quilt' => '/usr/bin/quilt', + 'wget' => '/usr/bin/wget', +}; + +############################################################################ + +sub new { + my $class = shift; + my $conf = shift; + my $opt = shift; + + my $self = {}; + + @{$self}{keys %$conf} = values %$conf; + + $self->{'want_branch'} = $$opt{'branch'}; + $self->{'want_listtags'} = 1 if $$opt{'list-tags'}; + $self->{'want_tag'} = $$opt{'tag'}; + $self->{'have_date'} = $$opt{'date'}; + $self->{'preserve_vcs'} = $$opt{'preserve-vcs'}; + $self->{'debug'} = $$opt{'debug'}; + + $self->{'want_branch'} = $$conf{'MOZCLIENT_BRANCH'} + if defined $$conf{'MOZCLIENT_BRANCH'} && !defined $self->{'want_branch'}; + + bless($self, $class); + $self; +} + +sub vcs { + my $self = shift; + + $self->{'MOZCLIENT_VCS'}; +} + +sub work_dir { + my $self = shift; + + $self->{'work-dir'} = shift if @_; + $self->{'work-dir'}; +} + +sub debug { + my $self = shift; + + $self->{'debug'} = shift if @_; + $self->{'debug'}; +} + +sub LOG { + my $self = shift; + my $str = shift; + + printf "LOG: $str\n", @_ if $self->debug; +} + +sub LOG2 { + my $self = shift; + my $str = shift; + + printf "$str\n", @_; +} + +sub check_dependencies { + my $self = shift; + + $self->LOG("MozClient::check_dependencies()"); + my $missing = []; + map { push @$missing, $_ unless -x $$dependencies{$_}} keys %$dependencies; + carp "# Error: missing dependencies. Please install " . + (join ", ", @$missing) . "\n" if $#$missing >= 0; + 1; +} + +sub cleanup_dir { + my $self = shift; + + if (-d $self->work_dir) { + $self->LOG("MozClient::cleanup_dir()"); + $self->run_system("rm -rf " . $self->work_dir); + } +} + +sub prepare_dir { + my $self = shift; + + $self->LOG("MozClient::prepare_dir()"); + $self->cleanup_dir(); + $self->mkdir($self->work_dir, 0755); +} + +sub run_system { + my $self = shift; + + $self->LOG2("\$ %s", @_); + my $cmd = sprintf "%s", @_; + my $args = &main::_split_args($cmd); + my $ret = system(@$args); + $ret == 0 || carp "Can't run '$cmd': error code $ret\n"; +} + +sub run_shell { + my $self = shift; + + $self->LOG2("\$ %s", @_); + my $cmd = shift; + return `$cmd`; +} + +sub chdir { + my $self = shift; + + $self->LOG2("\$ cd %s", @_); + my $dir = shift; + CORE::chdir($dir) || carp "Can't chdir($dir): $!\n"; +} + +sub unlink { + my $self = shift; + + $self->LOG2("\$ rm %s", @_); + my $file = shift; + + CORE::unlink($file) || carp "Can't unlink($file): $!\n"; +} + +sub mkdir { + my $self = shift; + my $dir = shift; + my $mode = shift; + $self->LOG2("\$ mkdir %s", $dir); + CORE::mkdir($dir, $mode) || carp "Can't mkdir($dir, $mode): $!\n"; +} + +sub want_list_tags { + my $self = shift; + + defined $self->{'want_listtags'} && $self->{'want_listtags'}; +} + +sub list_tags { + my $self = shift; + + $self->LOG("MozClient::list_tags()"); + die "Error: list_tags() not supported for " . $self->vcs; +} + +# Execute the command defined in MOZCLIENT_POSTCOCMD after the checkout +sub do_post_co_commands { + my $self = shift; + + $self->LOG("MozClient::do_post_co_commands()"); + $self->chdir($self->work_dir); + $self->run_shell($self->{'MOZCLIENT_POSTCOCMD'}); + $self->chdir(".."); +} + +sub get_client { + my $self = shift; + + $self->LOG("MozClient::get_client()"); + die "Can't MozClient::get_client() for " . $self->vcs; +} + +sub set_revdate { + my $self = shift; + + $self->LOG("MozClient::set_revdate()"); + die "Can't MozClient::set_revdate() for " . $self->vcs; +} + +sub convert_revdate { + my $self = shift; + + $self->LOG("MozClient::convert_revdate()"); + die "Can't MozClient::convert_revdate() for " . $self->vcs; +} + +sub do_dynamic_tag { + my $self = shift; + + $self->LOG("MozClient::do_dynamic_tag()"); + die "Error: do_dynamic_tag() not supported for " . $self->vcs; +} + +sub setup { + my $self = shift; + + $self->LOG("MozClient::setup()"); + $self->{'mozclient_date'} = ""; + $self->{'moz_co_tag'} = ""; + + if (!defined $self->{'want_tag'} && defined $self->{'MOZCLIENT_DYNTAG'}) { + $self->do_dynamic_tag(); + } + + if (defined $self->{'want_tag'}) { + # We want a tag, we can either let mozclient compute the version or + # specify our own (using -t TAG=version) + if (defined $self->{'have_date'}) { + warn "Warning: can't use -d and -t together. Ignoring -d"; + undef $self->{'have_date'}; + } + $self->{'want_tag'} =~ m/([^=]*)(=?)(.*)/; + $self->{'ltag'} = $1; + $self->{'dtag'} = $3; + $self->{'co_tag'} = "-r $1"; + $self->{'moz_co_tag'} = "MOZ_CO_TAG=$1"; + } + else { + # we don't want a specific tag, so go for a date and possibly a branch + if (!defined $self->{'have_date'}) { + chomp($self->{'have_date'} = `$self->{'MOZCLIENT_GETDATE'}`); + } + $self->{'mozclient_date'} = + '-D "' . $self->convert_revdate($self->{'have_date'}) . '"'; + $self->{'co_tag'} = ''; + $self->{'co_tag'} = + "-r " . $self->{'want_branch'} if defined $self->{'want_branch'}; + } +} + +sub checkout { + my $self = shift; + + $self->LOG("MozClient::checkout()"); + die "Can't MozClient::checkout() for " . $self->vcs; +} + +sub nobin_cleanup { + my $self = shift; + + $self->LOG("MozClient::nobin_cleanup()"); + + $self->chdir($self->work_dir . "/mozilla"); + my $cmd = sprintf "sh ../../%s > REMOVED+${nobinonly}.txt 2>&1", + $self->{'MOZCLIENT_EXCLUDE_SCRIPT'}; + $self->run_shell($cmd); + $self->unlink("REMOVED+${nobinonly}.txt") + unless -s "REMOVED+${nobinonly}.txt"; + $self->chdir("../.."); +} + +sub tar_exclude { + my $self = shift; + + $self->LOG("MozClient::tar_exclude()"); + # nothing + []; +} + +sub pack { + my $self = shift; + + $self->LOG("MozClient::pack()"); + + my $tar_exclude = ""; + unless ($self->{'preserve_vcs'}) { + my $dirs = $self->tar_exclude(); + + $tar_exclude = join " ", @$dirs; + } + + my $tversion; + if (defined $self->{'want_tag'} && + defined $self->{'dtag'} && length $self->{'dtag'} > 0) { + $tversion = $self->{'dtag'}; + } + else { + $self->chdir($self->work_dir); + chomp($tversion = `$self->{'MOZCLIENT_GETVERSION'}`); + $tversion .= '~' . $self->{'MOZCLIENT_VCS'} . $self->{'have_date'} + unless defined $self->{'want_tag'}; + $self->LOG2("\$ tversion=`" . $self->{'MOZCLIENT_GETVERSION'} . + "` # => $tversion"); + $self->chdir(".."); + } + my $version = $tversion; + $version .= "+${nobinonly}" + if -f $self->work_dir . "/mozilla/REMOVED+${nobinonly}.txt"; + my $cmd = sprintf "rm -rf %s/%s-%s", $self->work_dir, + $self->{'MOZCLIENT_APPNAME'}, $version; + $self->run_system($cmd); + if ($self->{'MOZCLIENT_EMBEDDED'} || $self->{'MOZCLIENT_WANTMOZDIR'}) { + my $dir = sprintf "%s/%s-%s", $self->work_dir, + $self->{'MOZCLIENT_APPNAME'}, $version; + $self->mkdir($dir, 0755); + } + if ($self->{'MOZCLIENT_EMBEDDED'}) { + $self->chdir($self->work_dir); + my $cmd = sprintf "tar jcf %s-%s/%s-%s-source.tar.bz2 %s mozilla", + $self->{'MOZCLIENT_APPNAME'}, $version, $self->{'MOZCLIENT_PROJECT'}, + $tversion, $tar_exclude; + $self->run_system($cmd); + $self->chdir(".."); + } + else { + my $cmd = sprintf "mv %s/mozilla %s/%s-%s/", + $self->work_dir, $self->work_dir, $self->{'MOZCLIENT_APPNAME'}, $version; + $self->run_system("$cmd"); + } + $self->unlink($self->{'MOZCLIENT_APPNAME'} . "_$version.orig.tar.gz") + if -f $self->{'MOZCLIENT_APPNAME'} . "_$version.orig.tar.gz"; + $self->chdir($self->work_dir); + $cmd = sprintf "tar zcf ../%s_%s.orig.tar.gz %s %s-%s", + $self->{'MOZCLIENT_APPNAME'}, $version, $tar_exclude, + $self->{'MOZCLIENT_APPNAME'}, $version; + $self->run_shell($cmd); + $self->chdir(".."); + $self->run_system("rm -rf " . $self->work_dir); + $self->run_system("ls -l " . $self->{'MOZCLIENT_APPNAME'} . + "_$version.orig.tar.gz"); +} + +1; |