]> cygwin.com Git - cygwin-apps/setup.git/blame - package_meta.cc
Added dpiAwareness element to manifest
[cygwin-apps/setup.git] / package_meta.cc
CommitLineData
7939f6d1 1/*
d55e14fe 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
3c196821 16#include "package_meta.h"
2c539780
MB
17
18#include <string>
19#include <set>
2c539780 20
7939f6d1
RC
21#include <stdio.h>
22#include <stdlib.h>
23#include <unistd.h>
24#include <strings.h>
7c05cfce 25#include "getopt++/StringArrayOption.h"
7939f6d1
RC
26
27#include "io_stream.h"
28#include "compress.h"
29
30#include "filemanip.h"
aa1e3b4d 31#include "LogSingleton.h"
fa0c0d10
RC
32/* io_stream needs a bit of tweaking to get rid of this. TODO */
33#include "mount.h"
34/* this goes at the same time */
35#include "win32.h"
7939f6d1 36
8e9aa511 37#include "script.h"
cbfc4215 38#include "package_db.h"
7939f6d1 39
3c196821 40#include <algorithm>
b45097bf
JT
41#include <functional>
42
31f0ccce 43#include "Generic.h"
c58b62ea
JT
44#include "download.h"
45#include "Exception.h"
46#include "resource.h"
3c196821 47
20f237b4
JT
48static StringArrayOption DeletePackageOption ('x', "remove-packages", IDS_HELPTEXT_REMOVE_PACKAGES);
49static StringArrayOption DeleteCategoryOption ('c', "remove-categories", IDS_HELPTEXT_REMOVE_CATEGORIES);
50static StringArrayOption PackageOption ('P', "packages", IDS_HELPTEXT_PACKAGES);
51static StringArrayOption CategoryOption ('C', "categories", IDS_HELPTEXT_CATEGORIES);
a667a8b2 52bool hasManualSelections = 0;
0407753c 53
7c6ef2c3
RC
54/*****************/
55
916f2b80 56/* Return an appropriate category caption given the action */
f34a20e7 57unsigned int
9ae1ac43 58packagemeta::action_caption (_actions _value)
7e8fc33c
RC
59{
60 switch (_value)
61 {
916f2b80 62 case NoChange_action:
f34a20e7 63 return IDS_ACTION_DEFAULT;
9ae1ac43 64 case Install_action:
f34a20e7 65 return IDS_ACTION_INSTALL;
9ae1ac43 66 case Reinstall_action:
f34a20e7 67 return IDS_ACTION_REINSTALL;
9ae1ac43 68 case Uninstall_action:
f34a20e7 69 return IDS_ACTION_UNINSTALL;
7e8fc33c 70 }
9ae1ac43 71
f34a20e7 72 return IDS_ACTION_UNKNOWN;
7e8fc33c
RC
73}
74
3c196821 75packagemeta::packagemeta (packagemeta const &rhs) :
4c46018d 76 name (rhs.name),
405d7186 77 categories (rhs.categories), versions (rhs.versions),
ec7c556d 78 installed (rhs.installed),
561005e2
JT
79 curr (rhs.curr),
80 exp (rhs.exp),
8aac1adc 81 desired (rhs.desired)
3c196821 82{
155eacb6 83
3c196821
RC
84}
85
0e43a3f8 86template<class T> struct removeCategory
0cf68afd
RC
87{
88 removeCategory(packagemeta *pkg) : _pkg (pkg) {}
155eacb6 89 void operator() (T x)
0cf68afd 90 {
155eacb6 91 std::vector <packagemeta *> &aList = packagedb::categories[x];
0cf68afd
RC
92 aList.erase (find (aList.begin(), aList.end(), _pkg));
93 }
94 packagemeta *_pkg;
95};
96
97
7c6ef2c3
RC
98packagemeta::~packagemeta()
99{
1eb2461a 100 for_each (categories.begin (), categories.end (), removeCategory<std::string> (this));
405d7186
RC
101 categories.clear ();
102 versions.clear ();
7c6ef2c3
RC
103}
104
fa6e8a64
JT
105SolvableVersion
106packagemeta::add_version (const SolverPool::addPackageData &inpkgdata)
7939f6d1 107{
fa6e8a64
JT
108 SolverPool::addPackageData pkgdata = inpkgdata;
109
110 packageversion *v = NULL;
111 switch (pkgdata.stability)
112 {
113 case TRUST_CURR:
114 v = &(this->curr);
115 break;
116 case TRUST_TEST:
117 v = &(this->exp);
118 break;
119 default:
120 break;
121 }
122
1c159e0a 123 /*
fa6e8a64 124 If a packageversion for the same version number is already present, allow
1c159e0a
JT
125 this version to replace it.
126
127 There is a problem where multiple repos provide a package. It's never been
128 clear which repo should win. With this implementation, the last one added
129 will win.
130
131 We rely on this by adding packages from installed.db last.
132 */
133
155eacb6 134 for (std::set <packageversion>::iterator i = versions.begin();
fa6e8a64
JT
135 i != versions.end();
136 i++)
1c159e0a 137 {
fa6e8a64
JT
138 if (i->Canonical_version() != pkgdata.version)
139 continue;
140
141 if (pkgdata.vendor == i->Vendor())
142 {
143 /* Merge the site-list from any existing packageversion with the same
144 repository 'release:' label */
145 pkgdata.archive.sites.insert(pkgdata.archive.sites.end(),
146 i->source()->sites.begin(),
147 i->source()->sites.end());
148
149 /* Installed packages do not supersede repo packages */
150 if (pkgdata.reponame != "_installed")
151 {
152 /* Ensure a stability level doesn't point to a version we're about
153 to remove */
154 if (v && (*v == *i))
155 *v = packageversion();
156
157 i->remove();
158 }
159 }
160 else
161 {
162 /* Otherwise... if we had a way to set repo priorities, that could be
163 used to control which packageversion the solver picks. For the
164 moment, just warn that you might not be getting what you think you
3103d940
AG
165 should...
166
167 (suppress this for installed packages, as we are only guessing the
168 vendor, currently)
169 */
170 if (pkgdata.reponame != "_installed")
171 {
172 Log (LOG_PLAIN) << "Version " << pkgdata.version << " of package " <<
173 name << " is present in releases labelled " << pkgdata.vendor <<
174 " and " << i->Vendor() << endLog;
175 }
fa6e8a64
JT
176 }
177
1c159e0a 178 versions.erase(i);
fa6e8a64
JT
179
180 break;
1c159e0a
JT
181 }
182
fa6e8a64
JT
183 /* Create the SolvableVersion */
184 packagedb db;
185 SolvableVersion thepkg = db.solver.addPackage(name, pkgdata);
186
1c159e0a
JT
187 /* Add the version */
188 std::pair<std::set <packageversion>::iterator, bool> result = versions.insert (thepkg);
189
190 if (!result.second)
191 Log (LOG_PLAIN) << "Failed to add version " << thepkg.Canonical_version() << " in package " << name << endLog;
192#ifdef DEBUG
193 else
194 Log (LOG_PLAIN) << "Added version " << thepkg.Canonical_version() << " in package " << name << endLog;
195#endif
196
197 /* Record the highest version at a given stability level */
1c159e0a
JT
198 if (v)
199 {
200 /* Any version is always greater than no version */
201 int comparison = 1;
202 if (*v)
203 comparison = SolvableVersion::compareVersions(thepkg, *v);
204
205#ifdef DEBUG
206 if ((bool)(*v))
207 Log (LOG_BABBLE) << "package " << thepkg.Name() << " comparing versions " << thepkg.Canonical_version() << " and " << v->Canonical_version() << ", result was " << comparison << endLog;
208#endif
209
210 if (comparison >= 0)
211 {
212 *v = thepkg;
213 }
214 }
fa6e8a64
JT
215
216 return thepkg;
7939f6d1
RC
217}
218
bacef89a
JT
219const packageversion *
220packagemeta::findVersion(std::string &version) const
221{
222 for (std::set <packageversion>::iterator i = versions.begin();
223 i != versions.end();
224 i++)
225 {
226 if (i->Canonical_version() == version)
227 return &(*i);
228 }
229
230 return NULL;
231}
232
d2e0c29e
JT
233bool
234packagemeta::isBlacklisted(const packageversion &version) const
235{
236 for (std::set<std::string>::iterator i = version_blacklist.begin();
237 i != version_blacklist.end();
238 i++)
239 {
240 if (i->compare(version.Canonical_version()) == 0)
241 return true;
242 }
243
244 return false;
245}
246
7939f6d1 247void
1c159e0a 248packagemeta::set_installed_version (const std::string &version)
7939f6d1 249{
155eacb6 250 for (std::set<packageversion>::iterator i = versions.begin(); i != versions.end(); i++)
1c159e0a
JT
251 {
252 if (version.compare(i->Canonical_version()) == 0)
253 {
254 installed = *i;
255
256 /* and mark as Keep */
257 desired = installed;
258 }
259 }
7939f6d1 260}
fa0c0d10 261
bb849dbd 262void
1eb2461a 263packagemeta::add_category (const std::string& cat)
bb849dbd 264{
0cf68afd
RC
265 if (categories.find (cat) != categories.end())
266 return;
bb849dbd 267 /* add a new record for the package list */
0cf68afd
RC
268 packagedb::categories[cat].push_back (this);
269 categories.insert (cat);
bb849dbd
RC
270}
271
0e43a3f8 272struct StringConcatenator {
1eb2461a 273 StringConcatenator(std::string aString) : gap(aString){}
155eacb6 274 void operator()(const std::string& aString)
69711722
RC
275 {
276 if (result.size() != 0)
277 result += gap;
278 result += aString;
279 }
1eb2461a
MB
280 std::string result;
281 std::string gap;
0e43a3f8
JT
282
283 typedef const std::string argument_type;
69711722
RC
284};
285
1eb2461a 286const std::string
bfdf6ac2
MB
287packagemeta::getReadableCategoryList () const
288{
155eacb6 289 return for_each(categories.begin(), categories.end(),
69711722 290 visit_if (
b45097bf
JT
291 StringConcatenator(", "),
292 std::bind(std::not_equal_to<std::string>(), "All", std::placeholders::_1))
293 ).visitor.result;
bfdf6ac2
MB
294}
295
513f7781 296static void
155eacb6 297parseNames (std::set<std::string> &parsed, std::string &option)
513f7781 298{
155eacb6 299 std::string tname;
513f7781
DK
300
301 /* Split up the packages listed in the option. */
155eacb6
AG
302 std::string::size_type loc = option.find (",", 0);
303 while (loc != std::string::npos)
513f7781
DK
304 {
305 tname = option.substr (0, loc);
306 option = option.substr (loc + 1);
307 parsed.insert (tname);
308 loc = option.find (",", 0);
309 }
310
311 /* At this point, no "," exists in option. Don't add
312 an empty string if the entire option was empty. */
313 if (option.length ())
314 parsed.insert (option);
315}
316
0af398cf
JT
317static void
318validatePackageNames (std::set<std::string> &names)
319{
320 packagedb db;
321 for (std::set<std::string>::iterator n = names.begin();
322 n != names.end();
323 ++n)
324 {
325 if (db.packages.find(*n) == db.packages.end())
326 {
327 Log(LOG_PLAIN) << "Package '" << *n << "' not found." << endLog;
328 }
329 }
330}
331
bacef89a 332bool packagemeta::isManuallyWanted(packageversion &version) const
0407753c
DK
333{
334 static bool parsed_yet = false;
bacef89a 335 static std::map<std::string, std::string> parsed_names;
a667a8b2 336 hasManualSelections |= parsed_names.size ();
155eacb6 337 static std::set<std::string> parsed_categories;
a667a8b2 338 hasManualSelections |= parsed_categories.size ();
0407753c 339 bool bReturn = false;
513f7781 340
155eacb6 341 /* First time through, we parse all the names out from the
0407753c
DK
342 option string and store them away in an STL set. */
343 if (!parsed_yet)
344 {
155eacb6
AG
345 std::vector<std::string> packages_options = PackageOption;
346 std::vector<std::string> categories_options = CategoryOption;
bacef89a
JT
347
348 std::set<std::string> items;
155eacb6 349 for (std::vector<std::string>::iterator n = packages_options.begin ();
7c05cfce
JT
350 n != packages_options.end (); ++n)
351 {
bacef89a 352 parseNames (items, *n);
7c05cfce 353 }
bacef89a
JT
354
355 std::set<std::string> packages;
356 /* Separate any 'package=version' into package and version parts */
357 for (std::set<std::string>::iterator n = items.begin();
358 n != items.end();
359 ++n)
360 {
361 std::string package;
362 std::string version;
363 std::string::size_type loc = n->find ("=", 0);
364 if (loc != std::string::npos)
365 {
366 package = n->substr(0, loc);
367 version = n->substr(loc+1);
368 }
369 else
370 {
371 package = *n;
372 version = "";
373 }
374 Log (LOG_BABBLE) << "package: " << package << " version: " << version << endLog;
375 parsed_names[package] = version;
376 packages.insert(package);
377 }
378
379 validatePackageNames (packages);
380
155eacb6 381 for (std::vector<std::string>::iterator n = categories_options.begin ();
7c05cfce
JT
382 n != categories_options.end (); ++n)
383 {
384 parseNames (parsed_categories, *n);
385 }
0407753c 386 parsed_yet = true;
0407753c 387 }
513f7781
DK
388
389 /* Once we've already parsed the option string, just do
0407753c 390 a lookup in the cache of already-parsed names. */
bacef89a
JT
391 std::map<std::string, std::string>::iterator i = parsed_names.find(name);
392 if (i != parsed_names.end())
393 {
394 bReturn = true;
395
396 /* Wanted version is unspecified */
397 version = packageversion();
398
399 /* ... unless a version was explicitly specified */
400 std::string v = i->second;
401 if (!v.empty())
402 {
403 const packageversion *pv = findVersion(v);
404 if (pv)
405 version = *pv;
406 else
407 Log (LOG_PLAIN) << "package: " << name << " version: " << v << " not found" << endLog;
408 }
409 }
513f7781 410
155eacb6 411 /* If we didn't select the package manually, did we select any
513f7781
DK
412 of the categories it is in? */
413 if (!bReturn && parsed_categories.size ())
414 {
415 std::set<std::string, casecompare_lt_op>::iterator curcat;
416 for (curcat = categories.begin (); curcat != categories.end (); curcat++)
417 if (parsed_categories.find (*curcat) != parsed_categories.end ())
418 {
0c83a709 419 Log (LOG_BABBLE) << "Found category " << *curcat << " in package " << name << endLog;
bacef89a 420 version = packageversion();
513f7781
DK
421 bReturn = true;
422 }
423 }
155eacb6 424
0407753c 425 if (bReturn)
0c83a709 426 Log (LOG_BABBLE) << "Added manual package " << name << endLog;
0407753c
DK
427 return bReturn;
428}
429
a667a8b2
CV
430bool packagemeta::isManuallyDeleted() const
431{
432 static bool parsed_yet = false;
155eacb6 433 static std::set<std::string> parsed_delete;
a667a8b2 434 hasManualSelections |= parsed_delete.size ();
155eacb6 435 static std::set<std::string> parsed_delete_categories;
a667a8b2
CV
436 hasManualSelections |= parsed_delete_categories.size ();
437 bool bReturn = false;
438
439 /* First time through, we parse all the names out from the
440 option string and store them away in an STL set. */
441 if (!parsed_yet)
442 {
155eacb6
AG
443 std::vector<std::string> delete_options = DeletePackageOption;
444 std::vector<std::string> categories_options = DeleteCategoryOption;
445 for (std::vector<std::string>::iterator n = delete_options.begin ();
a667a8b2
CV
446 n != delete_options.end (); ++n)
447 {
448 parseNames (parsed_delete, *n);
449 }
0af398cf 450 validatePackageNames (parsed_delete);
155eacb6 451 for (std::vector<std::string>::iterator n = categories_options.begin ();
a667a8b2
CV
452 n != categories_options.end (); ++n)
453 {
454 parseNames (parsed_delete_categories, *n);
455 }
456 parsed_yet = true;
457 }
458
459 /* Once we've already parsed the option string, just do
460 a lookup in the cache of already-parsed names. */
461 bReturn = parsed_delete.find(name) != parsed_delete.end();
462
463 /* If we didn't select the package manually, did we select any
464 of the categories it is in? */
465 if (!bReturn && parsed_delete_categories.size ())
466 {
467 std::set<std::string, casecompare_lt_op>::iterator curcat;
468 for (curcat = categories.begin (); curcat != categories.end (); curcat++)
469 if (parsed_delete_categories.find (*curcat) != parsed_delete_categories.end ())
470 {
0c83a709 471 Log (LOG_BABBLE) << "Found category " << *curcat << " in package " << name << endLog;
a667a8b2
CV
472 bReturn = true;
473 }
474 }
475
476 if (bReturn)
0c83a709 477 Log (LOG_BABBLE) << "Deleted manual package " << name << endLog;
a667a8b2
CV
478 return bReturn;
479}
480
1eb2461a 481const std::string
df62e023 482packagemeta::SDesc () const
bb849dbd 483{
155eacb6 484 for (std::set<packageversion>::iterator i = versions.begin(); i != versions.end(); i++)
1c159e0a
JT
485 {
486 if (i->SDesc().size())
487 return i->SDesc ();
488 }
489
490 return std::string();
491}
cbfc4215 492
e8f2c078
JT
493static bool
494hasLDesc(packageversion const &pkg)
495{
496 return pkg.LDesc().size();
497}
498
499const std::string
500packagemeta::LDesc () const
501{
502 std::set<packageversion>::iterator i = find_if (versions.begin(), versions.end(), hasLDesc);
503 if (i == versions.end())
504 return std::string();
505 return i->LDesc ();
506};
507
cbfc4215 508/* Return an appropriate caption given the current action. */
f34a20e7 509std::wstring
d55e14fe 510packagemeta::action_caption () const
cbfc4215 511{
a51575e3
JT
512 switch (_action)
513 {
514 case Uninstall_action:
f34a20e7 515 return LoadStringW(IDS_ACTION_UNINSTALL);
a51575e3
JT
516 case NoChange_action:
517 if (!desired)
f34a20e7 518 return LoadStringW(IDS_ACTION_SKIP);
a51575e3
JT
519 if (desired.sourcePackage() && srcpicked())
520 /* FIXME: Redo source should come up if the tarball is already present locally */
f34a20e7
JT
521 return LoadStringW(IDS_ACTION_SOURCE);
522 return LoadStringW(IDS_ACTION_KEEP);
a51575e3 523 case Reinstall_action:
f34a20e7 524 return LoadStringW(packagedb::task == PackageDB_Install ? IDS_ACTION_REINSTALL : IDS_ACTION_RETRIEVE);
a51575e3 525 case Install_action:
f34a20e7 526 return string_to_wstring(desired.Canonical_version());
a51575e3 527 }
f34a20e7 528 return LoadStringW(IDS_ACTION_UNKNOWN);
cbfc4215
RC
529}
530
8ba85a54
JT
531void
532packagemeta::select_action (int id, trusts const deftrust)
533{
534 if (id <= 0)
535 {
536 // Install a specific version
537 std::set<packageversion>::iterator i = versions.begin ();
538 for (int j = -id; j > 0; j--)
539 i++;
540
30d0e660 541 set_action(Install_action, *i, true);
8ba85a54
JT
542 }
543 else
544 {
916f2b80 545 if (id == packagemeta::NoChange_action)
8ba85a54 546 set_action((packagemeta::_actions)id, installed);
63a2c908
CF
547 else if (id == packagemeta::Install_action)
548 {
549 // Ignore install request if the default version is not accessible.
550 // This assumes that all available versions are already known.
551 // This is not always the case when set_action is called directly.
552 packageversion v = trustp (true, deftrust);
553 if (v.accessible ())
554 set_action(Install_action, v, true);
555 else
556 set_action(NoChange_action, installed);
557 }
8ba85a54 558 else
dbd295e7 559 set_action((packagemeta::_actions)id, trustp (true, deftrust), true);
8ba85a54 560 }
8ba85a54
JT
561}
562
76dc99c1
JT
563// toggle between the currently installed version (or uninstalled, if not
564// installed), and the naively preferred version (the highest non-test version)
565void
566packagemeta::toggle_action ()
567{
568 if (desired != installed)
569 {
916f2b80 570 set_action(NoChange_action, installed);
76dc99c1
JT
571 }
572 else
573 {
574 packageversion naively_preferred;
575 std::set<packageversion>::iterator i = versions.begin ();
576 for (i = versions.begin (); i != versions.end (); ++i)
577 if (!packagedb::solver.is_test_package(*i))
578 naively_preferred = *i;
579
30d0e660 580 set_action(Install_action, naively_preferred, true);
76dc99c1
JT
581 }
582}
583
8ba85a54
JT
584ActionList *
585packagemeta::list_actions(trusts const trust)
586{
a781f823 587 // build the list of possible actions
8ba85a54
JT
588 ActionList *al = new ActionList();
589
f34a20e7
JT
590 al->add(IDS_ACTION_UNINSTALL, (int)Uninstall_action, (_action == Uninstall_action), bool(installed));
591 al->add(IDS_ACTION_SKIP, (int)NoChange_action, (_action == NoChange_action) && !installed, !installed);
8ba85a54
JT
592
593 std::set<packageversion>::iterator i;
594 for (i = versions.begin (); i != versions.end (); ++i)
595 {
596 if (*i == installed)
597 {
f34a20e7
JT
598 al->add(IDS_ACTION_KEEP, (int)NoChange_action, (_action == NoChange_action), TRUE);
599 al->add(packagedb::task == PackageDB_Install ? IDS_ACTION_REINSTALL : IDS_ACTION_RETRIEVE,
a781f823 600 (int)Reinstall_action, (_action == Reinstall_action), TRUE);
8ba85a54
JT
601 }
602 else
603 {
f34a20e7 604 std::wstring label = string_to_wstring(i->Canonical_version());
d76a9ffd 605 if (packagedb::solver.is_test_package(*i))
f34a20e7 606 label += L" (Test)";
d76a9ffd 607 al->add(label,
8ba85a54 608 -std::distance(versions.begin (), i),
a781f823 609 (_action == Install_action) && (*i == desired),
8ba85a54
JT
610 TRUE);
611 }
612 }
613
614 return al;
615}
616
7e8fc33c
RC
617// Set a particular type of action.
618void
dbd295e7
JT
619packagemeta::set_action (_actions action, packageversion const &default_version,
620 bool useraction)
7e8fc33c 621{
916f2b80 622 if (action == NoChange_action)
7e8fc33c 623 {
916f2b80 624 // if installed, keep
7e8fc33c 625 if (installed
405d7186 626 || categories.find ("Base") != categories.end ()
fb5ecc5d 627 || categories.find ("Orphaned") != categories.end ())
7e8fc33c
RC
628 {
629 desired = default_version;
630 if (desired)
631 {
4209699d
JT
632 pick (desired != installed);
633 srcpick (false);
7e8fc33c
RC
634 }
635 }
636 else
6dc6650a
JT
637 {
638 // else, if not installed, skip
639 desired = packageversion ();
640 pick(false);
641 }
7e8fc33c
RC
642 }
643 else if (action == Install_action)
644 {
645 desired = default_version;
63a2c908 646 // If desired is empty, it will be set to the solver's preferred version later.
849c42ad
JT
647 if (desired)
648 {
649 if (desired != installed)
650 if (desired.accessible ())
651 {
652 /* Memorize the fact that the user picked to install this package at least once. */
653 if (useraction)
654 user_picked = true;
655
656 pick (true);
657 srcpick (false);
658 }
659 else
660 {
661 pick (false);
662 srcpick (true);
663 }
664 else
665 {
666 action = NoChange_action;
667 pick (false);
668 srcpick (false);
669 }
670 }
7e8fc33c
RC
671 }
672 else if (action == Reinstall_action)
673 {
674 desired = installed;
054697c2 675 if (desired.accessible ())
7e8fc33c 676 {
4209699d
JT
677 pick (true);
678 srcpick (false);
7e8fc33c 679 }
d997f4cf
JT
680 else
681 {
682 action = NoChange_action;
683 pick (false);
684 srcpick (false);
685 }
7e8fc33c
RC
686 }
687 else if (action == Uninstall_action)
688 {
3c196821 689 desired = packageversion ();
c99e4c14
CF
690 pick (false);
691 srcpick (false);
692 if (!installed)
693 action = NoChange_action;
3c196821 694 }
8efd971b
JT
695
696 _action = action;
3c196821
RC
697}
698
4209699d
JT
699bool
700packagemeta::picked () const
701{
702 return _picked;
703}
704
705void
706packagemeta::pick (bool picked)
707{
708 _picked = picked;
709
710 // side effect: display message when picked (if not already seen)
711 if (picked)
712 this->message.display ();
713}
714
715bool
716packagemeta::srcpicked () const
717{
718 return _srcpicked;
719}
720
721void
722packagemeta::srcpick (bool picked)
723{
724 _srcpicked = picked;
725}
726
3c196821
RC
727bool
728packagemeta::accessible () const
729{
155eacb6 730 for (std::set<packageversion>::iterator i=versions.begin();
3c196821
RC
731 i != versions.end(); ++i)
732 if (i->accessible())
733 return true;
734 return false;
735}
736
737bool
738packagemeta::sourceAccessible () const
739{
155eacb6 740 for (std::set<packageversion>::iterator i=versions.begin();
3c196821
RC
741 i != versions.end(); ++i)
742 {
743 packageversion bin=*i;
744 if (bin.sourcePackage().accessible())
745 return true;
7e8fc33c 746 }
c23d96d6
JT
747
748 return false;
749}
750
751bool
752packagemeta::isBinary () const
753{
155eacb6 754 for (std::set<packageversion>::iterator i=versions.begin();
c23d96d6 755 i != versions.end(); ++i)
afba8f14 756 if ((i->Type() == package_binary) && (i->accessible() || (*i == installed)))
c23d96d6
JT
757 return true;
758
3c196821 759 return false;
7e8fc33c 760}
f416a2b6
RC
761
762void
763packagemeta::logAllVersions () const
764{
155eacb6
AG
765 for (std::set<packageversion>::iterator i = versions.begin();
766 i != versions.end(); ++i)
304e9816 767 {
157dc2b8 768 Log (LOG_BABBLE) << " [" << trustLabel(*i) <<
c4e25cde 769 "] ver=" << i->Canonical_version() << endLog;
f717b243
JT
770 std::ostream & logger = Log (LOG_BABBLE);
771 logger << " depends=";
772 dumpPackageDepends(i->depends(), logger);
773 logger << endLog;
304e9816 774 }
f416a2b6 775#if 0
157dc2b8 776 Log (LOG_BABBLE) << " inst=" << i->
f416a2b6
RC
777 /* FIXME: Reinstate this code, but spit out all mirror sites */
778
779 for (int t = 1; t < NTRUST; t++)
780 {
781 if (pkg->info[t].install)
157dc2b8 782 Log (LOG_BABBLE) << " [%s] ver=%s\n"
f416a2b6
RC
783 " inst=%s %d exists=%s\n"
784 " src=%s %d exists=%s",
785 infos[t],
786 pkg->info[t].version ? : "(none)",
787 pkg->info[t].install ? : "(none)",
788 pkg->info[t].install_size,
789 (pkg->info[t].install_exists) ? "yes" : "no",
790 pkg->info[t].source ? : "(none)",
791 pkg->info[t].source_size,
792 (pkg->info[t].source_exists) ? "yes" : "no");
793 }
794#endif
795}
796
155eacb6 797std::string
f416a2b6
RC
798packagemeta::trustLabel(packageversion const &aVersion) const
799{
f416a2b6
RC
800 if (aVersion == curr)
801 return "Curr";
802 if (aVersion == exp)
803 return "Test";
804 return "Unknown";
805}
8c242540 806
d55e14fe
RC
807void
808packagemeta::logSelectionStatus() const
809{
810 packagemeta const & pkg = *this;
ec7c556d 811 const char *trust = ((pkg.desired == pkg.curr) ? "curr"
d55e14fe 812 : (pkg.desired == pkg.exp) ? "test" : "unknown");
1eb2461a 813 const std::string installed =
d55e14fe
RC
814 pkg.installed ? pkg.installed.Canonical_version () : "none";
815
f34a20e7 816 Log (LOG_BABBLE) << "[" << pkg.name << "] action=" << _action << " trust=" << trust << " installed=" << installed << " src?=" << (pkg.desired && srcpicked() ? "yes" : "no") << endLog;
d55e14fe 817 if (pkg.categories.size ())
157dc2b8 818 Log (LOG_BABBLE) << " categories=" << for_each(pkg.categories.begin(), pkg.categories.end(), StringConcatenator(", ")).result << endLog;
d55e14fe
RC
819#if 0
820 if (pkg.desired.required())
821 {
822 /* List other packages this package depends on */
823 Dependency *dp = pkg.desired->required;
1eb2461a 824 std::string requires = dp->package.serialise ();
d55e14fe 825 for (dp = dp->next; dp; dp = dp->next)
1eb2461a 826 requires += std::string (", ") + dp->package.serialise ();
d55e14fe 827
157dc2b8 828 Log (LOG_BABBLE) << " requires=" << requires;
d55e14fe
RC
829 }
830#endif
831 pkg.logAllVersions();
832}
cda26207 833
c58b62ea 834/* scan for local copies of package */
e8cc4542 835bool
c58b62ea
JT
836packagemeta::scan (const packageversion &pkg, bool mirror_mode)
837{
e8cc4542 838 /* empty version */
c58b62ea 839 if (!pkg)
e8cc4542 840 return false;
c58b62ea 841
c58b62ea
JT
842 try
843 {
ff2cd3f4 844 if (!check_for_cached (*(pkg.source ()), NULL, mirror_mode, false)
e8cc4542
JT
845 && ::source == IDC_SOURCE_LOCALDIR)
846 return false;
c58b62ea
JT
847 }
848 catch (Exception * e)
849 {
850 // We can ignore these, since we're clearing the source list anyway
851 if (e->errNo () == APPERR_CORRUPT_PACKAGE)
e8cc4542
JT
852 return false;
853
c58b62ea
JT
854 // Unexpected exception.
855 throw e;
856 }
e8cc4542
JT
857
858 return true;
c58b62ea
JT
859}
860
cda26207 861void
f1486891 862packagemeta::ScanDownloadedFiles (bool mirror_mode)
cda26207
RC
863{
864 /* Look at every known package, in all the known mirror dirs,
865 * and fill in the Cached attribute if it exists.
866 */
867 packagedb db;
263157cb 868 for (packagedb::packagecollection::iterator n = db.packages.begin ();
cda26207
RC
869 n != db.packages.end (); ++n)
870 {
263157cb 871 packagemeta & pkg = *(n->second);
155eacb6 872 std::set<packageversion>::iterator i = pkg.versions.begin ();
65ce9baf
BD
873 while (i != pkg.versions.end ())
874 {
875 /* scan doesn't alter operator == for packageversions */
f1486891
CV
876 bool lazy_scan = mirror_mode
877 && (*i != pkg.installed
f1486891
CV
878 || pkg.installed == pkg.curr
879 || pkg.installed == pkg.exp);
e8cc4542 880 bool accessible = scan (*i, lazy_scan);
65ce9baf
BD
881 packageversion foo = *i;
882 packageversion pkgsrcver = foo.sourcePackage ();
e8cc4542 883 bool src_accessible = scan (pkgsrcver, lazy_scan);
65ce9baf
BD
884
885 /* For local installs, if there is no src and no bin, the version
886 * is unavailable
887 */
e8cc4542 888 if (!accessible && !src_accessible
65ce9baf
BD
889 && *i != pkg.installed)
890 {
65ce9baf
BD
891 if (pkg.curr == *i)
892 pkg.curr = packageversion ();
893 if (pkg.exp == *i)
894 pkg.exp = packageversion ();
972b2d9a
JT
895
896 i->remove();
65ce9baf 897 pkg.versions.erase (i++);
972b2d9a 898
65ce9baf
BD
899 /* For now, leave the source version alone */
900 }
901 else
902 ++i;
903 }
cda26207 904 }
65ce9baf
BD
905 /* Don't explicity iterate through sources - any sources that aren't
906 referenced are unselectable anyway. */
cda26207 907}
31f0ccce 908
155eacb6
AG
909void
910packagemeta::addToCategoryBase()
0407753c
DK
911{
912 add_category ("Base");
913}
914
31f0ccce
RC
915bool
916packagemeta::hasNoCategories() const
917{
918 return categories.size() == 0;
919}
920
921void
922packagemeta::setDefaultCategories()
923{
fb5ecc5d 924 add_category ("Orphaned");
358712d8
RC
925}
926
927void
928packagemeta::addToCategoryAll()
929{
31f0ccce
RC
930 add_category ("All");
931}
621df5b3
JT
932
933void
934packagemeta::addScript(Script const &aScript)
935{
936 scripts_.push_back(aScript);
937}
938
939std::vector <Script> &
940packagemeta::scripts()
941{
942 return scripts_;
943}
This page took 2.086401 seconds and 6 git commands to generate.