source: ProjectBuilder/devel/pb/lib/ProjectBuilder/CMS.pm@ 1866

Last change on this file since 1866 was 1866, checked in by Bruno Cornec, 10 years ago
  • If using git, then do not use the version name in the URI cloned as it's in the repo in fact.
File size: 11.2 KB
Line 
1#!/usr/bin/perl -w
2#
3# Project Builder CMS module
4# CMS subroutines brought by the the Project-Builder project
5# which can be easily used by pbinit scripts
6#
7# $Id$
8#
9# Copyright B. Cornec 2007-2012
10# Eric Anderson's changes are (c) Copyright 2012 Hewlett Packard
11# Provided under the GPL v2
12
13package ProjectBuilder::CMS;
14
15use strict 'vars';
16use Carp 'confess';
17use Data::Dumper;
18use English;
19use File::Basename;
20use File::Copy;
21use POSIX qw(strftime);
22use lib qw (lib);
23use ProjectBuilder::Version;
24use ProjectBuilder::Base;
25use ProjectBuilder::Conf;
26use ProjectBuilder::VCS;
27
28# Inherit from the "Exporter" module which handles exporting functions.
29
30use vars qw($VERSION $REVISION @ISA @EXPORT);
31use Exporter;
32
33# Export, by default, all the functions into the namespace of
34# any code which uses this module.
35
36our @ISA = qw(Exporter);
37our @EXPORT = qw(pb_cms_init pb_cms_get_pkg pb_cms_get_real_pkg pb_cms_log);
38($VERSION,$REVISION) = pb_version_init();
39
40=pod
41
42=head1 NAME
43
44ProjectBuilder::CMS, part of the project-builder.org
45
46=head1 DESCRIPTION
47
48This modules provides configuration management system functions suitable for pbinit calls.
49
50=head1 USAGE
51
52=over 4
53
54=item B<pb_cms_init>
55
56This function setup the environment for the CMS system related to the URL given by the pburl configuration parameter.
57The potential parameter indicates whether we should inititate the context or not.
58It sets up environement variables (PBPROJDIR, PBDIR, PBREVISION, PBCMSLOGFILE)
59
60=cut
61
62sub pb_cms_init {
63
64my $pbinit = shift || undef;
65my $param = shift || undef;
66
67my ($pburl) = pb_conf_get("pburl");
68pb_log(2,"DEBUG: Project URL of $ENV{'PBPROJ'}: $pburl->{$ENV{'PBPROJ'}}\n");
69my ($scheme, $account, $host, $port, $path) = pb_get_uri($pburl->{$ENV{'PBPROJ'}});
70my $vcscmd = pb_vcs_cmd($scheme);
71
72my ($pbprojdir) = pb_conf_get_if("pbprojdir");
73
74if ((defined $pbprojdir) && (defined $pbprojdir->{$ENV{'PBPROJ'}})) {
75 $ENV{'PBPROJDIR'} = $pbprojdir->{$ENV{'PBPROJ'}};
76} else {
77 $ENV{'PBPROJDIR'} = "$ENV{'PBDEFDIR'}/$ENV{'PBPROJ'}";
78}
79# Expand potential env variable in it to allow string replacement
80eval { $ENV{'PBPROJDIR'} =~ s/(\$ENV.+\})/$1/eeg };
81
82
83# Computing the default dir for PBDIR.
84# what we have is PBPROJDIR so work from that.
85# Tree identical between PBCONFDIR and PBROOTDIR on one side and
86# PBPROJDIR and PBDIR on the other side.
87
88my $tmp = $ENV{'PBROOTDIR'};
89$tmp =~ s|^$ENV{'PBCONFDIR'}/||;
90
91#
92# Check project cms compliance
93#
94my $turl = "$pburl->{$ENV{'PBPROJ'}}/$tmp";
95$turl = $pburl->{$ENV{'PBPROJ'}} if ($scheme =~ /^(flat)|(ftp)|(http)|(file)|(git)\b/o);
96pb_vcs_compliant(undef,'PBDIR',"$ENV{'PBPROJDIR'}/$tmp",$turl,$pbinit);
97
98
99if ($scheme =~ /^hg/) {
100 $tmp = `(cd "$ENV{'PBDIR'}" ; $vcscmd identify )`;
101 chomp($tmp);
102 $tmp =~ s/^.* //;
103 $ENV{'PBREVISION'}=$tmp;
104 $ENV{'PBCMSLOGFILE'}="hg.log";
105} elsif ($scheme =~ /^git/) {
106 if ($scheme =~ /svn/) {
107 $tmp = `(cd "$ENV{'PBDIR'}" ; LANGUAGE=C $vcscmd info | grep -E '^Revision:' | cut -d: -f2)`;
108 $tmp =~ s/\s+//;
109 } else {
110 $tmp = `(cd "$ENV{'PBDIR'}" ; $vcscmd log | head -1 | cut -f2)`;
111 $tmp =~ s/^.* //;
112 }
113 chomp($tmp);
114 $ENV{'PBREVISION'}=$tmp;
115 $ENV{'PBCMSLOGFILE'}="git.log";
116} elsif ($scheme =~ /^(flat)|(ftp)|(http)|(file)\b/o) {
117 $ENV{'PBREVISION'}="flat";
118 $ENV{'PBCMSLOGFILE'}="flat.log";
119} elsif ($scheme =~ /^svn/) {
120 # svnversion more precise than svn info if sbx
121 if ((defined $param) && ($param eq "CMS")) {
122 $tmp = `(LANGUAGE=C $vcscmd info $pburl->{$ENV{'PBPROJ'}} | grep -E '^Revision:' | cut -d: -f2)`;
123 $tmp =~ s/\s+//;
124 } else {
125 $tmp = `(cd "$ENV{'PBDIR'}" ; $vcscmd"version" .)`;
126 }
127 chomp($tmp);
128 $ENV{'PBREVISION'}=$tmp;
129 $ENV{'PBCMSLOGFILE'}="svn.log";
130} elsif ($scheme =~ /^svk/) {
131 $tmp = `(cd "$ENV{'PBDIR'}" ; LANGUAGE=C $vcscmd info . | grep -E '^Revision:' | cut -d: -f2)`;
132 $tmp =~ s/\s+//;
133 chomp($tmp);
134 $ENV{'PBREVISION'}=$tmp;
135 $ENV{'PBCMSLOGFILE'}="svk.log";
136} elsif ($scheme =~ /^cvs/) {
137 # Way too slow
138 #$ENV{'PBREVISION'}=`(cd "$ENV{'PBROOTDIR'}" ; cvs rannotate -f . 2>&1 | awk '{print \$1}' | grep -E '^[0-9]' | cut -d. -f2 |sort -nu | tail -1)`;
139 #chomp($ENV{'PBREVISION'});
140 $ENV{'PBREVISION'}="cvs";
141 $ENV{'PBCMSLOGFILE'}="cvs.log";
142 $ENV{'CVS_RSH'} = "ssh" if ($scheme =~ /ssh/);
143} else {
144 die "cms $scheme unknown";
145}
146
147pb_log(1,"pb_cms_init returns $scheme,$pburl->{$ENV{'PBPROJ'}}\n");
148return($scheme,$pburl->{$ENV{'PBPROJ'}});
149}
150
151=item B<pb_cms_get_pkg>
152
153This function returns the list of packages we are working on in a CMS action.
154The first parameter is the default list of packages from the configuration file.
155The second parameter is the optional list of packages from the configuration file.
156
157=cut
158
159sub pb_cms_get_pkg {
160
161my @pkgs = ();
162my $defpkgdir = shift || undef;
163my $extpkgdir = shift || undef;
164
165# Get packages list
166if (not defined $ARGV[0]) {
167 @pkgs = keys %$defpkgdir if (defined $defpkgdir);
168} elsif ($ARGV[0] =~ /^all$/) {
169 @pkgs = keys %$defpkgdir if (defined $defpkgdir);
170 push(@pkgs, keys %$extpkgdir) if (defined $extpkgdir);
171} else {
172 @pkgs = @ARGV;
173}
174pb_log(0,"Packages: ".join(',',@pkgs)."\n");
175return(\@pkgs);
176}
177
178=item B<pb_cms_get_real_pkg>
179
180This function returns the real name of a virtual package we are working on in a CMS action.
181It supports the following types: perl.
182The first parameter is the virtual package name
183
184=cut
185
186sub pb_cms_get_real_pkg {
187
188my $pbpkg = shift || undef;
189my $dtype = shift;
190my $pbpkgreal = $pbpkg;
191
192my @nametype = pb_conf_get_if("namingtype");
193my $type = $nametype[0]->{$pbpkg};
194if (defined $type) {
195 if ($type eq "perl") {
196 if ($dtype eq "rpm") {
197 $pbpkgreal = "perl-".$pbpkg;
198 } elsif ($dtype eq "deb") {
199 # Only lower case allowed in Debian
200 # Cf: http://www.debian.org/doc/debian-policy/ch-controlfields.html#s-f-Package
201 $pbpkgreal = "lib".lc($pbpkg)."-perl";
202 } elsif ($dtype eq "ebuild") {
203 $pbpkgreal = $pbpkg;
204 } elsif ($dtype eq "hpux") {
205 $pbpkgreal = $pbpkg;
206 } elsif ($dtype eq "pkg") {
207 $pbpkgreal = "PB$pbpkg";
208 } else {
209 die "pb_cms_get_real_pkg not implemented for $dtype yet";
210 }
211 } else {
212 die "nametype $type not implemented yet";
213 }
214}
215
216pb_log(2,"pb_cms_get_real_pkg returns $pbpkgreal\n");
217return($pbpkgreal);
218}
219
220=item B<pb_cms_create_authors>
221
222This function creates a AUTHORS files for the project. It call it AUTHORS.pb if an AUTHORS file already exists.
223The first parameter is the source file for authors information.
224The second parameter is the directory where to create the final AUTHORS file.
225The third parameter is the schema of the CMS systems (svn, cvs, svn+ssh, ...)
226
227=cut
228
229sub pb_cms_create_authors {
230
231my $authors=shift;
232my $dest=shift;
233my $scheme=shift;
234
235return if ($authors eq "/dev/null");
236open(SAUTH,$authors) || die "Unable to open $authors";
237# Save a potentially existing AUTHORS file and write instead to AUTHORS.pb
238my $ext = "";
239if (-f "$dest/AUTHORS") {
240 $ext = ".pb";
241}
242open(DAUTH,"> $dest/AUTHORS$ext") || die "Unable to create $dest/AUTHORS$ext";
243print DAUTH "Authors of the project are:\n";
244print DAUTH "===========================\n";
245while (<SAUTH>) {
246 my ($nick,$gcos) = split(/:/);
247 chomp($gcos);
248 print DAUTH "$gcos";
249 if (defined $scheme) {
250 # Do not give a scheme for flat types
251 my $endstr="";
252 if ("$ENV{'PBREVISION'}" ne "flat") {
253 $endstr = " under $scheme";
254 }
255 print DAUTH " ($nick$endstr)\n";
256 } else {
257 print DAUTH "\n";
258 }
259}
260close(DAUTH);
261close(SAUTH);
262}
263
264=item B<pb_cms_log>
265
266This function creates a ChangeLog file for the project.
267The first parameter is the schema of the CMS systems (svn, cvs, svn+ssh, ...)
268The second parameter is the directory where the CMS content was checked out.
269The third parameter is the directory where to create the final ChangeLog file.
270The fourth parameter is unused.
271The fifth parameter is the source file for authors information.
272
273It may use a tool like svn2cl or cvs2cl to generate it if present, or the log file from the CMS if not.
274
275=cut
276
277
278sub pb_cms_log {
279
280my $scheme = shift;
281my $pkgdir = shift;
282my $dest = shift;
283my $chglog = shift;
284my $authors = shift;
285my $testver = shift || undef;
286
287pb_cms_create_authors($authors,$dest,$scheme);
288my $vcscmd = pb_vcs_cmd($scheme);
289
290if ((defined $testver) && (defined $testver->{$ENV{'PBPROJ'}}) && ($testver->{$ENV{'PBPROJ'}} =~ /true/i)) {
291 if (! -f "$dest/ChangeLog") {
292 open(CL,"> $dest/ChangeLog") || confess "Unable to create $dest/ChangeLog";
293 # We need a minimal version for debian type of build
294 print CL "\n";
295 print CL "\n";
296 print CL "\n";
297 print CL "\n";
298 print CL "1990-01-01 none\n";
299 print CL "\n";
300 print CL " * test version\n";
301 print CL "\n";
302 close(CL);
303 pb_log(0,"Generating fake ChangeLog for test version\n");
304 open(CL,"> $dest/$ENV{'PBCMSLOGFILE'}") || die "Unable to create $dest/$ENV{'PBCMSLOGFILE'}";
305 close(CL);
306 }
307}
308
309if (! -f "$dest/ChangeLog") {
310 if ($scheme =~ /^svn/) {
311 # In case we have no network, just create an empty one before to allow correct build
312 open(CL,"> $dest/ChangeLog") || die "Unable to create $dest/ChangeLog";
313 close(CL);
314 my $command = pb_check_req("svn2cl",1);
315 if ((defined $command) && (-x $command)) {
316 pb_system("$command --group-by-day --authors=$authors -i -o $dest/ChangeLog $pkgdir","Generating ChangeLog from SVN with svn2cl");
317 } else {
318 # To be written from pbcl
319 pb_system("$vcscmd log -v $pkgdir > $dest/$ENV{'PBCMSLOGFILE'}","Extracting log info from SVN");
320 }
321 } elsif ($scheme =~ /^svk/) {
322 pb_system("$vcscmd log -v $pkgdir > $dest/$ENV{'PBCMSLOGFILE'}","Extracting log info from SVK");
323 } elsif ($scheme =~ /^hg/) {
324 # In case we have no network, just create an empty one before to allow correct build
325 open(CL,"> $dest/ChangeLog") || die "Unable to create $dest/ChangeLog";
326 close(CL);
327 pb_system("$vcscmd log -v $pkgdir > $dest/$ENV{'PBCMSLOGFILE'}","Extracting log info from Mercurial");
328 } elsif ($scheme =~ /^git/) {
329 # In case we have no network, just create an empty one before to allow correct build
330 open(CL,"> $dest/ChangeLog") || die "Unable to create $dest/ChangeLog";
331 close(CL);
332 pb_system("$vcscmd log -v $pkgdir > $dest/$ENV{'PBCMSLOGFILE'}","Extracting log info from GIT");
333 } elsif ($scheme =~ /^(flat)|(ftp)|(http)|(file)|(dir)\b/o) {
334 pb_system("echo ChangeLog for $pkgdir > $dest/ChangeLog","Empty ChangeLog file created");
335 } elsif ($scheme =~ /^cvs/) {
336 my $tmp=basename($pkgdir);
337 # CVS needs a relative path !
338 # In case we have no network, just create an empty one before to allow correct build
339 open(CL,"> $dest/ChangeLog") || die "Unable to create $dest/ChangeLog";
340 close(CL);
341 my $command = pb_check_req("cvs2cl",1);
342 if (-x $command) {
343 pb_system("$command --group-by-day -U $authors -f $dest/ChangeLog $pkgdir","Generating ChangeLog from CVS with cvs2cl");
344 } else {
345 # To be written from pbcl
346 pb_system("$vcscmd log $tmp > $dest/$ENV{'PBCMSLOGFILE'}","Extracting log info from CVS");
347 }
348 } else {
349 die "cms $scheme unknown";
350 }
351}
352if (! -f "$dest/ChangeLog") {
353 copy("$dest/$ENV{'PBCMSLOGFILE'}","$dest/ChangeLog");
354}
355}
356
357=back
358
359=head1 WEB SITES
360
361The main Web site of the project is available at L<http://www.project-builder.org/>. Bug reports should be filled using the trac instance of the project at L<http://trac.project-builder.org/>.
362
363=head1 USER MAILING LIST
364
365None exists for the moment.
366
367=head1 AUTHORS
368
369The Project-Builder.org team L<http://trac.project-builder.org/> lead by Bruno Cornec L<mailto:bruno@project-builder.org>.
370
371=head1 COPYRIGHT
372
373Project-Builder.org is distributed under the GPL v2.0 license
374described in the file C<COPYING> included with the distribution.
375
376=cut
377
3781;
Note: See TracBrowser for help on using the repository browser.