]> cygwin.com Git - cygwin-apps/setup.git/blame - package_db.cc
Suggest URLs for updated setup based on build architecture
[cygwin-apps/setup.git] / package_db.cc
CommitLineData
7939f6d1 1/*
31f0ccce 2 * Copyright (c) 2001, 2003 Robert Collins.
7939f6d1
RC
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * A copy of the GNU General Public License can be found at
10 * http://www.gnu.org/
11 *
12 * Written by Robert Collins <rbtcollins@hotmail.com>
13 *
14 */
15
16/* this is the package database class.
17 * It lists all known packages, including custom ones, ones from a mirror and
18 * installed ones.
19 */
20
7939f6d1
RC
21#include <stdio.h>
22#include <stdlib.h>
23#include <unistd.h>
24#include <strings.h>
2e0aaec9 25#include <algorithm>
45d60587 26#include <sstream>
45e01f23
RC
27#if HAVE_ERRNO_H
28#include <errno.h>
29#endif
7939f6d1
RC
30
31#include "io_stream.h"
32#include "compress.h"
33
34#include "filemanip.h"
f3992588 35#include "package_version.h"
7939f6d1
RC
36#include "package_db.h"
37#include "package_meta.h"
ad646f43 38#include "Exception.h"
2f18f94d 39#include "Generic.h"
f6d6c600
JT
40#include "LogSingleton.h"
41#include "resource.h"
1c159e0a 42#include "libsolv.h"
2602c5c4 43#include "csu_util/version_compare.h"
0c539f7f
JT
44#include "getopt++/BoolOption.h"
45
20f237b4 46static BoolOption MirrorOption (false, 'm', "mirror-mode", IDS_HELPTEXT_MIRROR_MODE);
7939f6d1 47
7939f6d1
RC
48packagedb::packagedb ()
49{
b0cccc59
JT
50}
51
ab67dafa
JT
52void
53packagedb::init ()
54{
55 installeddbread = 0;
56 installeddbver = 0;
0c539f7f
JT
57 prepped = false;
58
ab67dafa
JT
59 packages.clear();
60 sourcePackages.clear();
61 categories.clear();
62 solver.clear();
63 solution.clear();
64 basepkg = packageversion();
65 dependencyOrderedPackages.clear();
66}
67
b0cccc59
JT
68void
69packagedb::read ()
70{
7939f6d1
RC
71 if (!installeddbread)
72 {
b0cccc59
JT
73 /* Read in the local installation database. */
74 io_stream *db = 0;
26922cd2 75 db = io_stream::open ("cygfile:///etc/setup/installed.db", "rt", 0);
82573872 76 installeddbread = 1;
7939f6d1
RC
77 if (!db)
78 return;
f6d6c600 79 char line[1000], pkgname[1000];
7939f6d1 80
24cbae7f
RC
81 if (db->gets (line, 1000))
82 {
f6d6c600
JT
83 /* Look for header line (absent in version 1) */
84 int instsz;
24cbae7f
RC
85 int dbver;
86 sscanf (line, "%s %d", pkgname, &instsz);
f6d6c600
JT
87 if (!strcasecmp (pkgname, "INSTALLED.DB"))
88 dbver = instsz;
24cbae7f
RC
89 else
90 dbver = 1;
91 delete db;
fa0c0d10 92 db = 0;
f6d6c600
JT
93
94 Log (LOG_BABBLE) << "INSTALLED.DB version " << dbver << endLog;
95
96 if (dbver <= 3)
7939f6d1 97 {
f6d6c600
JT
98 char inst[1000];
99
24cbae7f 100 db =
26922cd2 101 io_stream::open ("cygfile:///etc/setup/installed.db", "rt", 0);
f6d6c600
JT
102
103 // skip over already-parsed header line
104 if (dbver >= 2)
24cbae7f 105 db->gets (line, 1000);
f6d6c600 106
24cbae7f 107 while (db->gets (line, 1000))
7939f6d1 108 {
24cbae7f 109 int parseable;
f6d6c600 110 int user_picked = 0;
4e868a01
RC
111 pkgname[0] = '\0';
112 inst[0] = '\0';
4e868a01 113
f6d6c600 114 int res = sscanf (line, "%s %s %d", pkgname, inst, &user_picked);
4e868a01 115
f6d6c600 116 if (res < 3 || pkgname[0] == '\0' || inst[0] == '\0')
4e868a01
RC
117 continue;
118
24cbae7f
RC
119 fileparse f;
120 parseable = parse_filename (inst, f);
121 if (!parseable)
122 continue;
123
1c159e0a
JT
124 SolverPool::addPackageData data;
125 data.reponame = "_installed";
126 data.version = f.ver;
127 data.type = package_binary;
128
129 // very limited information is available from installed.db, so
130 // we put our best guesses here...
131 data.vendor = "cygwin";
132 data.requires = NULL;
20b98f20 133 data.obsoletes = NULL;
9c3e3256 134 data.provides = NULL;
e6433da6 135 data.conflicts = NULL;
1c159e0a
JT
136 data.sdesc = "";
137 data.ldesc = "";
2602c5c4
KB
138 data.stability = TRUST_UNKNOWN;
139 data.spkg = PackageSpecification(std::string(pkgname) + "-src", f.ver);
140
141 // supplement this with sdesc, source, and stability
142 // information from setup.ini, if possible...
143 packageversion pv = findBinaryVersion(PackageSpecification(pkgname, f.ver));
144 PackageDepends dep;
145 PackageDepends obs;
6d23697e
KB
146 PackageDepends prov;
147 PackageDepends conf;
2602c5c4
KB
148 if (pv)
149 {
150 data.sdesc = pv.SDesc();
dff279e2 151 data.ldesc = pv.LDesc();
2602c5c4
KB
152 data.archive = *pv.source();
153 data.stability = pv.Stability();
154 data.spkg_id = pv.sourcePackage();
c59b92e8 155 data.spkg = pv.sourcePackageName();
2602c5c4
KB
156 dep = pv.depends();
157 data.requires = &dep;
158 obs = pv.obsoletes();
159 data.obsoletes = &obs;
6d23697e
KB
160 prov = pv.provides();
161 data.provides = &prov;
162 conf = pv.conflicts();
163 data.conflicts = &conf;
2602c5c4
KB
164 }
165 else
166 // This version is no longer available. It could
167 // be old, or it could be a previous test release
168 // that has been replaced by a new test release.
169 // Try to get some info from the packagemeta.
1c159e0a 170 {
2602c5c4
KB
171 packagemeta *pkgm = findBinary(PackageSpecification(pkgname));
172 if (pkgm)
173 {
174 data.sdesc = pkgm->curr.SDesc();
dff279e2 175 data.ldesc = pkgm->curr.LDesc();
2602c5c4
KB
176 if (pkgm->curr
177 && version_compare (f.ver, pkgm->curr.Canonical_version()) > 0)
178 data.stability = TRUST_TEST;
179 }
1c159e0a
JT
180 }
181
182 packagemeta *pkg = packagedb::addBinary (pkgname, data);
183
184 pkg->set_installed_version (f.ver);
f6d6c600
JT
185
186 if (dbver == 3)
187 pkg->user_picked = (user_picked & 1);
1c159e0a 188
7939f6d1 189 }
24cbae7f 190 delete db;
fa0c0d10 191 db = 0;
24cbae7f
RC
192 }
193 else
f6d6c600
JT
194 {
195 fatal(NULL, IDS_INSTALLEDB_VERSION);
196 }
197
198 installeddbver = dbver;
7939f6d1 199 }
7939f6d1 200 }
1c159e0a
JT
201 solver.internalize();
202}
203
d76f912c
KB
204/* Create the fictitious basepkg */
205void
206packagedb::makeBase()
207{
208 SolverPool::addPackageData data;
209 data.reponame = "_installed";
210 data.version = "0.0-0";
211 data.type = package_binary;
212 data.vendor = "cygwin";
213 data.sdesc = "Ficitious package that requires all Base packages";
214 data.ldesc = "Ficitious package that requires all Base packages";
215 data.obsoletes = NULL;
9c3e3256 216 data.provides = NULL;
e6433da6 217 data.conflicts = NULL;
d76f912c
KB
218 data.stability = TRUST_CURR;
219 // data.spkg = PackageSpecification();
220 // data.spkg_id = packageversion();
221
222 PackageDepends dep;
223 for (std::vector <packagemeta *>::const_iterator i = categories["Base"].begin();
224 i != categories["Base"].end(); i++)
225 {
226 packagemeta *pkg = *i;
227 PackageSpecification *spec = new PackageSpecification(pkg->name);
228 dep.push_back(spec);
229 }
230 data.requires = &dep;
231
232 basepkg = solver.addPackage("base", data);
233 /* We don't register this in packagemeta */
234}
235
45d60587
JT
236/* Create the fictitious windows package */
237void
238packagedb::makeWindows()
239{
240 std::stringstream v;
241 v << OSMajorVersion() << "." << OSMinorVersion() << "." << OSBuildNumber();
242
243 SolverPool::addPackageData data;
244 data.reponame = "_installed";
245 data.version = v.str();
246 data.type = package_binary;
247 data.vendor = "cygwin";
248 data.sdesc = "Ficitious package indicating Windows version";
249 data.ldesc = "Ficitious package indicating Windows version";
250 data.requires = NULL;
251 data.obsoletes = NULL;
252 data.provides = NULL;
253 data.conflicts = NULL;
254 data.stability = TRUST_CURR;
255
256 solver.addPackage("_windows", data);
257 /* We don't register this in packagemeta */
258}
259
1c159e0a
JT
260/* Add a package version to the packagedb */
261packagemeta *
262packagedb::addBinary (const std::string &pkgname,
263 const SolverPool::addPackageData &pkgdata)
264{
265 /* If pkgname isn't already in packagedb, add a packagemeta */
266 packagemeta *pkg = findBinary (PackageSpecification(pkgname));
267 if (!pkg)
268 {
269 pkg = new packagemeta (pkgname);
270 packages.insert (packagedb::packagecollection::value_type(pkgname, pkg));
271 }
272
fa6e8a64
JT
273 /* Create the SolvableVersion and register it in packagemeta */
274 pkg->add_version (pkgdata);
1c159e0a
JT
275
276 return pkg;
277}
278
279packageversion
280packagedb::addSource (const std::string &pkgname,
281 const SolverPool::addPackageData &pkgdata)
282{
283 /* If pkgname isn't already in packagedb, add a packagemeta */
284 packagemeta *pkg = findSource (PackageSpecification(pkgname));
285 if (!pkg)
286 {
287 pkg = new packagemeta (pkgname);
288 sourcePackages.insert (packagedb::packagecollection::value_type(pkgname, pkg));
289 }
290
fa6e8a64
JT
291 /* Create the SolvableVersion and register it in packagemeta */
292 SolvableVersion sv = pkg->add_version (pkgdata);
1c159e0a
JT
293
294 return sv;
7939f6d1
RC
295}
296
7c7034e8
RC
297int
298packagedb::flush ()
299{
300 /* naive approach - just dump the lot */
301 char const *odbn = "cygfile:///etc/setup/installed.db";
302 char const *ndbn = "cygfile:///etc/setup/installed.db.new";
303
b41c2908 304 io_stream::mkpath_p (PATH_TO_FILE, ndbn, 0755);
7c7034e8 305
26922cd2 306 io_stream *ndb = io_stream::open (ndbn, "wb", 0644);
7c7034e8 307
3c054baf 308 // XXX if this failed, try removing any existing .new database?
7c7034e8
RC
309 if (!ndb)
310 return errno ? errno : 1;
311
f6d6c600 312 ndb->write ("INSTALLED.DB 3\n", strlen ("INSTALLED.DB 3\n"));
263157cb 313 for (packagedb::packagecollection::iterator i = packages.begin ();
cfae3b8d 314 i != packages.end (); ++i)
7c7034e8 315 {
263157cb 316 packagemeta & pkgm = *(i->second);
df62e023
RC
317 if (pkgm.installed)
318 {
f6d6c600
JT
319 /*
320 In INSTALLED.DB 3, lines are: 'packagename version flags', where
321 version is encoded in a notional filename for backwards
322 compatibility, and the only currently defined flag is user-picked
323 (bit 0).
324 */
d19f12fd 325 std::string line;
f6d6c600
JT
326 line = pkgm.name + " " +
327 pkgm.name + "-" + std::string(pkgm.installed.Canonical_version()) + ".tar.bz2 " +
328 (pkgm.user_picked ? "1" : "0") + "\n";
d2a3615c 329 ndb->write (line.c_str(), line.size());
df62e023 330 }
7c7034e8
RC
331 }
332
333 delete ndb;
334
335 io_stream::remove (odbn);
336
337 if (io_stream::move (ndbn, odbn))
338 return errno ? errno : 1;
339 return 0;
340}
341
f6d6c600
JT
342void
343packagedb::upgrade()
344{
345 if (installeddbver < 3)
346 {
347 /* Guess which packages were user_picked. This has to take place after
348 setup.ini has been parsed as it needs dependency information. */
349 guessUserPicked();
350 installeddbver = 3;
351 }
352}
353
3c196821
RC
354packagemeta *
355packagedb::findBinary (PackageSpecification const &spec) const
356{
263157cb
JT
357 packagedb::packagecollection::iterator n = packages.find(spec.packageName());
358 if (n != packages.end())
3c196821 359 {
263157cb 360 packagemeta & pkgm = *(n->second);
155eacb6 361 for (std::set<packageversion>::iterator i=pkgm.versions.begin();
3c196821
RC
362 i != pkgm.versions.end(); ++i)
363 if (spec.satisfies (*i))
364 return &pkgm;
365 }
366 return NULL;
367}
368
2602c5c4
KB
369packageversion
370packagedb::findBinaryVersion (PackageSpecification const &spec) const
371{
372 packagedb::packagecollection::iterator n = packages.find(spec.packageName());
373 if (n != packages.end())
374 {
375 packagemeta & pkgm = *(n->second);
155eacb6 376 for (std::set<packageversion>::iterator i=pkgm.versions.begin();
2602c5c4
KB
377 i != pkgm.versions.end(); ++i)
378 if (spec.satisfies (*i))
379 return *i;
380 }
381 return packageversion();
382}
383
3c196821
RC
384packagemeta *
385packagedb::findSource (PackageSpecification const &spec) const
386{
263157cb
JT
387 packagedb::packagecollection::iterator n = sourcePackages.find(spec.packageName());
388 if (n != sourcePackages.end())
3c196821 389 {
263157cb 390 packagemeta & pkgm = *(n->second);
155eacb6 391 for (std::set<packageversion>::iterator i = pkgm.versions.begin();
263157cb 392 i != pkgm.versions.end(); ++i)
3c196821 393 if (spec.satisfies (*i))
263157cb 394 return &pkgm;
3c196821
RC
395 }
396 return NULL;
397}
398
c59b92e8
JT
399packageversion
400packagedb::findSourceVersion (PackageSpecification const &spec) const
401{
402 packagedb::packagecollection::iterator n = sourcePackages.find(spec.packageName());
403 if (n != sourcePackages.end())
404 {
405 packagemeta & pkgm = *(n->second);
155eacb6 406 for (std::set<packageversion>::iterator i = pkgm.versions.begin();
c59b92e8
JT
407 i != pkgm.versions.end(); ++i)
408 if (spec.satisfies (*i))
409 return *i;
410 }
411 return packageversion();
412}
413
65fa35d4
DK
414/* static members */
415
263157cb 416int packagedb::installeddbread = 0;
f6d6c600 417int packagedb::installeddbver = 0;
0c539f7f 418bool packagedb::prepped = false;
263157cb
JT
419packagedb::packagecollection packagedb::packages;
420packagedb::categoriesType packagedb::categories;
421packagedb::packagecollection packagedb::sourcePackages;
422PackageDBActions packagedb::task = PackageDB_Install;
d76f912c 423packageversion packagedb::basepkg;
263157cb 424std::vector <packagemeta *> packagedb::dependencyOrderedPackages;
1c159e0a 425SolverPool packagedb::solver;
1d553f34 426SolverSolution packagedb::solution(packagedb::solver);
ad646f43 427
ad646f43
RC
428#include <stack>
429
430class
431ConnectedLoopFinder
432{
263157cb
JT
433public:
434 ConnectedLoopFinder(void);
435 void doIt(void);
436private:
437 size_t visit (packagemeta *pkg);
438
ad646f43
RC
439 packagedb db;
440 size_t visited;
263157cb
JT
441
442 typedef std::map<packagemeta *, size_t> visitMap;
443 visitMap visitOrder;
444 std::stack<packagemeta *> nodesInStronglyConnectedComponent;
ad646f43
RC
445};
446
447ConnectedLoopFinder::ConnectedLoopFinder() : visited(0)
448{
263157cb
JT
449 for (packagedb::packagecollection::iterator i = db.packages.begin ();
450 i != db.packages.end (); ++i)
451 visitOrder.insert(visitMap::value_type(i->second, 0));
ad646f43
RC
452}
453
454void
455ConnectedLoopFinder::doIt()
456{
457 /* XXX this could be done useing a class to hold both the visitedInIteration and the package
458 * meta reference. Then we could use a range, not an int loop.
459 */
a2488a3c
CV
460 /* We have to expect dependency loops. These loops break the topological
461 sorting which would be a result of the below algorithm looking for
462 strongly connected components in a directed graph. Unfortunately it's
463 not possible to order a directed graph with loops topologially.
c9c19491
CV
464 So we always have to make sure that the really important packages don't
465 introduce dependency loops, since we can't do this from within setup. */
263157cb
JT
466 for (packagedb::packagecollection::iterator i = db.packages.begin ();
467 i != db.packages.end (); ++i)
ad646f43 468 {
263157cb
JT
469 packagemeta &pkg (*(i->second));
470 if (pkg.installed && !visitOrder[&pkg])
471 visit (&pkg);
ad646f43 472 }
157dc2b8 473 Log (LOG_BABBLE) << "Visited: " << visited << " nodes out of "
92ef6cf8
BD
474 << db.packages.size() << " while creating dependency order."
475 << endLog;
ad646f43
RC
476}
477
478static bool
479checkForInstalled (PackageSpecification *spec)
480{
481 packagedb db;
482 packagemeta *required = db.findBinary (*spec);
483 if (!required)
484 return false;
485 if (spec->satisfies (required->installed)
486 && required->desired == required->installed )
487 /* done, found a satisfactory installed version that will remain
488 installed */
489 return true;
490 return false;
491}
492
493size_t
263157cb 494ConnectedLoopFinder::visit(packagemeta *nodeToVisit)
ad646f43 495{
263157cb 496 if (!nodeToVisit->installed)
ad646f43
RC
497 /* Can't visit this node, and it is not less than any visted node */
498 return db.packages.size() + 1;
263157cb
JT
499
500 if (visitOrder[nodeToVisit])
501 return visitOrder[nodeToVisit];
502
ad646f43
RC
503 ++visited;
504 visitOrder[nodeToVisit] = visited;
505
263157cb 506#if DEBUG
157dc2b8 507 Log (LOG_PLAIN) << "visited '" << nodeToVisit->name << "', assigned id " << visited << endLog;
263157cb
JT
508#endif
509
ad646f43
RC
510 size_t minimumVisitId = visited;
511 nodesInStronglyConnectedComponent.push(nodeToVisit);
512
60b4f6ca 513 /* walk through each node */
f717b243
JT
514 const PackageDepends deps = nodeToVisit->installed.depends();
515 PackageDepends::const_iterator dp = deps.begin();
516 while (dp != deps.end())
ad646f43 517 {
60b4f6ca
JT
518 /* check for an installed match */
519 if (checkForInstalled (*dp))
ad646f43
RC
520 {
521 /* we found an installed ok package */
522 /* visit it if needed */
523 /* UGLY. Need to refactor. iterators in the outer would help as we could simply
524 * vist the iterator
525 */
60b4f6ca 526 const packagedb::packagecollection::iterator n = db.packages.find((*dp)->packageName());
263157cb
JT
527
528 if (n == db.packages.end())
60b4f6ca 529 Log (LOG_PLAIN) << "Search for package '" << (*dp)->packageName() << "' failed." << endLog;
ad646f43
RC
530 else
531 {
263157cb 532 packagemeta *nodeJustVisited = n->second;
ad646f43
RC
533 minimumVisitId = std::min (minimumVisitId, visit (nodeJustVisited));
534 }
ad646f43
RC
535 }
536 /* not installed or not available we ignore */
537 ++dp;
538 }
263157cb 539
ad646f43
RC
540 if (minimumVisitId == visitOrder[nodeToVisit])
541 {
263157cb 542 packagemeta *popped;
ad646f43
RC
543 do {
544 popped = nodesInStronglyConnectedComponent.top();
545 nodesInStronglyConnectedComponent.pop();
263157cb 546 db.dependencyOrderedPackages.push_back(popped);
ad646f43
RC
547 /* mark as displayed in a connected component */
548 visitOrder[popped] = db.packages.size() + 2;
549 } while (popped != nodeToVisit);
550 }
263157cb 551
ad646f43 552 return minimumVisitId;
263157cb 553}
ad646f43
RC
554
555PackageDBConnectedIterator
556packagedb::connectedBegin()
557{
558 if (!dependencyOrderedPackages.size())
ad646f43 559 {
92ef6cf8
BD
560 ConnectedLoopFinder doMe;
561 doMe.doIt();
562 std::string s = "Dependency order of packages: ";
563
564 for (std::vector<packagemeta *>::iterator i =
565 dependencyOrderedPackages.begin();
566 i != dependencyOrderedPackages.end(); ++i)
567 s = s + (*i)->name + " ";
157dc2b8 568 Log (LOG_BABBLE) << s << endLog;
ad646f43 569 }
ad646f43
RC
570 return dependencyOrderedPackages.begin();
571}
572
573PackageDBConnectedIterator
574packagedb::connectedEnd()
575{
576 return dependencyOrderedPackages.end();
577}
8c242540 578
31f0ccce
RC
579void
580packagedb::setExistence ()
581{
582 /* binary packages */
583 /* Remove packages that are in the db, not installed, and have no
584 mirror info and are not cached for both binary and source packages. */
263157cb 585 packagedb::packagecollection::iterator i = packages.begin ();
31f0ccce
RC
586 while (i != packages.end ())
587 {
263157cb 588 packagemeta & pkg = *(i->second);
31f0ccce 589 if (!pkg.installed && !pkg.accessible() &&
263157cb
JT
590 !pkg.sourceAccessible() )
591 {
592 packagemeta *pkgm = (*i).second;
593 delete pkgm;
594 packages.erase (i++);
595 }
31f0ccce 596 else
263157cb 597 ++i;
31f0ccce 598 }
263157cb 599
31f0ccce
RC
600#if 0
601 /* remove any source packages which are not accessible */
602 vector <packagemeta *>::iterator i = db.sourcePackages.begin();
603 while (i != db.sourcePackages.end())
604 {
605 packagemeta & pkg = **i;
606 if (!packageAccessible (pkg))
607 {
608 packagemeta *pkgm = *i;
609 delete pkgm;
610 i = db.sourcePackages.erase (i);
611 }
612 else
613 ++i;
614 }
615#endif
616}
2f18f94d
RC
617
618void
619packagedb::fillMissingCategory ()
620{
263157cb
JT
621 for (packagedb::packagecollection::iterator i = packages.begin(); i != packages.end(); i++)
622 {
623 if (i->second->hasNoCategories())
624 i->second->setDefaultCategories();
625
626 i->second->addToCategoryAll();
243f3cc1
JT
627 }
628}
263157cb 629
db9818d7 630void
a59178eb 631packagedb::defaultTrust (SolverTasks &q, SolverSolution::updateMode mode, bool test)
db9818d7 632{
2506055b 633 solution.update(q, mode, test);
549ab3ec 634 solution.augmentTasks(q);
b5baa4ae
JT
635
636 // reflect that task list into packagedb
637 solution.trans2db();
347e23de 638}
db9818d7 639
347e23de
JT
640void
641packagedb::removeEmptyCategories()
642{
cccc9ec3
JT
643 std::vector<std::string> empty;
644
db9818d7
JT
645 for (packagedb::categoriesType::iterator n = packagedb::categories.begin();
646 n != packagedb::categories.end(); ++n)
647 if (!n->second.size())
648 {
cccc9ec3 649 empty.push_back(n->first);
db9818d7 650 }
cccc9ec3
JT
651
652 for (unsigned int i = 0; i < empty.size(); ++i)
653 {
654 packagedb::categoriesType::iterator n = packagedb::categories.find(empty[i]);
655 Log (LOG_BABBLE) << "Removing empty category " << empty[i] << endLog;
656 if (n != packagedb::categories.end())
657 packagedb::categories.erase(n);
658 }
db9818d7 659}
f6d6c600
JT
660
661void
662packagedb::guessUserPicked()
663{
664 /*
665 Assume that any non-base installed package which is a dependency of an
666 installed package wasn't user_picked
667
668 i.e. only installed packages which aren't in the base category, and aren't
669 a dependency of any installed package are user_picked
670 */
671
672 /* First mark all installed non-base packages */
673 for (packagedb::packagecollection::iterator i = packages.begin ();
674 i != packages.end (); ++i)
675 {
676 packagemeta & pkgm = *(i->second);
677
678 if (pkgm.categories.find ("Base") != pkgm.categories.end ())
679 continue;
680
681 if (pkgm.installed)
682 pkgm.user_picked = TRUE;
683 }
684
685 /* Then clear the mark for all dependencies of all installed packages */
686 for (packagedb::packagecollection::iterator i = packages.begin ();
687 i != packages.end (); ++i)
688 {
689 packagemeta & pkgm = *(i->second);
690
691 if (!pkgm.installed)
692 continue;
693
60b4f6ca 694 /* walk through each node */
f717b243
JT
695 const PackageDepends deps = pkgm.installed.depends();
696 std::vector <PackageSpecification *>::const_iterator dp = deps.begin();
697 while (dp != deps.end())
f6d6c600 698 {
60b4f6ca
JT
699 /* check for an installed match */
700 if (checkForInstalled(*dp))
f6d6c600 701 {
60b4f6ca 702 const packagedb::packagecollection::iterator n = packages.find((*dp)->packageName());
f6d6c600
JT
703 if (n != packages.end())
704 {
705 packagemeta *pkgm2 = n->second;
706 pkgm2->user_picked = FALSE;
707 }
708 /* skip to next and clause */
709 ++dp;
710 continue;
711 }
712 ++dp;
713 }
714 }
715}
c59b92e8
JT
716
717void
718packagedb::fixup_source_package_ids()
719{
720 for (packagecollection::iterator i = packages.begin ();
721 i != packages.end (); ++i)
722 {
723 packagemeta &pkgm = *(i->second);
724
155eacb6 725 for (std::set<packageversion>::iterator i = pkgm.versions.begin();
c59b92e8
JT
726 i != pkgm.versions.end(); ++i)
727 {
c59b92e8
JT
728 /* Some packages really have no source, indicated by no [sS]ource:
729 line in setup.ini, which becomes an empty source package name */
730 const std::string spkg = i->sourcePackageName();
731 if (spkg.empty())
732 continue;
733
734 /* Otherwise, we need to find the source package and fix up the source
735 package id*/
736 packageversion spkg_id = findSourceVersion(PackageSpecification(spkg,
737 i->Canonical_version()));
738
739 if (spkg_id)
740 {
3c754445
JT
741 if (i->sourcePackage() != spkg_id)
742 i->fixup_spkg_id(spkg_id);
c59b92e8
JT
743 }
744 else
745 {
746 Log (LOG_BABBLE) << "No source package for '" << i->Name() << "' " << i->Canonical_version() << ", source package name '" << spkg << "'" << endLog;
747 }
748 }
749 }
3c754445
JT
750
751 solver.internalize();
c59b92e8 752}
0c539f7f
JT
753
754void
755packagedb::prep()
756{
757 /* make packagedb ready for use for chooser */
758 if (prepped)
759 return;
760
761 makeBase();
45d60587 762 makeWindows();
0c539f7f
JT
763 read();
764 upgrade();
765 fixup_source_package_ids();
766 removeEmptyCategories();
767
768 /* XXX: this needs to be broken out somewhere where it can do progress
769 reporting, as it can take a long time... */
770 if (source == IDC_SOURCE_DOWNLOAD || source ==IDC_SOURCE_LOCALDIR)
771 packagemeta::ScanDownloadedFiles (MirrorOption);
772
773 setExistence ();
774 fillMissingCategory ();
775
776 prepped = true;
777}
9ca5efb3
KB
778
779void
780packagedb::noChanges ()
781{
782 for (packagecollection::iterator i = packages.begin();
783 i != packages.end(); i++)
784 {
785 packagemeta *pkg = i->second;
6dc6650a
JT
786 pkg->set_action(packagemeta::NoChange_action, pkg->installed);
787 pkg->default_version = pkg->installed;
9ca5efb3
KB
788 }
789}
This page took 0.256249 seconds and 6 git commands to generate.