source: soft/build_system/build_system/mkcd/tags/V3_3_6_1mdk/pm/Mkcd/Group.pm @ 1

Last change on this file since 1 was 1, checked in by fasma, 12 years ago

Initial Import from Mandriva's soft revision 224062 and package revision 45733

File size: 27.9 KB
Line 
1package Mkcd::Group;
2
3my $VERSION = '2.0.2';
4
5use strict;
6use File::NCopy qw(copy);       
7use File::Path;
8use Mkcd::Disc;
9use Mkcd::List;
10use Mkcd::Tools qw(cleanrpmsrate printTable printDiscsFile readBatchFile printBatchFile log_);
11use Mkcd::Package qw(genDeps getSize);
12
13=head1 NAME
14
15Group - mkcd module
16
17=head1 SYNOPSYS
18
19    require Mkcd::Group;
20
21=head1 DESCRIPTION
22
23C<Mkcd::Group> include the mkcd high level disc building routines.
24
25=head1 SEE ALSO
26
27mkcd
28
29=head1 COPYRIGHT
30
31Copyright (C) 2000,2001 MandrakeSoft <warly@mandrakesoft.com>
32
33This program is free software; you can redistribute it and/or modify
34it under the terms of the GNU General Public License as published by
35the Free Software Foundation; either version 2, or (at your option)
36any later version.
37
38This program is distributed in the hope that it will be useful,
39but WITHOUT ANY WARRANTY; without even the implied warranty of
40MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
41GNU General Public License for more details.
42
43You should have received a copy of the GNU General Public License
44along with this program; if not, write to the Free Software
45Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
46
47=cut
48
49use vars qw($config);
50
51sub new {
52    my ($class, $conf) = @_;
53    $config = $conf;
54    bless {
55            config      => $conf,
56            list        => new Mkcd::List($conf),
57            disc        => new Mkcd::Disc($conf)
58       }, $class;
59}
60
61#
62# group structure
63#
64# $group[group number]{list}{rpm/srpm} = { list => [[cd, repname, {options}],[], ...,[]] }
65#
66# $group[group number]
67# brokendeps   => {
68#       rpm_depending_on_non_listed_locales => 1 ,
69#       rpm_which_deps_are_broken => 2,
70#       rpm_exluded_from_conf => 3 }
71# conflict     => { $group_number => 1 } this group have common disc with generic like function with group $group_number.
72# depsrep      => deps repository name
73# depslistid   => [ depslist id ]
74# discdeps     => { cd => { cds it depends on ] }
75# disc_impacted=> { cd => 1 }
76# done         => { rpm => rep number }
77# installDisc  => install disc for this group
78# filelist     => [FILELIST]
79# lang         => { locale1 => 1, locale2 => 1}
80# list_conflict=> { list => { type => { grp => { list => { type => 0/1 }}}}}
81# listmaxrep   => { rpm/srpm => { list => max ordered rep_name number for list list } }
82# listrpm      => { list => [ rpm ] }
83# listsize     => { rpm => { list => total rpm size, ... } }
84# maxrep       => max ordered rep_name number
85# maxsize      => rpm maxsize
86# nodeps       => { list => 1}
87# orderedrep   => { rpm/srpm => { "rep_name" => num } }
88# orderedlist  => { rpm/srpm }
89# pkgdeps      => { package_name => [depslist dependencies ] }
90# pkgrate      => { rpm => rpmsrate_increase }
91# globrpm      => [ "path1/rpm1" ... "pathn/rpmq" ]
92# rejected     => { rpm => [ "error", "message" ] }
93# rep          => { type => list => [ { "path" => [pkg list] } } ]
94# rep_pkg      => { type => { "path" => [pkg list] } }
95# replist      => { $type => [ [ cd, repname, num, [ [related list, related curdir] [] ] ], [], ..., []] }
96# revdeps      => [ reversed depslist ]
97# rpmsrate     => { rpmsrate }
98# rpmsratepath => rpmsrate path
99# score        => [ score weight ]
100# scoredlist   => { rpm_name => score }
101# size         => { rpm_name => [filesize, list number, directory], ... }
102# srpmname     => { srpm => srpm-version-release }
103# sourcerpm    => { rpm => sourcerpm }
104# urpm         => URPM::urpm
105#     option added to urpm
106#     rpmkey
107#     sourcerpm
108#     rpm
109
110#
111#  FIXME
112#
113# Weigh should be put in the first loop with list so that generic
114# groups without installation can get scoring. At present the implementation
115# prevent from using the -o option with generic and as a consequence
116# generic groups will be sorted with (1,1,0) (no install means no rpmsrate)
117#
118
119sub getGroups {
120    my ($config,$lists) = @_;
121    my (@list, %cd, %done, %list, %repname);
122    log_("getGroups\n",$config->{verbose},$config->{LOG},1);
123    foreach my $i (keys %{$lists}) {
124        log_("getGroups: disc $i\n",$config->{verbose},$config->{LOG},2);
125        $cd{$i} = 1;
126        ref $config->{disc}[$i]{fastgeneric} or next;
127        my @l = @{$config->{disc}[$i]{fastgeneric}};
128        foreach (@l) {
129            log_("getGroups: list $_->[1]{list} repname $_->[1]{repname} options (". keys(%{$_->[1]}) .")\n",$config->{verbose},$config->{LOG},3);
130            my $idx;
131            $idx = push @{$list[$_->[1]{list}]}, [$i, $_->[1]{repname}, $_->[1], {}];
132            push @{$repname{$i}{$_->[1]{repname}}}, [ $_->[1]{list}, $idx - 1 ];
133            log_("getGroups: cd $i repname $_->[1]{repname} list $_->[1]{list}\n",$config->{verbose},$config->{LOG},3);
134            $list{$_->[1]{list}} = 1
135        }
136    }
137    my @group;
138    my $g = prepare_cloned_discs(\@group,\%done,$config,$lists);
139    my %donerep;
140    foreach my $i (keys %{$lists}) {
141        my $t = $config->{disc}[$i]{function}{data}{installation};
142        log_("getGroups: disc $i ($t)\n",$config->{verbose},$config->{LOG},2);
143        ref $t and do {
144            log_("getGroups: install disc for group $g => ($i)\n",$config->{verbose},$config->{LOG},3);
145            $group[$g]{installDisc} = $i;
146            $group[$g]{options} = $t->[1];
147            $group[$g]{score} ||= $t->[1]{score} || [1,1,1];
148            ($group[$g]{maxrep}{rpm},$group[$g]{maxlist}{rpm}) = addRepList("rpm",$group[$g],$g,$t->[1]{rpmsdir},$donerep{$g},\%done,\%list,\%cd,\%repname,$i,\@list);
149            ($group[$g]{maxrep}{srpm},$group[$g]{maxlist}{srpm}) = addRepList("srpm",$group[$g],$g,$t->[1]{srpmsdir},$donerep{$g},\%done,\%list,\%cd,\%repname,$i,\@list);
150            $group[$g]{rpmsratepath} ||= $t->[1]{rpmsrate} || "$t->[1]{install}/Mandrake/base/rpmsrate";
151            log_("getGroups: using $group[$g]{rpmsratepath} as rpmsrate file\n",$config->{verbose},$config->{LOG},4);
152            $group[$g]{list} and $group[$g]{depsrep} = join '-', keys %{$group[$g]{list}};
153            log_("getGroups: $group[$g]{depsrep} defined as deps file directory\n",$config->{verbose},$config->{LOG},4);
154            if (ref $t->[1]{lang}) {
155                foreach (@{$t->[1]{lang}}) { $group[$g]{lang}{$_} = 1 }
156            }
157
158            $group[$g]{discdeps}{$i} ||= {};
159            log_("getGroups DEBUG: discdep for group $g => ($group[$g]{discdep})\n",$config->{verbose},$config->{LOG},5);
160            $g++;
161        }
162    }
163    foreach (keys %list) {
164        $list{$_} and next;
165        log_("getGroups: searching alone groups list $_\n",$config->{verbose},$config->{LOG},2);
166        $group[$g]{score} = [1,1,1];
167        $group[$g]{depsrep} = $_;
168        getAlone($list[$_],$group[$g],$g,\%done);
169        $list{$_}++;
170        log_("getGroups: adding a group $g for list $_\n",$config->{verbose},$config->{LOG},2);
171        $g++
172    }
173
174    foreach my $i (keys %{$lists}) {
175        $done{$i} and next;
176        $done{$i} = {};
177        log_("getGroups: searching alone disc disc $i does not handled by any group, setting alone group\n",$config->{verbose},$config->{LOG},2);
178        $group[$g]{discdeps}{$i} ||= {};
179        log_("getGroups: adding a group $g for disc $i\n",$config->{verbose},$config->{LOG},2);
180        $g++
181    }
182   
183    for (my $i; $i < @group; $i++) {
184        $group[$i]{orderedlist}{rpm} ||= [];
185        foreach (@{$group[$i]{orderedlist}{rpm}}) {
186            $group[$i]{list}{$_}{srpm} ||= []
187        }
188        $group[$i]{orderedlist}{srpm} ||= [];
189        log_("getGroups: ordered rpm list for group $i: @{$group[$i]{orderedlist}{rpm}}\n",$config->{verbose},$config->{LOG},2);       
190        log_("getGroups: ordered srpm list for group $i: @{$group[$i]{orderedlist}{srpm}}\n",$config->{verbose},$config->{LOG},2);     
191    }
192   
193    # $config->{verbose} and printTable(\@group);
194    \@group
195}
196
197sub getAlone{
198    my ($list,$group,$g,$done) = @_;
199    my $num = 1;
200    $list or return;
201    my $lnsort = 1;
202    foreach my $l (@{$list}) {
203        my ($cd,$rep,$opt) = @$l;
204        my $ls = $opt->{list};
205        $done->{$cd}{$rep}{$ls} and next;
206        log_("WARNING getAlone: rep $rep of list $_ does not belong to any installation disc, setting alone group $g\n",0,$config->{LOG});
207        my $type = $opt->{source} ? "srpm" : "rpm";
208        log_("getGroups: searching alone groups list $ls cd $cd rep $rep type $type\n",$config->{verbose},$config->{LOG},1);
209        $group->{list}{$ls}{$type} or push @{$group->{orderedlist}{$type}}, $ls;       
210        $group->{listmatrix}{$type}{$ls}{$ls} = 1;
211        $config->{list}[$ls]{disc}{$cd}{$rep}{master} ||= $g;
212        if (! exists $config->{disc}[$cd]{group_master}) {
213            log_("getAlone: setting group $g as master of disc $cd\n",$config->{verbose},$config->{LOG},2);
214            $config->{disc}[$cd]{group_master} = $g;
215            push @{$group->{master_of_disc}}, $cd
216        }
217        $config->{disc}[$cd]{group_list}{$g}{$ls}{$type} = 1;
218        push @{$group->{list}{$ls}{$type}}, $l;
219        if (! $group->{orderedrep}{$type}{"$cd/$rep"}) {
220            $group->{orderedrep}{$type}{"$cd/$rep"} = $num;
221            push @{$group->{replist}{$type}}, [ $cd, $rep, $num++, { $ls => $l } ]
222        }
223        if (!$group->{listsort}{$ls}{$type}) { $group->{listsort}{$ls}{$type} = $lnsort++ };
224        $done->{$cd}{$rep}{$ls}++;
225        log_("getAlone: searching alone groups group $g handle disc $l->[0]\n",$config->{verbose},$config->{LOG},2);
226        # FIXME discdeps may be deprecated for group as hdlists are built without reading real directories.
227        $group->{discdeps}{$l->[0]} ||= {};
228        $group->{disc_impacted}{$l->[0]} = 1;
229        log_("getAlone: setting nodeps flag for group $g list $ls\n",$config->{verbose},$config->{LOG},3) if $opt->{nodeps};
230        $group->{nodeps}{$ls} = $opt->{nodeps};
231        $group->{options}{nodeps} = $opt->{nodeps}
232    }
233}
234
235sub addRepList{
236    my ($type,$group,$g,$replist,$donerep,$done,$list,$disc,$repname,$i,$listTable) = @_;
237    my $num = 1;
238    my $lnsort = 1;
239    foreach (@$replist) {
240        my ($cdlist,$cd,$name) = @$_;
241        my $opt = $_->[3] || {};
242        log_("getGroups: group $g cd $cd repname $name list $cdlist noauto ($opt->{noauto})\n",$config->{verbose},$config->{LOG},2);
243        $donerep->{$type}{$cd}{$name}{$cdlist} and log_("ERROR getGroups: $cd/$name/$cdlist is defined multiple time for group $g, ignoring\n",$config->{verbose},$config->{LOG}) and next;
244        $donerep->{$type}{$cd}{$name}{$cdlist} = 1;
245        $disc->{$cd} or log_("ERROR getGroups: disc $cd not in list, ignoring\n",$config->{verbose},$config->{LOG}) and next;
246        my $ln = $repname->{$cd}{$name};
247        $ln or log_("ERROR getGroups: $name on disc $cd does not exist\n",$config->{verbose},$config->{LOG}) and next;
248        my $replist_list;
249        if (! $group->{orderedrep}{$type}{"$cd/$name"}) {
250            $group->{orderedrep}{$type}{"$cd/$name"} = $num;
251            $replist_list = {};
252            push @{$group->{replist}{$type}}, [ $cd, $name, $num, $replist_list]
253        }
254        $cd != $i and $group->{discdeps}{$i}{$cd}++;
255        $group->{disc_impacted}{$cd} = 1;
256        $cd != $i and log_("getGroups: group $g handle disc $i\n",$config->{verbose},$config->{LOG},2);
257        foreach my $l (@$ln) {
258            my ($ls,$idx) = @$l;
259            next if $cdlist && $cdlist != $ls;
260            next if $replist_list->{$ls};
261            if ($group->{listmaxrep}{$type}{$ls} < $group->{orderedrep}{$type}{"$cd/$name"}) { $group->{listmaxrep}{$type}{$ls} = $group->{orderedrep}{$type}{"$cd/$name"} }
262            $group->{list}{$ls}{$type} or push @{$group->{orderedlist}{$type}}, $ls;   
263            foreach my $lst (@{$group->{orderedlist}{$type}}) { $group->{listmatrix}{$type}{$ls}{$lst} = 1 }
264            foreach my $lst_ent (@$ln) { $group->{listmatrix}{$type}{$ls}{$lst_ent->[0]} = 1 }
265            if (!$group->{listsort}{$ls}{$type}) { $group->{listsort}{$ls}{$type} = $lnsort++ };
266            my $curdir = [$cd, $name, $listTable->[$ls][$idx][2], $opt];
267            push @{$group->{list}{$ls}{$type}}, $curdir;
268            $replist_list->{$ls} = $curdir;
269            if ($opt->{fixed}) {
270                if (!$config->{list}[$ls]{disc}{$cd}{$name}{master}) {
271                    log_("WARNING addRepList: disc $cd rep $name has no master yet\n",$config->{verbose},$config->{LOG},2) if (!$config->{list}[$ls]{disc}{$cd}{$name}{master});
272                    $config->{list}[$ls]{disc}{$cd}{$name}{master} = $g;
273                }
274            } else {
275                # this group is the master for this rep
276                log_("ERROR addRepList: group $g has already a master, overridding\n",$config->{verbose},$config->{LOG},2) if ($config->{list}[$ls]{disc}{$cd}{$name}{master});
277                $config->{list}[$ls]{disc}{$cd}{$name}{master} = $g;
278                if (! exists $config->{disc}[$cd]{group_master}) {
279                    log_("addRepList: setting group $g as master of disc $cd\n",$config->{verbose},$config->{LOG},2);
280                    $config->{disc}[$cd]{group_master} = $g;
281                    push @{$group->{master_of_disc}}, $cd
282                }
283            }
284            $config->{disc}[$cd]{group_list}{$g}{$ls}{$type} = 1;
285            $list->{$ls}++;
286            $done->{$cd}{$name}{$ls}++;
287        }
288        $num++
289    }
290    return ($num,$lnsort)
291}
292
293sub preCheck{
294    # TODO
295    # may not be necessary
296}
297
298sub orderGroups{
299    my ($config,$groups,$lists,$acds) = @_;
300    my @metagroups;
301    my @groupmeta;
302    my $ok;
303    my $check_group = sub {
304        my ($i,$og,$cd) = @_;
305        log_("checking group $i\n",$config->{verbose},$config->{LOG});
306        if (ref $groups->[$i]{master_of_disc}) {
307            if ($groupmeta[$i] == $groupmeta[$og]) {
308                log_("setting group $i different from $og cos of disc $cd\n",$config->{verbose},$config->{LOG});
309                $groupmeta[$i] = $groupmeta[$og] + 1;
310                return 0;
311            }
312        } elsif ($groupmeta[$i] != $groupmeta[$og] && $og == $config->{disc}[$cd]{group_master}) {
313            log_("setting group $i equal to $og cos of disc $cd\n",$config->{verbose},$config->{LOG});
314            $groupmeta[$i] = $groupmeta[$og];
315            return 0
316        }
317        1
318    };
319    # FIXME This algo can create empty metagroups
320    while (!$ok) {
321        log_("orderGroups: ordering metagroups\n",$config->{verbose},$config->{LOG});
322        $ok = 1;
323        my %handled;
324        for (my $i; $i < @$groups; $i++) {
325            if ($groups->[$i]{installDisc}) {
326                $lists->{$groups->[$i]{installDisc}} == 2 or next
327            }
328            log_("Group $i (install disc $groups->[$i]{installDisc})\n",$config->{verbose},$config->{LOG});
329            foreach my $list (keys %{$groups->[$i]{list}}) {
330                foreach my $type (keys %{$groups->[$i]{list}{$list}}) {
331                    foreach my $rep (@{$groups->[$i]{list}{$list}{$type}}) {
332                        my ($cd,$r) = ($rep->[0],$rep->[1]);
333                        $lists->{$cd} == 2 or next;
334                        my $og = $config->{disc}[$cd]{group_master};
335                        $handled{$cd}{$og} = 1;
336                        $og == $i and next;
337                        log_("Master of disc $cd/$r = ($og)\n",$config->{verbose},$config->{LOG});
338                        $ok = $check_group->($i,$og,$cd);
339                    }
340                }
341            }
342        }
343        for (my $i; $i < @$groups; $i++) {
344            foreach my $cd (keys %{$groups->[$i]{disc_prereq}}) {
345                log_("ordreGroups: searching for disc_prereq for group $i disc $cd\n",$config->{verbose},$config->{LOG});
346                foreach (keys %{$handled{$cd}}) {
347                    $_ == $i and next;
348                    log_("ordreGroups: disc $cd handled by group $_\n",$config->{verbose},$config->{LOG});
349                    $ok = $check_group->($i,$_,$cd);
350                }
351            }
352        }
353    }
354    for (my $i; $i < @$groups; $i++) {
355        if ($groups->[$i]{installDisc}) {
356            $lists->{$groups->[$i]{installDisc}} == 2 or next
357        }
358        log_("orderGroups: group $i metagroup $groupmeta[$i]\n",$config->{verbose},$config->{LOG});
359        push @{$metagroups[$groupmeta[$i]][0]}, $groups->[$i];
360    }
361    my %donedisc;
362    foreach (@metagroups) {
363        my %cd;
364        my %cdg;
365        my $i = 1;
366        foreach (@$acds) { $cd{$_} = $i++ }
367        my $grps = $_->[0];
368        my $loop;
369        my $ok = 0;
370        $_->[1] = [];
371        my %groups_conflict;
372        while (!$ok && !$loop) {
373            $ok = 1;
374            foreach my $gn (0 .. @{$grps}) {
375                my $g = $grps->[$gn];
376                log_("orderGroups: group $gn discs " . (join ' ',(keys %{$g->{discdeps}})) . "\n",$config->{verbose},$config->{LOG});
377                foreach my $cd (keys %{$g->{discdeps}}) {
378                    $donedisc{$cd} and next;
379                    $groups_conflict{$cd}{$gn} = 1;
380                    $g->{conflict} = $groups_conflict{$cd};
381                    log_("orderGroups: group $gn conflict with group $gn ($g->{conflict}{$gn})\n",$config->{verbose},$config->{LOG});
382                    log_("orderGroups: orderGroups: disc $cd\n",$config->{verbose},$config->{LOG});
383                    $lists->{$cd} >= 1 or next;
384                    $cdg{$cd} = {};
385                    if (ref $g->{discdeps}{$cd}) {
386                        foreach (keys %{$g->{discdeps}{$cd}}) {
387                            $donedisc{$_} and next;
388                            log_("orderGroups: disc $cd => $_\n",$config->{verbose},$config->{LOG});
389                            $cdg{$cd}{$_} and log_("ERROR: orderGroups: loop in discs dependencies, taking manual order\n",$config->{verbose},$config->{LOG}) and $loop = 1;
390                            $cdg{$cd}{$_} = 1;
391                            $cdg{$_} = {};
392                            if ($cd{$cd} <= $cd{$_}) { 
393                                $cd{$cd} = $cd{$_} + 1;
394                                $ok = 0
395                            }
396                        }
397                    }
398                }
399            }
400        }
401        if ($loop) {
402            foreach my $c (@$acds) { $cdg{$c} and $lists->{$c} == 2 and push @{$_->[1]}, $c and $donedisc{$c} = 1} 
403        } else {
404            my @scds = sort { $cd{$a} <=> $cd{$b} } keys %cdg;
405            foreach my $c (@scds) { $lists->{$c} == 2 and push @{$_->[1]}, $c and $donedisc{$c} = 1}   
406        }
407        log_("orderGroups: disc sorting @{$_->[1]}\n",$config->{verbose},$config->{LOG});
408
409        for (my $i; $i < @$grps; $i++) {
410            foreach my $ls (keys %{$grps->[$i]{list}}) {
411                foreach my $l (keys %{$grps->[$i]{list}}) {
412                    log_("getGroups: group $i listmatrix list $ls - list $l -> $grps->[$i]{listmatrix}{rpm}{$ls}{$l}\n", $config->{verbose}, $config->{LOG})
413                }
414                foreach my $t (keys %{$grps->[$i]{list}{$ls}}) {
415                    my $rep = $grps->[$i]{list}{$ls}{$t};
416                    for (my $grp; $grp < @$grps; $grp++) {
417                        foreach my $list (keys %{$grps->[$grp]{list}}) {
418                            foreach my $type (keys %{$grps->[$grp]{list}{$list}}) {
419                                my $rep2 = $grps->[$grp]{list}{$list}{$type};
420                                foreach my $a (@$rep) {
421                                    if (grep { $a->[0] == $_->[0] } @$rep2) {
422                                        log_("getGroups: group $i list $ls type $t conflicts with group $grp list $list type $type\n", $config->{verbose}, $config->{LOG});     
423                                        $grps->[$i]{list_conflict}{$ls}{$t}{int $grp}{$list}{$type} = 1;
424                                        last
425                                    }
426                                }
427                            }
428                        }
429                    }
430                }
431            }
432        }
433    }
434    # add alone discs
435    my @cd;
436    foreach (keys %donedisc) {
437        $donedisc{$_} or push @cd, $_ 
438    }
439    @cd and push @metagroups, [0,\@cd];
440    \@metagroups
441}
442
443sub getGroupReps{
444    my ($config,$group,$discsFiles) = @_;
445    my $topdir = "$config->{topdir}/build/$config->{name}";
446    my $check_discsFiles = sub {
447        my ($cd,$rep,$listnumber,$rep_nb) = @_;
448        foreach (keys %{$discsFiles->[$cd]{$rep}{$listnumber}}) {
449            my $type = /src$/ ? 'srpm' : 'rpm' ;
450            my $d = $discsFiles->[$cd]{$rep}{$listnumber}{$_};
451            push @{$group->{rep}{$listnumber}[$rep_nb]{$type}{$d}}, $_;
452            push @{$group->{rep_pkg}{srpm}{$d}}, $_
453        }
454    };
455    my $check_dir = sub {
456        my ($dir,$listnumber,$rep_nb,$type,$test) = @_;
457        opendir my $RPMS, $dir or log_("WARNING getGroupReps: cannot open $dir\n", $config->{verbose},$config->{LOG}) and return;
458        foreach (readdir $RPMS) {
459            /($test)\.rpm$/ or next;
460            /(.*)\.rpm$/ or next;
461            push @{$group->{rep}{$listnumber}[$rep_nb]{$type}{$dir}}, $1;
462            push @{$group->{rep_pkg}{$type}{$dir}}, $1
463        }
464    };
465    my $testarch = join '|', keys %{$config->{ARCH}};
466    foreach my $listnumber (keys %{$group->{list}}) {
467        my $ok;
468        foreach (@{$group->{list}{$listnumber}{rpm}}) {
469            !$_->[3]{nodeps} and $ok = 1
470        }
471        if (!$ok) { $group->{nodeps}{$listnumber} = 1 }
472        log_("getGroupReps list $listnumber\n", $config->{verbose}, $config->{LOG});
473        my $rep_nb;
474        foreach (@{$config->{list}[$listnumber]{packages}}) {
475            log_("getGroupReps: @$_ (num $rep_nb)\n", $config->{verbose}, $config->{LOG});
476            my ($dir, @srpms) = @$_;
477            $check_dir->($dir,$listnumber,$rep_nb,'rpm',$testarch);
478            foreach my $d (@srpms) {
479                $check_dir->($d,$listnumber,$rep_nb,'srpm','src');
480            }
481            $rep_nb++
482        }
483       
484        foreach my $d (@{$config->{list}[$listnumber]{virtual}}) {
485            my $cd = $d->{disc};
486            my $path = $d->{path};
487            my $rep = $d->{repname};
488            my $dir = "$topdir/$cd/$path";
489            log_("getGroupReps: virtual disc $cd path $path (num $rep_nb) in $dir\n", $config->{verbose} ,$config->{LOG});
490            if ($discsFiles->[$cd]{$rep}{$listnumber}) {
491                $check_discsFiles->($cd,$rep,$listnumber)
492            } elsif (-d $dir) {
493                $check_dir->($dir,$listnumber,$rep_nb,'rpm',$testarch);
494            } else {
495                log_("ERROR getGroupReps: could not find virtual disc $cd path $path\n", $config->{verbose} ,$config->{LOG});
496                next
497            }
498            $rep_nb++
499        }
500        foreach my $cd (keys %{$config->{list}[$listnumber]{disc}}) {
501            foreach my $rep (keys %{$config->{list}[$listnumber]{disc}{$cd}}) {
502                if ($config->{list}[$listnumber]{disc}{$cd}{$rep}{done}) {
503                    $check_discsFiles->($cd,$rep,$listnumber)
504                }
505                $rep_nb++
506            }
507        }
508    }
509}
510
511# TODO at present clone only do full copy
512sub prepare_cloned_discs {
513    my ($group,$done,$config,$lists) = @_;
514    my $g;
515    foreach my $cd (keys %$lists) {
516        my $loc_conf = $config->{disc}[$cd]{function};
517        if ($loc_conf->{data}{clone}) {
518            log_("prepare_cloned_discs: disc $cd\n", $config->{verbose}, $config->{LOG});
519            # nothing to do, cp -r
520            #if (@{$loc_conf->{list}} == 1 && !$loc_conf->{list}[0][1]{to_del}) {
521            #
522            $loc_conf->{data}{clone}[0][1]{full_copy} = 1;
523            $group->[$g]{disc_impacted}{$cd} = 1;
524            $group->[$g]{discdeps}{$cd} = {};
525            log_("prepare_cloned_discs: setting group $g as master of disc $cd\n", $config->{verbose}, $config->{LOG});
526            $config->{disc}[$cd]{group_master} = int $g;
527            push @{$group->[$g]{master_of_disc}}, $cd;
528           
529            foreach (@{$loc_conf->{data}{clone}}) {
530                $group->[$g]{disc_prereq}{$_->[1]{disc}}++
531            }
532            $done->{$cd} = {};
533            $g++
534            #   next
535            #}
536        }
537    }
538    $g
539}
540
541sub makeWithGroups {
542    my ($class, $lists, $acds) = @_;
543    my $config = $class->{config};
544
545    my $metagroups = orderGroups($config,getGroups($config,$lists),$lists,$acds);
546
547    my (@discsFiles,@cdsize,%size,%graft,%done_deps,%inode);
548    for(my $i; $i < @{$config->{disc}}; $i++) { 
549        $cdsize[$i] = $config->{disc}[$i]{size}; 
550        $size{optimize_space}{disc}{$i} = $cdsize[$i]
551    }
552    foreach (@{$metagroups}) {
553        log_("makeWithGroups: Group listing $_ (@{$_->[1]} -- $_->[0])\n", $config->{verbose}, $config->{LOG})
554    }
555    foreach my $g (@{$metagroups}) {
556        my $cds = $g->[1];
557        my $groups = $g->[0];
558        print { $class->{config}{LOG} } "Group: $g (@{$cds} -- $groups)\n";
559        # FIXME ordering metagroups can lead to empty groups with the -l option
560        $groups or next;
561
562        my (@buildlist, @rpmlist, @needed);
563        my (@groupok,@mkisos);
564        $class->{disc}->makeDiscs(0,$lists,$cds,\%size,\@mkisos,\@discsFiles,\%graft,\%inode);
565
566        for (my $i; $i < @$groups; $i++) {
567            log_("Get already built discs lists\n", $config->{verbose}, $config->{LOG});
568            $groups->[$i]{done} = {};
569            $class->{disc}->getBuiltDiscs($lists, $groups->[$i], \@discsFiles);
570           
571            log_("GROUP $i\n",$config->{verbose},$config->{LOG});
572            getGroupReps($config,$groups->[$i],\@discsFiles);
573           
574            log_("genDeps\n",$config->{verbose},$config->{LOG});
575            if (! $done_deps{$groups->[$i]{depsrep}} && ref $groups->[$i]{rep_pkg}{rpm}) {
576                $done_deps{$groups->[$i]{depsrep}} = genDeps("$config->{tmp}/$config->{name}/$groups->[$i]{depsrep}",$groups->[$i]{rep_pkg}{rpm},$config->{deps},$config->{verbose},$config->{tmp}) or log_("ERROR: genDeps failed\n", $config->{verbose}, $config->{LOG}) and return 0
577            }
578            $groups->[$i]{urpm} = $done_deps{$groups->[$i]{depsrep}};
579
580            log_("getSize\n",$config->{verbose},$config->{LOG});
581            my $redeps = getSize($groups->[$i],$config,$config->{verbose}) or log_("ERROR: getSize failed\n", $config->{verbose}, $config->{LOG}) and return 0;
582           
583            $class->{disc}->guessHdlistSize($groups->[$i], \%size, \@cdsize, $lists, \@discsFiles);
584
585            $groups->[$i]{revdeps} = $class->{list}->reverseDepslist($groups->[$i]);
586
587            ($groups->[$i]{filelist},my $norpmsrate) = $class->{list}->getList($groups->[$i],\@discsFiles);
588
589            if ($groups->[$i]{rpmsratepath}) { 
590                my $outputdir = "$config->{tmp}/build/$config->{name}/$groups->[$i]{installDisc}/Mandrake/base/";
591                -d $outputdir or mkpath $outputdir;
592                my $output = "$outputdir/rpmsrate";
593                log_("cleanrpmsrate $groups->[$i]{rpmsratepath} -> $output\n",$config->{verbose},$config->{LOG});
594                $groups->[$i]{rpmsrate} = cleanrpmsrate($groups->[$i]{rpmsratepath},$output,$norpmsrate, $groups->[$i]{rep_pkg}{rpm}) or log_("ERROR: cleanrpmsrate failed\n", $config->{verbose}, $config->{LOG});
595                $groups->[$i]{options}{rpmsrate} = $output;
596            }
597
598            log_("build_list group $i\n", $config->{verbose}, $config->{LOG});
599            $rpmlist[$i] = $class->{list}->build_list($groups->[$i]) or return 0;
600
601            $class->{list}->scoreList($groups->[$i]) or return 0;
602            $class->{list}->autodeps($groups->[$i],$rpmlist[$i]);
603
604            foreach my $l (keys %{$rpmlist[$i]}) { 
605                my (@force, @need, @superforce, @limit, @b);
606                foreach (keys %{$rpmlist[$i]{$l}}) {
607                    if (!$_) {
608                        log_("ERROR: empty rpmlist key ($rpmlist[$i]{$l}{$_}) KEYS ", $config->{verbose}, $config->{LOG}), keys %{$rpmlist[$i]{$l}{$_}}," \n";
609                        next
610                    }
611                    my $elt = [ $_, $rpmlist[$i]{$l}{$_}, $groups->[$i]{scorelist}{$_} ];
612                    if (!$config->{nodeps} && !$groups->[$i]{options}{nodeps} && !$groups->[$i]{nodeps}{$l} && /basesystem/) { 
613                        $elt->[1]{needed} = 1;
614                        push @superforce, $elt
615                    } elsif ($rpmlist[$i]{$l}{$_}{force}) { 
616                        $elt->[1]{needed} = 1;
617                        push @force, $elt
618                    } elsif ($rpmlist[$i]{$l}{$_}{limit}) {
619                        push @limit, $elt
620                    } else { 
621                        push @b, $elt
622                    }
623                    push @{$needed[$i]{$l}{alap}[$rpmlist[$i]{$l}{$_}{needed}]}, $elt, if $rpmlist[$i]{$l}{$_}{needed};
624                    # used to check which packages has beed rejected
625                    push @{$groups->[$i]{buildlist}}, $_
626                }
627                $buildlist[$i]{$l} = [sort { $a->[2] <=> $b->[2] } @b];
628                unshift @{$buildlist [$i]{$l}}, sort { $a->[2] <=> $b->[2] } @limit;
629                # needed must not be put first.
630                #push @{$buildlist[$i]{$l}}, sort { $a->[2] <=> $b->[2] } @need;
631                push @{$buildlist[$i]{$l}}, sort { $a->[2] <=> $b->[2] } @force;
632                push @{$buildlist[$i]{$l}}, sort { $a->[2] <=> $b->[2] } @superforce
633            }
634        }
635
636        # FIXME it must have a cleaner manner to keep buildlist and do not have
637        # to copy it.
638        my @cb;
639        for(my $i; $i < @buildlist; $i++) { 
640            foreach my $l (keys %{$buildlist[$i]}) { 
641                foreach (@{$buildlist[$i]{$l}}) { 
642                    log_("MakeWithGroups: copying buildlist group $i list $l package $_->[0] score $_->[2] options " . join(' ', keys %{$_->[1]}) . "\n",$config->{verbose},$config->{LOG}); 
643                    push @{$cb[$i]{$l}}, $_
644                }
645            }
646        }
647
648        my $diff = {};
649        my $rejected;
650        my $n=1;
651        $rejected = $class->{list}->buildDiscs($groups,\@cb,\@rpmlist,\@groupok,\%size,\@cdsize,$lists,$cds,\@needed,$diff,$n) if @cb;
652        my $logi;
653        my ($cd,$diff) = $class->{list}->processDiff($groups,$diff,\@discsFiles);
654        my $ok;
655        # discsFiles contains all the rpms, cd contains only the diff
656        $class->{disc}->makeDiscs(1,$lists,$cds,\%size,\@mkisos,\@discsFiles,\%graft,\%inode,$cd) or return 0;
657        $ok = $class->{disc}->checkSize($n,\%size,\@cdsize,$cds,$rejected);
658        #log_("makeWithGroups: disc_building_tries $config->{disc_building_tries}\n",1,$config->{LOG});
659        $ok = 1 if $config->{disc_building_tries} < 2;
660        while (!$ok) {
661            $n++;
662            log_("makeWithGroups: trying to adjust disc size, try $n\n", $config->{verbose}, $config->{LOG});
663            $ok = 1;
664            my @cb;
665            for(my $i; $i < @buildlist; $i++) { 
666                foreach my $l (keys %{$buildlist[$i]}) { 
667                    $cb[$i]{$l} = [];
668                    foreach (@{$buildlist[$i]{$l}}) {
669                        push @{$cb[$i]{$l}}, $_ if ($groups->[$i]{rejected}{$_->[0]})
670                    }
671                }
672            }
673            $rejected = $class->{list}->buildDiscs($groups,\@cb,\@rpmlist,\@groupok,\%size,\@cdsize,$lists,$cds,\@needed,$diff,$n) if @cb;
674            my ($cd,$diff) = $class->{list}->processDiff($groups,$diff,\@discsFiles);
675            $class->{disc}->makeDiscs($n,$lists,$cds,\%size,\@mkisos,\@discsFiles,\%graft,\%inode,$cd) or return 0;
676            $ok = $class->{disc}->checkSize($n,\%size,\@cdsize,$cds,$rejected);
677            !$ok and log_("ERROR: one or more disc are too big or too small, trying to correct\n", $config->{verbose}, $config->{LOG});
678            $n >= $config->{disc_building_tries} and log_("ERROR: could not manage to build discs of correct size, exiting\n", $config->{verbose}, $config->{LOG}) and last
679        }
680        # finally really build the ISOs
681        $class->{disc}->makeDiscs(-1,$lists,$cds,\%size,\@mkisos,\@discsFiles,\%graft,\%inode,$cd) or return 0;
682        for (my $i; $i < @$groups; $i++) {
683            foreach my $list (keys %{$groups->[$i]{list}}) {
684                foreach my $type (keys %{$groups->[$i]{list}{$list}}) {
685                    foreach (@{$groups->[$i]{list}{$list}{$type}}) {
686                        $config->{list}[$list]{disc}{$_->[0]}{$_->[1]}{done} = 1
687                    }
688                }
689            }   
690        }
691    }
692    printDiscsFile($config,\@discsFiles,$config->{print},$metagroups);
693    $config->{printscript} and printBatchFile($config,\@discsFiles,$config->{printscript});
694    1
695}
696
6971
698
699#
700# Changelog
701#
702# 2002 02 21
703# add maxlistmaxrep value to group
704#
705# 2002 03 03
706# change size to an hash that contains disc size and rep size
707#
708# 2002 03 09
709# make group{discrep} and hash not to have loop in disc dependencies when there are multiple repository on one CD
710#
711# 2002 03 14
712# BIG change of group source handling
713#
714# 2002 03 15
715# use new source handling
716#
717# 2002 03 23
718# change getAlone to be able to build generic CDs without installation
719#
720# 2002 06 16   
721# add conflict in group
722#
723# 2002 08 30
724# change reps structure, add pkg and pkg_rep in group
Note: See TracBrowser for help on using the repository browser.