source: ProjectBuilder/devel/pb-modules/lib/ProjectBuilder/Distribution.pm@ 1505

Last change on this file since 1505 was 1505, checked in by Bruno Cornec, 12 years ago
  • Base.pm: use Carp and Cwd so we can give better error messages. Use new Global::pb_stop_on_error variable to decide whether we should abort on an error. (Eric Anderson from 9c3c696597c49b385df409311b1385d7a394db5a)
  • Distribution.pm: Remove useless redundant check of deps not maching whitespace, improve message since it is likely to call sudo. Skip dependencies that are all whitespace since that leads to errors when running dpkg -L <whitespace> (Eric Anderson from 9c3c696597c49b385df409311b1385d7a394db5a)
File size: 17.9 KB
RevLine 
[11]1#!/usr/bin/perl -w
[2]2#
[11]3# Creates common environment for distributions
[2]4#
5# $Id$
6#
7
[329]8package ProjectBuilder::Distribution;
9
[11]10use strict;
[423]11use Data::Dumper;
[1148]12use ProjectBuilder::Version;
[395]13use ProjectBuilder::Base;
[702]14use ProjectBuilder::Conf;
15use File::Basename;
16use File::Copy;
[2]17
[1148]18# Global vars
[329]19# Inherit from the "Exporter" module which handles exporting functions.
20
[1156]21use vars qw($VERSION $REVISION @ISA @EXPORT);
[329]22use Exporter;
23
24# Export, by default, all the functions into the namespace of
25# any code which uses this module.
26
27our @ISA = qw(Exporter);
[1177]28our @EXPORT = qw(pb_distro_conffile pb_distro_get pb_distro_getlsb pb_distro_installdeps pb_distro_getdeps pb_distro_only_deps_needed pb_distro_setuprepo pb_distro_setuposrepo pb_distro_get_param pb_distro_get_context);
[1156]29($VERSION,$REVISION) = pb_version_init();
[329]30
[391]31=pod
32
33=head1 NAME
34
35ProjectBuilder::Distribution, part of the project-builder.org - module dealing with distribution detection
36
37=head1 DESCRIPTION
38
39This modules provides functions to allow detection of Linux distributions, and giving back some attributes concerning them.
40
41=head1 SYNOPSIS
42
43 use ProjectBuilder::Distribution;
44
45 #
46 # Return information on the running distro
47 #
[1177]48 my $pbos = pb_distro_get_context();
49 print "distro tuple: ".Dumper($pbos->name, $pbos->ver, $pbos->fam, $pbos->type, $pbos->pbsuf, $pbos->pbupd, $pbos->pbins, $pbos->arch)."\n";
[391]50 #
51 # Return information on the requested distro
52 #
[1177]53 my $pbos = pb_distro_get_context("ubuntu-7.10-x86_64");
54 print "distro tuple: ".Dumper($pbos->name, $pbos->ver, $pbos->fam, $pbos->type, $pbos->pbsuf, $pbos->pbupd, $pbos->pbins, $pbos->arch)."\n";
[391]55 #
56 # Return information on the running distro
57 #
[622]58 my ($ddir,$dver) = pb_distro_get();
[391]59
60=head1 USAGE
61
62=over 4
63
[891]64=item B<pb_distro_conffile>
65
66This function returns the mandatory configuration file used for distribution/OS detection
67
68=cut
69
70sub pb_distro_conffile {
71
72return("CCCC/pb.conf");
73}
74
75
[756]76=item B<pb_distro_init>
[395]77
[1177]78This function returns a hash of parameters indicating the distribution name, version, family, type of build system, suffix of packages, update command line, installation command line and architecture of the underlying Linux distribution. The value of the fields may be "unknown" in case the function was unable to recognize on which distribution it is running.
[391]79
[756]80As an example, Ubuntu and Debian are in the same "du" family. As well as RedHat, RHEL, CentOS, fedora are on the same "rh" family.
[1177]81Mandriva, Open SuSE and Fedora have all the same "rpm" type of build system. Ubuntu and Debian have the same "deb" type of build system.
[756]82And "fc" is the extension generated for all Fedora packages (Version will be added by pb).
[1177]83All this information is stored in an external configuration file typically at /etc/pb/pb.conf
[391]84
[756]85When passing the distribution name and version as parameters, the B<pb_distro_init> function returns the parameter of that distribution instead of the underlying one.
[391]86
[756]87Cf: http://linuxmafia.com/faq/Admin/release-files.html
88Ideas taken from http://search.cpan.org/~kerberus/Linux-Distribution-0.14/lib/Linux/Distribution.pm
89
[391]90=cut
91
[756]92
[74]93sub pb_distro_init {
[2]94
[1177]95my $pbos = {
96 'name' => undef,
97 'version' => undef,
98 'arch' => undef,
99 'family' => "unknown",
100 'suffix' => "unknown",
101 'update' => "unknown",
102 'install' => "unknown",
103 'type' => "unknown",
104 'os' => "unknown",
105 'nover' => "false",
106 'rmdot' => "false",
107 };
108$pbos->{'name'} = shift;
109$pbos->{'version'} = shift;
110$pbos->{'arch'} = shift;
[2]111
[869]112# Adds conf file for distribution description
113# the location of the conf file is finalyzed at install time
114# depending whether we deal with package install or tar file install
[891]115pb_conf_add(pb_distro_conffile());
[869]116
[11]117# If we don't know which distribution we're on, then guess it
[1177]118($pbos->{'name'},$pbos->{'version'}) = pb_distro_get() if ((not defined $pbos->{'name'}) || (not defined $pbos->{'version'}));
[2]119
[1159]120# For some rare cases, typically nover ones
[1177]121$pbos->{'name'} = "unknown" if (not defined $pbos->{'name'});
122$pbos->{'version'} = "unknown" if (not defined $pbos->{'version'});
[1159]123
[757]124# Initialize arch
[1177]125$pbos->{'arch'} = pb_get_arch() if (not defined $pbos->{'arch'});
[757]126
[969]127# Dig into the tuple to find the best answer
[1177]128# Do NOT factorize here, as it won't work as of now for hash creation
129$pbos->{'family'} = pb_distro_get_param($pbos,pb_conf_get("osfamily"));
130$pbos->{'type'} = pb_distro_get_param($pbos,pb_conf_get("ostype"));
131($pbos->{'os'},$pbos->{'install'},$pbos->{'suffix'},$pbos->{'nover'},$pbos->{'rmdot'},$pbos->{'update'}) = pb_distro_get_param($pbos,pb_conf_get("os","osins","ossuffix","osnover","osremovedotinver","osupd"));
132#($pbos->{'family'},$pbos->{'type'},$pbos->{'os'},$pbos->{'install'},$pbos->{'suffix'},$pbos->{'nover'},$pbos->{'rmdot'},$pbos->{'update'}) = pb_distro_get_param($pbos,pb_conf_get("osfamily","ostype","os","osins","ossuffix","osnover","osremovedotinver","osupd"));
[867]133
134# Some OS have no interesting version
[1177]135$pbos->{'version'} = "nover" if ((defined $pbos->{'nover'}) && ($pbos->{'nover'} eq "true"));
[867]136
[1167]137# For some OS remove the . in version name for extension
[1177]138my $dver2 = $pbos->{'version'};
139$dver2 =~ s/\.//g if ((defined $pbos->{'rmdot'}) && ($pbos->{'rmdot'} eq "true"));
[867]140
[1177]141if ((not defined $pbos->{'suffix'}) || ($pbos->{'suffix'} eq "")) {
142 # By default suffix is a concatenation of name and version
143 $pbos->{'suffix'} = ".$pbos->{'name'}$dver2"
[11]144} else {
[867]145 # concat just the version to what has been found
[1177]146 $pbos->{'suffix'} = ".$pbos->{'suffix'}$dver2";
[11]147}
148
[867]149# if ($arch eq "x86_64") {
150# $opt="--exclude=*.i?86";
151# }
[1177]152pb_log(2,"DEBUG: pb_distro_init: ".Dumper($pbos)."\n");
[867]153
[1177]154return($pbos);
[11]155}
[23]156
[756]157=item B<pb_distro_get>
[395]158
[756]159This function returns a list of 2 parameters indicating the distribution name and version of the underlying Linux distribution. The value of those 2 fields may be "unknown" in case the function was unable to recognize on which distribution it is running.
[395]160
[1156]161On my home machine it would currently report ("mandriva","2010.2").
[395]162
163=cut
164
[622]165sub pb_distro_get {
[23]166
[869]167# 1: List of files that unambiguously indicates what distro we have
168# 2: List of files that ambiguously indicates what distro we have
169# 3: Should have the same keys as the previous one. If ambiguity, which other distributions should be checked
170# 4: Matching Rg. Expr to detect distribution and version
171my ($single_rel_files, $ambiguous_rel_files,$distro_similar,$distro_match) = pb_conf_get("osrelfile","osrelambfile","osambiguous","osrelexpr");
[23]172
173my $release;
174my $distro;
175
[391]176# Begin to test presence of non-ambiguous files
[23]177# that way we reduce the choice
[24]178my ($d,$r);
[869]179while (($d,$r) = each %$single_rel_files) {
[1027]180 if (defined $ambiguous_rel_files->{$d}) {
181 print STDERR "The key $d is considered as both unambiguous and ambigous.\n";
[1029]182 print STDERR "Please fix your configuration file.\n"
[1027]183 }
[869]184 if (-f "$r" && ! -l "$r") {
185 my $tmp=pb_get_content("$r");
[23]186 # Found the only possibility.
187 # Try to get version and return
[869]188 if (defined ($distro_match->{$d})) {
189 ($release) = $tmp =~ m/$distro_match->{$d}/m;
[23]190 } else {
[1102]191 print STDERR "Unable to find $d version in $r (non-ambiguous)\n";
[23]192 print STDERR "Please report to the maintainer bruno_at_project-builder.org\n";
193 $release = "unknown";
194 }
195 return($d,$release);
196 }
197}
198
[423]199# Now look at ambiguous files
[1027]200# Ubuntu before 10.04 includes a /etc/debian_version file that creates an ambiguity with debian
[423]201# So we need to look at distros in reverse alphabetic order to treat ubuntu always first via lsb
[869]202foreach $d (reverse keys %$ambiguous_rel_files) {
203 $r = $ambiguous_rel_files->{$d};
204 if (-f "$r" && !-l "$r") {
[23]205 # Found one possibility.
206 # Get all distros concerned by that file
[869]207 my $tmp=pb_get_content("$r");
[24]208 my $found = 0;
[869]209 my $ptr = $distro_similar->{$d};
[423]210 pb_log(2,"amb: ".Dumper($ptr)."\n");
[24]211 $release = "unknown";
[869]212 foreach my $dd (split(/,/,$ptr)) {
[423]213 pb_log(2,"check $dd\n");
[23]214 # Try to check pattern
[869]215 if (defined $distro_match->{$dd}) {
216 pb_log(2,"cmp: $distro_match->{$dd} - vs - $tmp\n");
217 ($release) = $tmp =~ m/$distro_match->{$dd}/m;
[24]218 if ((defined $release) && ($release ne "unknown")) {
219 $distro = $dd;
220 $found = 1;
221 last;
222 }
[23]223 }
224 }
225 if ($found == 0) {
[1102]226 print STDERR "Unable to find $d version in $r (ambiguous)\n";
[23]227 print STDERR "Please report to the maintainer bruno_at_project-builder.org\n";
228 $release = "unknown";
229 } else {
230 return($distro,$release);
231 }
232 }
233}
234return("unknown","unknown");
[24]235}
[23]236
[1071]237=item B<pb_distro_getlsb>
[621]238
[1071]239This function returns the 5 lsb values LSB version, distribution ID, Description, release and codename.
240As entry it takes an optional parameter to specify whether the output is short or not.
241
242=cut
243
244sub pb_distro_getlsb {
245
246my $s = shift;
247pb_log(3,"Entering pb_distro_getlsb\n");
248
249my ($ambiguous_rel_files) = pb_conf_get("osrelambfile");
250my $lsbf = $ambiguous_rel_files->{"lsb"};
251
252# LSB has not been configured.
253if (not defined $lsbf) {
254 print STDERR "no lsb entry defined for osrelambfile\n";
255 die "You modified upstream delivery and lost !\n";
256}
257
258if (-r $lsbf) {
259 my $rep = pb_get_content($lsbf);
260 # Create elementary fields
261 my ($c, $r, $d, $i, $l) = ("", "", "", "", "");
262 for my $f (split(/\n/,$rep)) {
263 pb_log(3,"Reading file part ***$f***\n");
264 $c = $f if ($f =~ /^DISTRIB_CODENAME/);
265 $c =~ s/DISTRIB_CODENAME=/Codename:\t/;
266 $r = $f if ($f =~ /^DISTRIB_RELEASE/);
267 $r =~ s/DISTRIB_RELEASE=/Release:\t/;
268 $d = $f if ($f =~ /^DISTRIB_DESCRIPTION/);
269 $d =~ s/DISTRIB_DESCRIPTION=/Description:\t/;
270 $d =~ s/"//g;
271 $i = $f if ($f =~ /^DISTRIB_ID/);
272 $i =~ s/DISTRIB_ID=/Distributor ID:\t/;
273 $l = $f if ($f =~ /^LSB_VERSION/);
274 $l =~ s/LSB_VERSION=/LSB Version:\t/;
275 }
[1177]276 my $regexp = "^[A-z ]*:[\t ]*";
277 $c =~ s/$regexp// if (defined $s);
278 $r =~ s/$regexp// if (defined $s);
279 $d =~ s/$regexp// if (defined $s);
280 $i =~ s/$regexp// if (defined $s);
281 $l =~ s/$regexp// if (defined $s);
[1071]282 return($l, $i, $d, $r, $c);
283} else {
284 print STDERR "Unable to read $lsbf file\n";
285 die "Please report to the maintainer bruno_at_project-builder.org\n";
286}
287}
288
[621]289=item B<pb_distro_installdeps>
290
[1177]291This function install the dependencies required to build the package on a distro.
292Dependencies can be passed as a parameter in which case they are not computed
[621]293
294=cut
295
296sub pb_distro_installdeps {
297
298# SPEC file
299my $f = shift || undef;
[1177]300my $pbos = shift;
[621]301my $deps = shift || undef;
302
303# Protection
[1212]304return if (not defined $pbos->{'install'});
[621]305
[1177]306# Get dependencies in the build file if not forced
[1505]307$deps = pb_distro_getdeps($f,$pbos) if (not defined $deps);
[621]308pb_log(2,"deps: $deps\n");
[623]309return if ((not defined $deps) || ($deps =~ /^\s*$/));
[1505]310
311# This may not be // proof. We should test for availability of repo and sleep if not
312my $cmd = "$pbos->{'install'} $deps";
313pb_system($cmd,"Installing dependencies ($cmd)");
[621]314}
315
316=item B<pb_distro_getdeps>
317
318This function computes the dependencies indicated in the build file and return them as a string of packages to install
319
320=cut
321
322sub pb_distro_getdeps {
323
324my $f = shift || undef;
[1177]325my $pbos = shift;
[621]326
327my $regexp = "";
328my $deps = "";
329my $sep = $/;
330
331# Protection
[1177]332return("") if (not defined $pbos->{'type'});
[899]333return("") if (not defined $f);
334
[1177]335pb_log(3,"entering pb_distro_getdeps: $pbos->{'type'} - $f\n");
336if ($pbos->{'type'} eq "rpm") {
[621]337 # In RPM this could include files, but we do not handle them atm.
338 $regexp = '^BuildRequires:(.*)$';
[1177]339} elsif ($pbos->{'type'} eq "deb") {
[621]340 $regexp = '^Build-Depends:(.*)$';
[1177]341} elsif ($pbos->{'type'} eq "ebuild") {
[621]342 $sep = '"'.$/;
343 $regexp = '^DEPEND="(.*)"\n'
344} else {
345 # No idea
[622]346 return("");
[621]347}
348pb_log(2,"regexp: $regexp\n");
349
350# Preserve separator before using the one we need
351my $oldsep = $/;
352$/ = $sep;
353open(DESC,"$f") || die "Unable to open $f";
354while (<DESC>) {
355 pb_log(4,"read: $_\n");
356 next if (! /$regexp/);
357 chomp();
358 # What we found with the regexp is the list of deps.
359 pb_log(2,"found deps: $_\n");
[681]360 s/$regexp/$1/i;
[698]361 # Remove conditions in the middle and at the end for deb
[931]362 s/\(\s*[><=]+.*\)[^,]*,/,/g;
[698]363 s/\(\s*[><=]+.*$//g;
364 # Same for rpm
[931]365 s/[><=]+[^,]*,/,/g;
[652]366 s/[><=]+.*$//g;
[621]367 # Improve string format (remove , and spaces at start, end and in double
[652]368 s/,/ /g;
[621]369 s/^\s*//;
370 s/\s*$//;
371 s/\s+/ /g;
372 $deps .= " ".$_;
373}
374close(DESC);
375$/ = $oldsep;
376pb_log(2,"now deps: $deps\n");
[1177]377my $deps2 = pb_distro_only_deps_needed($pbos,$deps);
[622]378return($deps2);
379}
380
381
382=item B<pb_distro_only_deps_needed>
383
384This function returns only the dependencies not yet installed
385
386=cut
387
388sub pb_distro_only_deps_needed {
389
[1177]390my $pbos = shift;
[622]391my $deps = shift || undef;
392
[623]393return("") if ((not defined $deps) || ($deps =~ /^\s*$/));
[621]394my $deps2 = "";
395# Avoid to install what is already there
[1505]396foreach my $p (split(/\s+/,$deps)) {
397 next if $p =~ /^\s*$/o;
[1177]398 if ($pbos->{'type'} eq "rpm") {
[621]399 my $res = pb_system("rpm -q --whatprovides --quiet $p","","quiet");
400 next if ($res eq 0);
[1177]401 } elsif ($pbos->{'type'} eq "deb") {
[621]402 my $res = pb_system("dpkg -L $p","","quiet");
403 next if ($res eq 0);
[1177]404 } elsif ($pbos->{'type'} eq "ebuild") {
[621]405 } else {
406 # Not reached
407 }
408 pb_log(2,"found deps2: $p\n");
409 $deps2 .= " $p";
410}
411
412$deps2 =~ s/^\s*//;
413pb_log(2,"now deps2: $deps2\n");
414return($deps2);
415}
416
[1132]417=item B<pb_distro_setuposrepo>
418
419This function sets up potential additional repository for the setup phase
420
421=cut
422
423sub pb_distro_setuposrepo {
424
[1177]425my $pbos = shift;
[1132]426
[1177]427pb_distro_setuprepo_gen($pbos,pb_distro_conffile(),"osrepo");
[1132]428}
429
[702]430=item B<pb_distro_setuprepo>
431
432This function sets up potential additional repository to the build environment
433
434=cut
435
436sub pb_distro_setuprepo {
437
[1177]438my $pbos = shift;
[702]439
[1177]440pb_distro_setuprepo_gen($pbos,"$ENV{'PBDESTDIR'}/pbrc","addrepo");
[1132]441}
442
443=item B<pb_distro_setuprepo_gen>
444
445This function sets up in a generic way potential additional repository
446
447=cut
448
449sub pb_distro_setuprepo_gen {
450
[1177]451my $pbos = shift;
[1132]452my $pbconf = shift || undef;
453my $pbkey = shift || undef;
454
455return if (not defined $pbconf);
456return if (not defined $pbkey);
457my ($addrepo) = pb_conf_read($pbconf,$pbkey);
[702]458return if (not defined $addrepo);
459
[1177]460my $param = pb_distro_get_param($pbos,$addrepo);
[702]461return if ($param eq "");
462
463# Loop on the list of additional repo
464foreach my $i (split(/,/,$param)) {
465
466 my ($scheme, $account, $host, $port, $path) = pb_get_uri($i);
467 my $bn = basename($i);
468
469 # The repo file can be local or remote. download or copy at the right place
470 if (($scheme eq "ftp") || ($scheme eq "http")) {
471 pb_system("wget -O $ENV{'PBTMP'}/$bn $i","Donwloading additional repository file $i");
472 } else {
473 copy($i,$ENV{'PBTMP'}/$bn);
474 }
475
476 # The repo file can be a real file or a package
[1177]477 if ($pbos->{'type'} eq "rpm") {
[702]478 if ($bn =~ /\.rpm$/) {
[721]479 my $pn = $bn;
480 $pn =~ s/\.rpm//;
481 if (pb_system("rpm -q --quiet $pn","","quiet") != 0) {
482 pb_system("sudo rpm -Uvh $ENV{'PBTMP'}/$bn","Adding package to setup repository");
483 }
484 } elsif ($bn =~ /\.repo$/) {
[702]485 # Yum repo
[721]486 pb_system("sudo mv $ENV{'PBTMP'}/$bn /etc/yum.repos.d","Adding yum repository") if (not -f "/etc/yum.repos.d/$bn");
[702]487 } elsif ($bn =~ /\.addmedia/) {
488 # URPMI repo
[721]489 # We should test that it's not already a urpmi repo
[702]490 pb_system("chmod 755 $ENV{'PBTMP'}/$bn ; sudo $ENV{'PBTMP'}/$bn 2>&1 > /dev/null","Adding urpmi repository");
491 } else {
492 pb_log(0,"Unable to deal with repository file $i on rpm distro ! Please report to dev team\n");
493 }
[1177]494 } elsif ($pbos->{'type'} eq "deb") {
[721]495 if (($bn =~ /\.sources.list$/) && (not -f "/etc/apt/sources.list.d/$bn")) {
[711]496 pb_system("sudo mv $ENV{'PBTMP'}/$bn /etc/apt/sources.list.d","Adding apt repository");
497 pb_system("sudo apt-get update","Updating apt repository");
[702]498 } else {
499 pb_log(0,"Unable to deal with repository file $i on deb distro ! Please report to dev team\n");
500 }
501 } else {
502 pb_log(0,"Unable to deal with repository file $i on that distro ! Please report to dev team\n");
503 }
504}
505return;
506}
507
508=item B<pb_distro_get_param>
509
510This function gets the parameter in the conf file from the most precise tuple up to default
511
512=cut
513
514sub pb_distro_get_param {
515
[1177]516my @param;
517my $param;
518my $pbos = shift;
[702]519
[1177]520pb_log(2,"DEBUG: pb_distro_get_param on $pbos->{'name'}-$pbos->{'version'}-$pbos->{'arch'} for ".Dumper(@_)."\n");
521foreach my $opt (@_) {
522 if (defined $opt->{"$pbos->{'name'}-$pbos->{'version'}-$pbos->{'arch'}"}) {
523 $param = $opt->{"$pbos->{'name'}-$pbos->{'version'}-$pbos->{'arch'}"};
524 } elsif (defined $opt->{"$pbos->{'name'}-$pbos->{'version'}"}) {
525 $param = $opt->{"$pbos->{'name'}-$pbos->{'version'}"};
526 } elsif (defined $opt->{"$pbos->{'name'}"}) {
527 $param = $opt->{"$pbos->{'name'}"};
528 } elsif (defined $opt->{$pbos->{'family'}}) {
529 $param = $opt->{$pbos->{'family'}};
530 } elsif (defined $opt->{$pbos->{'type'}}) {
531 $param = $opt->{$pbos->{'type'}};
532 } elsif (defined $opt->{$pbos->{'os'}}) {
533 $param = $opt->{$pbos->{'os'}};
534 } elsif (defined $opt->{"default"}) {
535 $param = $opt->{"default"};
536 } else {
537 $param = "";
538 }
539
540 # Allow replacement of variables inside the parameter such as name, version, arch for rpmbootstrap
541 # but not shell variable which are backslashed
542 if ($param =~ /[^\\]\$/) {
543 pb_log(3,"Expanding variable on $param\n");
[1181]544 eval { $param =~ s/(\$\w+->{\'\w+\'})/$1/eeg };
[1177]545 }
546 push @param,$param;
[702]547}
[974]548
[1177]549pb_log(2,"DEBUG: pb_distro_get_param on $pbos->{'name'}-$pbos->{'version'}-$pbos->{'arch'} returns ==".Dumper(@param)."==\n");
550
551# Return one param in scalar context, an array if not.
552my $nb = @param;
553if ($nb eq 1) {
554 return($param);
555} else {
556 return(@param);
[982]557}
[1177]558}
[974]559
[1177]560=item B<pb_distro_get_context>
[702]561
[1177]562This function gets the OS context passed as parameter and return the corresponding distribution hash
[1402]563If passed undef or "" then auto-detects
[1177]564
565=cut
566
567
568sub pb_distro_get_context {
569
570my $os = shift;
571my $pbos;
572
[1402]573if ((defined $os) && ($os ne "")) {
[1177]574 my ($name,$ver,$darch) = split(/-/,$os);
575 pb_log(0,"Bad format for $os") if ((not defined $name) || (not defined $ver) || (not defined $darch)) ;
576 chomp($darch);
577 $pbos = pb_distro_init($name,$ver,$darch);
578} else {
579 $pbos = pb_distro_init();
[702]580}
[1177]581return($pbos);
582}
[749]583
[395]584=back
[23]585
[395]586=head1 WEB SITES
[23]587
[395]588The 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/>.
589
590=head1 USER MAILING LIST
591
592None exists for the moment.
593
594=head1 AUTHORS
595
596The Project-Builder.org team L<http://trac.project-builder.org/> lead by Bruno Cornec L<mailto:bruno@project-builder.org>.
597
598=head1 COPYRIGHT
599
600Project-Builder.org is distributed under the GPL v2.0 license
601described in the file C<COPYING> included with the distribution.
602
603=cut
604
605
[11]6061;
Note: See TracBrowser for help on using the repository browser.