summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFabien Tassin <fta@sofaraway.org>2008-06-06 02:09:09 +0200
committerFabien Tassin <fta@sofaraway.org>2008-06-06 02:09:09 +0200
commit433c87d371433b71f49d6f4c5c95b667e193e81e (patch)
tree21d4c3acf2acd877bae350576317ed09419f8ea2
parent45fbe26801d385c8ed4eb9f305f141d46efaafa1 (diff)
* [mozclient] Split perl modules from main perl file
- update src/mozclient.pl - add src/mozclient/lib/MozClient/VCS.pm - add src/mozclient/lib/MozClient/CVS.pm - add src/mozclient/lib/MozClient/Mercurial.pm - update src/Makefile
-rw-r--r--debian/changelog4
-rw-r--r--src/Makefile3
-rwxr-xr-xsrc/mozclient.pl527
-rw-r--r--src/mozclient/lib/MozClient/CVS.pm144
-rw-r--r--src/mozclient/lib/MozClient/Mercurial.pm85
-rw-r--r--src/mozclient/lib/MozClient/VCS.pm351
6 files changed, 606 insertions, 508 deletions
diff --git a/debian/changelog b/debian/changelog
index b87a76c..5cf7d51 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -5,9 +5,11 @@ mozilla-devscripts (0.09) UNRELEASED; urgency=low
* [ mozclient ]
+ Full refactoring of mozclient. It is now written in object-oriented Perl.
The makefile version was getting difficult to extend and to maintain.
- We now have a base class and a set of VCS classes inheriting for it.
+ We now have a base class called MozClient::VCS and a set of VCS classes
+ inheriting for it.
- add src/mozclient.pl
- add src/mozclient/${projects}.conf
+ - add src/mozclient/lib/MozClient/{VCS,CVS,Mercurial}.pm
- move src/patches to src/mozclient/patches
- update src/${projects}.mk.in
- update src/Makefile
diff --git a/src/Makefile b/src/Makefile
index 0334ad8..bb8b1a3 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -44,11 +44,14 @@ extra_files = \
remove.binonly.sh \
xpi.mk \
lp-locale-export.mk \
+ mozclient.pl \
$(NULL)
extra_dirs = \
mozclient \
mozclient/patches \
+ mozclient/lib \
+ mozclient/lib/MozClient \
minefield-packager/debian \
$(NULL)
diff --git a/src/mozclient.pl b/src/mozclient.pl
index 760cf5c..7671a8b 100755
--- a/src/mozclient.pl
+++ b/src/mozclient.pl
@@ -19,20 +19,14 @@
############################################################################
-package MozClient;
-
-# 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;
+use Getopt::Long qw(:config no_auto_abbrev no_ignore_case
+ require_order bundling);
my $mozclient_dir = "/usr/share/mozilla-devscripts";
my $pkg_conf_dir = "$mozclient_dir/mozclient";
my $patches_dir = "$pkg_conf_dir/patches";
my $work_dir = "mozclient-tmp";
-my $nobinonly = "nobinonly";
my @conf_mandatory = qw(MOZCLIENT_APPNAME MOZCLIENT_FILE MOZCLIENT_GETVERSION
MOZCLIENT_GETDATE MOZCLIENT_VCS);
@@ -43,14 +37,6 @@ my @conf_optional = qw(MOZCLIENT_MODULES MOZCLIENT_PROJECT MOZCLIENT_BRANCH
MOZCLIENT_CVS_LOC MOZCLIENT_HG_LOC);
my @conf_list = qw(MOZCLIENT_FILE);
-# List of dependencies
-my $dependencies = {
- 'cvs' => '/usr/bin/cvs',
- 'mercurial' => '/usr/bin/hg',
- 'quilt' => '/usr/bin/quilt',
- 'wget' => '/usr/bin/wget',
-};
-
my $defaults = {
'MOZCLIENT_CVS_LOC' => ':pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot',
'MOZCLIENT_HG_LOC' => 'http://hg.mozilla.org/',
@@ -59,505 +45,28 @@ my $defaults = {
'MOZCLIENT_PATCHES' => "$patches_dir",
};
-############################################################################
-
-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 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 $work_dir) {
- $self->LOG("MozClient::cleanup_dir()");
- $self->run_system("rm -rf $work_dir");
- }
-}
-
-sub prepare_dir {
- my $self = shift;
-
- $self->LOG("MozClient::prepare_dir()");
- $self->cleanup_dir();
- $self->mkdir($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";
-}
+BEGIN {
+ # We look for modules in /usr/share/mozilla-devscripts/mozclient/lib
+ # We can prefer another path by using '--conf-dir path' or '-c path'
+ unshift @INC, "/usr/share/mozilla-devscripts/mozclient/lib";
-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($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'};
+ my @args = @ARGV;
+ while (1) {
+ my $arg = shift @args;
+ last unless defined $arg;
+ next unless $arg eq '-c' || $arg eq '--conf-dir';
+ my $path = shift @args;
+ die "Usage error: $arg needs an argument\n" unless defined $path;
+ unshift @INC, $path;
+ last;
}
}
-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("$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($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 "$work_dir/mozilla/REMOVED+${nobinonly}.txt";
- $self->run_system("rm -rf $work_dir/" . $self->{'MOZCLIENT_APPNAME'} .
- "-$version");
- if ($self->{'MOZCLIENT_EMBEDDED'} || $self->{'MOZCLIENT_WANTMOZDIR'}) {
- $self->mkdir("$work_dir/" . $self->{'MOZCLIENT_APPNAME'} . "-$version",
- 0755);
- }
- if ($self->{'MOZCLIENT_EMBEDDED'}) {
- $self->chdir($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 {
- $self->run_system("mv $work_dir/mozilla $work_dir/" .
- $self->{'MOZCLIENT_APPNAME'} . "-$version/");
- }
- $self->unlink($self->{'MOZCLIENT_APPNAME'} . "_$version.orig.tar.gz")
- if -f $self->{'MOZCLIENT_APPNAME'} . "_$version.orig.tar.gz";
- $self->chdir($work_dir);
- my $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 $work_dir");
- $self->run_system("ls -l " . $self->{'MOZCLIENT_APPNAME'} .
- "_$version.orig.tar.gz");
-}
-
-############################################################################
-
-package MozClient::CVS;
-
-use vars qw(@ISA);
-use strict;
-
-@ISA = ("MozClient");
-
-# Return the list of TAGs known by the VCS for MOZCLIENT_FILE
-sub list_tags {
- my $self = shift;
-
- $self->LOG("MozClient::CVS::list_tags()");
- $self->chdir($work_dir);
- $self->run_system("cvs -d " . $self->{'MOZCLIENT_CVS_LOC'} . " co " .
- (join ' ', @{$self->{'MOZCLIENT_FILE'}}));
- my $file = ${$self->{'MOZCLIENT_FILE'}}[0];
- $file =~ s,^([^/]*)/,,;
- $self->chdir("$1");
- $self->run_system("cvs status -v $file");
- $self->chdir("../..");
-}
-
-sub do_dynamic_tag {
- my $self = shift;
-
- $self->LOG("MozClient::CVS::do_dynamic_tag()");
- # We want a dynamic TAG. Fetch files listed in MOZCLIENT_DYNTAG_FILES, then
- # apply MOZCLIENT_DYNTAG rule to set $want_tag
- die "Error: Missing MOZCLIENT_DYNTAG_FILES\n"
- unless defined $self->{'MOZCLIENT_DYNTAG_FILES'};
- $self->chdir($work_dir);
- my $date = "";
- $date = '-D "' . $self->convert_revdate($self->{'have_date'}) . '"'
- if defined $self->{'have_date'};
- undef $self->{'have_date'};
- my $cmd = sprintf "cvs -d %s co %s", $self->{'MOZCLIENT_CVS_LOC'},
- $self->{'MOZCLIENT_DYNTAG_FILES'};
- $self->run_system($cmd);
- chomp($self->{'want_tag'} = `$self->{'MOZCLIENT_DYNTAG'}`);
- $self->LOG2("\$ want_tag=`" . $self->{'MOZCLIENT_DYNTAG'} . "` # => " .
- $self->{'want_tag'});
- $self->chdir("..");
-}
-
-sub get_client {
- my $self = shift;
-
- $self->LOG("MozClient::CVS::get_client()");
- my $tbranch = defined $self->{'want_branch'} ?
- "-r " . $self->{'want_branch'} : "";
-
- $self->chdir($work_dir);
- my $cmd = sprintf "cvs -d %s co %s %s %s %s", $self->{'MOZCLIENT_CVS_LOC'},
- $tbranch, $self->{'mozclient_date'}, $self->{'co_tag'},
- $self->{'MOZILLA_CLIENT'};
- $self->run_system($cmd);
- $self->chdir("..");
-
- if (defined $self->{'MOZCLIENT_WANTPATCH'} &&
- $self->{'MOZCLIENT_WANTPATCH'}) {
- $self->run_system("ln -s " . $self->{'MOZCLIENT_PATCHES'} .
- " $work_dir/patches");
- $self->chdir($work_dir);
- $self->run_system("quilt --quiltrc /dev/null push -a");
- $self->chdir("..");
- }
-}
-
-sub convert_revdate {
- my $self = shift;
- my $arg = shift;
-
- $self->LOG("MozClient::CVS::convert_revdate($arg)");
- $arg =~ s,(....)(..)(..)[rt](..)(..),$1/$2/$3 $4:$5 PST,;
- $arg;
-}
-
-sub set_revdate {
- my $self = shift;
-
- $self->LOG("MozClient::CVS::set_revdate()");
-
- # We can set a date for CVS
- if (defined $self->{'MOZCLIENT_PROJECT'}) {
- $self->{'mozclient_date'} =
- 'MOZ_CO_DATE="' . $self->convert_revdate($self->{'have_date'}) . '"';
- }
- else {
- $self->{'mozclient_date'} =
- '-D "' . $self->convert_revdate($self->{'have_date'}) . '"';
- }
-}
-
-sub checkout {
- my $self = shift;
-
- $self->LOG("MozClient:CVS::checkout:()");
- $self->chdir($work_dir);
- if (defined $self->{'MOZCLIENT_PROJECT'}) {
- my $cmd = sprintf "make -f %s checkout MOZ_CO_PROJECT=%s %s %s",
- $self->{'MOZILLA_CLIENT'}, $self->{'MOZCLIENT_PROJECT'},
- $self->{'mozclient_date'}, $self->{'moz_co_tag'};
- $self->run_system($cmd);
- }
- else {
- my $cmd = sprintf "cvs -d %s -q -z 3 co -P -A %s %s %s",
- $self->{'MOZCLIENT_CVS_LOC'}, $self->{'mozclient_date'},
- $self->{'co_tag'}, $self->{'MOZCLIENT_MODULES'};
- $self->run_system($cmd);
- }
- $self->chdir("..");
-}
-
-sub tar_exclude {
- my $self = shift;
-
- $self->LOG("MozClient::CVS::tar_exclude()");
- [ '--exclude CVS', '--exclude .cvsignore' ];
-}
-
-############################################################################
-
-package MozClient::Mercurial;
-
-use vars qw(@ISA);
-use strict;
-
-@ISA = ("MozClient");
-
-sub get_client {
- my $self = shift;
-
- $self->LOG("MozClient::Mercurial::get_client()");
- # nothing to do
-}
-
-sub convert_revdate {
- my $self = shift;
- my $arg = shift;
-
- $self->LOG("MozClient::Mercurial::convert_revdate($arg)");
- $arg =~ s,^(\d+).*,$1,;
- $arg;
-}
-
-sub set_revdate {
- my $self = shift;
-
- $self->LOG("MozClient::Mercurial::set_revdate()");
-
- # We can set a revision for hg
- $self->{'mozclient_date'} =
- '-r ' . $self->convert_revdate($self->{'have_date'});
-}
-
-sub checkout {
- my $self = shift;
-
- $self->LOG("MozClient:Mercurial::checkout:()");
- $self->chdir($work_dir);
- my $modules = [];
- if (defined $self->{'MOZCLIENT_PROJECT'}) {
- push @$modules,
- $self->{'MOZCLIENT_HG_LOC'} . $self->{'MOZCLIENT_PROJECT'} . "/";
- }
- else {
- for my $module (@{$self->{'MOZCLIENT_MODULES'}}) {
- push @$modules, (sprintf " %s%s/%s", $self->{'MOZCLIENT_HG_LOC'},
- $self->{'MOZCLIENT_PROJECT'}, $module);
- }
- }
- my $cmd = sprintf "hg clone %s %s mozilla", $self->{'mozclient_date'},
- join " ", @$modules;
- $self->run_system($cmd);
- $self->chdir("..");
-}
-
-sub tar_exclude {
- my $self = shift;
-
- $self->LOG("MozClient::Mercurial::tar_exclude()");
- [ '--exclude .hg' ];
-}
-
-############################################################################
-
-package main;
-
-use strict;
-use Getopt::Long qw(:config no_auto_abbrev no_ignore_case
- require_order bundling);
-
sub help {
print <<EOF;
mozclient [-b branch] [-t tag] [-d YYYYMMDDtHHmm] project-name
mozclient [-l] project-name
- --conf-dir|-c dir use dir as config directory (default: $mozclient_dir)
+ --conf-dir|-c dir use dir as config directory
--list-tags|-l list VCS tags
--branch|-b branch checkout from a specific branch
--date|-d date checkout by date (YYYYMMDDtHHmm)
@@ -657,6 +166,9 @@ sub read_project_file {
############################################################################
+use MozClient::CVS;
+use MozClient::Mercurial;
+
# Main
my $opt = {};
GetOptions($opt,
@@ -680,6 +192,7 @@ do {
die "VCS '$$conf{'MOZCLIENT_VCS'}' not supported yet";
};
+$client->work_dir($work_dir);
$client->check_dependencies();
$client->prepare_dir();
diff --git a/src/mozclient/lib/MozClient/CVS.pm b/src/mozclient/lib/MozClient/CVS.pm
new file mode 100644
index 0000000..7c946a3
--- /dev/null
+++ b/src/mozclient/lib/MozClient/CVS.pm
@@ -0,0 +1,144 @@
+# -*- mode: Perl -*-
+
+# Copyright (c) 2007-2008 Fabien Tassin <fta@sofaraway.org>
+# Description: MozClient::CVS
+#
+# 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::CVS;
+
+use vars qw(@ISA);
+use strict;
+use MozClient::VCS;
+
+@ISA = ("MozClient::VCS");
+
+# Return the list of TAGs known by the VCS for MOZCLIENT_FILE
+sub list_tags {
+ my $self = shift;
+
+ $self->LOG("MozClient::CVS::list_tags()");
+ $self->chdir($self->work_dir);
+ $self->run_system("cvs -d " . $self->{'MOZCLIENT_CVS_LOC'} . " co " .
+ (join ' ', @{$self->{'MOZCLIENT_FILE'}}));
+ my $file = ${$self->{'MOZCLIENT_FILE'}}[0];
+ $file =~ s,^([^/]*)/,,;
+ $self->chdir("$1");
+ $self->run_system("cvs status -v $file");
+ $self->chdir("../..");
+}
+
+sub do_dynamic_tag {
+ my $self = shift;
+
+ $self->LOG("MozClient::CVS::do_dynamic_tag()");
+ # We want a dynamic TAG. Fetch files listed in MOZCLIENT_DYNTAG_FILES, then
+ # apply MOZCLIENT_DYNTAG rule to set $want_tag
+ die "Error: Missing MOZCLIENT_DYNTAG_FILES\n"
+ unless defined $self->{'MOZCLIENT_DYNTAG_FILES'};
+ $self->chdir($self->work_dir);
+ my $date = "";
+ $date = '-D "' . $self->convert_revdate($self->{'have_date'}) . '"'
+ if defined $self->{'have_date'};
+ undef $self->{'have_date'};
+ my $cmd = sprintf "cvs -d %s co %s", $self->{'MOZCLIENT_CVS_LOC'},
+ $self->{'MOZCLIENT_DYNTAG_FILES'};
+ $self->run_system($cmd);
+ chomp($self->{'want_tag'} = `$self->{'MOZCLIENT_DYNTAG'}`);
+ $self->LOG2("\$ want_tag=`" . $self->{'MOZCLIENT_DYNTAG'} . "` # => " .
+ $self->{'want_tag'});
+ $self->chdir("..");
+}
+
+sub get_client {
+ my $self = shift;
+
+ $self->LOG("MozClient::CVS::get_client()");
+ my $tbranch = defined $self->{'want_branch'} ?
+ "-r " . $self->{'want_branch'} : "";
+
+ $self->chdir($self->work_dir);
+ my $cmd = sprintf "cvs -d %s co %s %s %s %s", $self->{'MOZCLIENT_CVS_LOC'},
+ $tbranch, $self->{'mozclient_date'}, $self->{'co_tag'},
+ $self->{'MOZILLA_CLIENT'};
+ $self->run_system($cmd);
+ $self->chdir("..");
+
+ if (defined $self->{'MOZCLIENT_WANTPATCH'} &&
+ $self->{'MOZCLIENT_WANTPATCH'}) {
+ my $cmd = sprintf "ln -s %s %s/patches", $self->{'MOZCLIENT_PATCHES'},
+ $self->work_dir;
+ $self->run_system($cmd);
+ $self->chdir($self->work_dir);
+ $self->run_system("quilt --quiltrc /dev/null push -a");
+ $self->chdir("..");
+ }
+}
+
+sub convert_revdate {
+ my $self = shift;
+ my $arg = shift;
+
+ $self->LOG("MozClient::CVS::convert_revdate($arg)");
+ $arg =~ s,(....)(..)(..)[rt](..)(..),$1/$2/$3 $4:$5 PST,;
+ $arg;
+}
+
+sub set_revdate {
+ my $self = shift;
+
+ $self->LOG("MozClient::CVS::set_revdate()");
+
+ # We can set a date for CVS
+ if (defined $self->{'MOZCLIENT_PROJECT'}) {
+ $self->{'mozclient_date'} =
+ 'MOZ_CO_DATE="' . $self->convert_revdate($self->{'have_date'}) . '"';
+ }
+ else {
+ $self->{'mozclient_date'} =
+ '-D "' . $self->convert_revdate($self->{'have_date'}) . '"';
+ }
+}
+
+sub checkout {
+ my $self = shift;
+
+ $self->LOG("MozClient:CVS::checkout:()");
+ $self->chdir($self->work_dir);
+ if (defined $self->{'MOZCLIENT_PROJECT'}) {
+ my $cmd = sprintf "make -f %s checkout MOZ_CO_PROJECT=%s %s %s",
+ $self->{'MOZILLA_CLIENT'}, $self->{'MOZCLIENT_PROJECT'},
+ $self->{'mozclient_date'}, $self->{'moz_co_tag'};
+ $self->run_system($cmd);
+ }
+ else {
+ my $cmd = sprintf "cvs -d %s -q -z 3 co -P -A %s %s %s",
+ $self->{'MOZCLIENT_CVS_LOC'}, $self->{'mozclient_date'},
+ $self->{'co_tag'}, $self->{'MOZCLIENT_MODULES'};
+ $self->run_system($cmd);
+ }
+ $self->chdir("..");
+}
+
+sub tar_exclude {
+ my $self = shift;
+
+ $self->LOG("MozClient::CVS::tar_exclude()");
+ [ '--exclude CVS', '--exclude .cvsignore' ];
+}
+
+1;
diff --git a/src/mozclient/lib/MozClient/Mercurial.pm b/src/mozclient/lib/MozClient/Mercurial.pm
new file mode 100644
index 0000000..54fd9dd
--- /dev/null
+++ b/src/mozclient/lib/MozClient/Mercurial.pm
@@ -0,0 +1,85 @@
+# -*- mode: Perl -*-
+
+# Copyright (c) 2007-2008 Fabien Tassin <fta@sofaraway.org>
+# Description: MozClient::Mercurial
+#
+# 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::Mercurial;
+
+use vars qw(@ISA);
+use strict;
+use MozClient::VCS;
+
+@ISA = ("MozClient::VCS");
+
+sub get_client {
+ my $self = shift;
+
+ $self->LOG("MozClient::Mercurial::get_client()");
+ # nothing to do
+}
+
+sub convert_revdate {
+ my $self = shift;
+ my $arg = shift;
+
+ $self->LOG("MozClient::Mercurial::convert_revdate($arg)");
+ $arg =~ s,^(\d+).*,$1,;
+ $arg;
+}
+
+sub set_revdate {
+ my $self = shift;
+
+ $self->LOG("MozClient::Mercurial::set_revdate()");
+
+ # We can set a revision for hg
+ $self->{'mozclient_date'} =
+ '-r ' . $self->convert_revdate($self->{'have_date'});
+}
+
+sub checkout {
+ my $self = shift;
+
+ $self->LOG("MozClient:Mercurial::checkout:()");
+ $self->chdir($self->work_dir);
+ my $modules = [];
+ if (defined $self->{'MOZCLIENT_PROJECT'}) {
+ push @$modules,
+ $self->{'MOZCLIENT_HG_LOC'} . $self->{'MOZCLIENT_PROJECT'} . "/";
+ }
+ else {
+ for my $module (@{$self->{'MOZCLIENT_MODULES'}}) {
+ push @$modules, (sprintf " %s%s/%s", $self->{'MOZCLIENT_HG_LOC'},
+ $self->{'MOZCLIENT_PROJECT'}, $module);
+ }
+ }
+ my $cmd = sprintf "hg clone %s %s mozilla", $self->{'mozclient_date'},
+ join " ", @$modules;
+ $self->run_system($cmd);
+ $self->chdir("..");
+}
+
+sub tar_exclude {
+ my $self = shift;
+
+ $self->LOG("MozClient::Mercurial::tar_exclude()");
+ [ '--exclude .hg' ];
+}
+
+1;
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;