[rt-devel] RT contributor framework
Ruslan U. Zakirov
cubic at acronis.ru
Fri Sep 12 13:23:53 EDT 2003
Intoduction:
I was searching a way of using CVS or Aegis to manage mine RT
contributions for some time. May be because of lack of knowledge in VSs
technologies or something else, but I didn't find solutions to solve
next problems:
- have no rights to commit in mainline;
- easy resolve conflicts on merging own repository with mainline;
- need more then one repository for different subprojects;
- save change sets in CVS instead of changes for particular files;
- get Aegis full clone of RT3.0.0 project from Best Practical web;
Tasks:
1) setup mainline repository that consistent with Best Practical
current version
2) setup repository for fixes/changes that should be included in
mainline
3) setup repository for stable(currently working) version of RT
4) setup other repositories for subprojects(contributions)
5) write this article
6) and many other tasks
Solutions:
I've stop my searches on BitKeeper(www.bitkeeper.com) with Single
User/Host license. I know that this license have restrictions on using
some good stuffs, but allowed tools solve most of described problems.
Everthing that you need to install bk on your machine you could find at
its site. I mentioned only one problem, after installation bk doesn't
start under root login with complaints about 'wm'.
Now we need to do initial import of RT source tree in bk repository:
- cd /tmp
- wget http://fsck.com/pub/rt/release/rt-3-0-4.tar.gz
- tar -zxvf rt-3-0-4.tar.gz
- cd /to/where/you/want/to/create/your/bk/repository
- bk setuptool bp_current
following GUI instructions of Setup Tool
- bk import -F -tCVS -A /tmp/rt-3-0-4 bp_current
We have got new bk branch without parent under bp_current dir.
It would be our clone off mainline. We should never push changes in it.
It's only for import latest changes from Best Practical.
I've started writing of script that automagically pull changes from
aegis history
page(http://fsck.com/aegis/aegis.cgi?file@proj_hstry+project@rt.3.0),
but it still in development state. Script attached to this email.
Coution!!! Be easy! Don't run it right now :) (It's still under
development). This tool uses ChangeSets comments for last delta number
identification. You must do "cd bp_current; bk comments -y'152/201
Bumping to RT 3.0.4'" before starting this script. BUGS: Script skips
deltas which creates new files and deletes old one. A lot of output
to STDOUT and more other .
Any help with script are wellcome.
Let forget about dirty script. And do some imort by hands.
- cd bp_current
- bk -r edit
- wget -q -O -
http://fsck.com/aegis/aegis.cgi/rt.3.0.C195.patch?file@aepatch+project@rt.3.0+change@195
| gunzip -c | patch -p0
- bk -r ci -y'153/195 #3042: Make max inline body size
configurable'
- bk commit -d -y'153/195 #3042: Make max inline body size
configurable'
Now we have commited new changeset from aegis. This also skip new
files, I found only next solution:
- find . -type f | xargs bk ci -i -y'New files'
To be continued:
Any sugestions and comments are wellcome.
Is it interesting for somebody or may be it's useful only for me?
Best regards. Ruslan.
-------------- next part --------------
#!/usr/bin/perl -w
use strict;
use Compress::Zlib qw(uncompress);
use vars qw($DEBUG $VERSION $AEGIS_URL $HISTORY_URL);
$DEBUG = 1;
$VERSION = '0.1';
$AEGIS_URL = 'http://fsck.com';
$HISTORY_URL = $AEGIS_URL.'/aegis/aegis.cgi?file at proj_hstry+project@rt.3.0';
if ($DEBUG) {
print check_bk()."\n";
print check_rep()."\n";
print get_rep()."\n";
} else {
check_bk();
check_rep();
get_rep();
}
my @ae_csets = ae_csets();
unless (@ae_csets) {
die "No Aegis change sets found\n";
}
my $last_ae_delta = $ae_csets[0]->{delta};
my @deltas = get_history();
unless (@ae_csets) {
die "No Aegis change sets found at $HISTORY_URL\n";
}
foreach my $delta (@deltas) {
next if ($delta->{delta}<=$last_ae_delta);
my $patch = get_patch($AEGIS_URL.$delta->{href});
print $delta->{delta}."/".$delta->{cset}." ".$delta->{comment}."\n" if ($DEBUG);
print $patch if ($DEBUG);
apply_patch($patch);
ci($delta);
commit($delta);
}
exit(0);
sub check_bk
{
my $res = `bk version`;
my ($ver) = ($res =~ /^BitKeeper\s?version is (.*?)$/m);
die "$res" unless ($ver);
return $ver;
}
sub check_rep
{
my $res = `bk config`;
my ($desc) = ($res =~ /^\s*description: (.*?)$/im);
die "$res" unless ($desc);
return $desc;
}
sub get_rep
{
my $res = `bk -R -r edit 2>&1`;
die "$res" unless ($res);
return $res;
}
sub ci
{
my $delta = shift;
my $cmd = "bk -r -R ci -l -y\"".$delta->{delta}."/".$delta->{cset}." ".$delta->{comment}."\" 2>&1";
my $res = `$cmd`;
die "$res" unless ($res);
print $res if ($DEBUG);
return $res;
}
sub commit
{
my $delta = shift;
my $cmd = "bk commit -d -y\"".$delta->{delta}."/".$delta->{cset}." ".$delta->{comment}."\" 2>&1";
my $res = `$cmd`;
die "$res" unless ($res);
return $res;
}
sub ae_csets
{
my @res = `bk changes`;
my @csets;
foreach my $str (@res) {
my ($delta,$cset,$comment) = ($str =~ /^\s*(\d+)\/(\d+) (.*)$/);
next unless ($delta);
if ($DEBUG) {
print "Delta: $delta, CSet: $cset, Comment: $comment\n";
}
push (@csets, {delta => $delta, cset => $cset, comment => $comment});
}
return @csets;
}
sub apply_patch
{
my $patch = shift;
open (PATCH, "|patch -p0 -f") || die "$!";
print PATCH $patch;
close PATCH;
return 1;
}
sub get_patch
{
my $href=shift;
require LWP::UserAgent;
my $ua = LWP::UserAgent->new(env_proxy => 1,
keep_alive => 1,
timeout => 30,
);
my $response = $ua->get($href);
die "Error while getting ", $response->request->uri,
" -- ", $response->status_line, "\nAborting"
unless $response->is_success;
my $content = $response->content;
my $output = Compress::Zlib::memGunzip(\$content) || die "Bad patch\n";
print "Patch $href geted\n" if ($DEBUG);
return $output;
}
sub get_history
{
my @deltas;
require LWP::UserAgent;
my $ua = LWP::UserAgent->new(env_proxy => 1,
keep_alive => 1,
timeout => 30,
);
my $response = $ua->get($HISTORY_URL);
die "Error while getting ", $response->request->uri,
" -- ", $response->status_line, "\nAborting"
unless $response->is_success;
my $content = $response->content;
($content) = ($content =~ /<table.*?^(.*?)^<\/table>/ms);
while ($content =~ /\G.*?^<tr class="(?:odd|even)-group">\n<td valign=top align=right>\n(\d+)\n(?:.*?\n){4}(\d+)<\/a>\n<\/td><td valign=top>\n(.*?)\n<\/td><td valign=top>\n.*?href="(.*?)"/igms) {
my ($delta,$cset,$comment,$href) = ($1,$2,$3,$4);
if ($DEBUG) {
print "Delta: $delta, CSet: $cset, Comment: $comment, HREF: $href\n";
}
push (@deltas, {delta => $delta, cset => $cset, comment => $comment, href => $href});
}
return @deltas;
}
More information about the Rt-devel
mailing list