From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 123743 invoked by alias); 2 Aug 2016 15:31:43 -0000 Mailing-List: contact cygwin-apps-help@cygwin.com; run by ezmlm Precedence: bulk Sender: cygwin-apps-owner@cygwin.com List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Mail-Followup-To: cygwin-apps@cygwin.com Received: (qmail 123675 invoked by uid 89); 2 Aug 2016 15:31:42 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.1 required=5.0 tests=AWL,BAYES_00,KAM_LAZY_DOMAIN_SECURITY autolearn=no version=3.3.2 spammy=categories, db, 42,6, sk:install X-HELO: rgout02.bt.lon5.cpcloud.co.uk Received: from rgout02.bt.lon5.cpcloud.co.uk (HELO rgout02.bt.lon5.cpcloud.co.uk) (65.20.0.179) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 02 Aug 2016 15:31:32 +0000 X-OWM-Source-IP: 31.51.206.218 (GB) X-OWM-Env-Sender: jonturney@btinternet.com X-Junkmail-Premium-Raw: score=7/50,refid=2.7.2:2016.8.1.131817:17:7.944,ip=31.51.206.218,rules=__HAS_FROM, __TO_MALFORMED_2, __TO_NO_NAME, __HAS_CC_HDR, __CC_NAME, __CC_NAME_DIFF_FROM_ACC, __SUBJ_ALPHA_END, __HAS_MSGID, __SANE_MSGID, __HAS_X_MAILER, __IN_REP_TO, __REFERENCES, __FROM_DOMAIN_IN_ANY_CC1, __ANY_URI, __URI_NO_MAILTO, __URI_NO_WWW, __MIME_TEXT_ONLY, RDNS_GENERIC_POOLED, HTML_00_01, HTML_00_10, RDNS_SUSP_GENERIC, __FROM_DOMAIN_IN_RCPT, RDNS_SUSP, IN_REP_TO, REFERENCES, NO_URI_HTTPS, MSG_THREAD, __CC_REAL_NAMES, MULTIPLE_REAL_RCPTS, LEGITIMATE_SIGNS, LEGITIMATE_NEGATE Received: from localhost.localdomain (31.51.206.218) by rgout02.bt.lon5.cpcloud.co.uk (8.6.122.06) (authenticated as jonturney@btinternet.com) id 57A0AF7B0001DA06; Tue, 2 Aug 2016 16:31:31 +0100 From: Jon Turney To: cygwin-apps@cygwin.com Cc: Jon Turney Subject: [PATCH setup 08/10] Track if a package was installed by user, or as a dependency Date: Tue, 02 Aug 2016 15:31:00 -0000 Message-Id: <20160802153037.125216-9-jon.turney@dronecode.org.uk> In-Reply-To: <20160802153037.125216-1-jon.turney@dronecode.org.uk> References: <20160802153037.125216-1-jon.turney@dronecode.org.uk> X-SW-Source: 2016-08/txt/msg00015.txt.bz2 Update the installed.db file format to version 3: - Write installed version as a version, rather than as a notional filename. - Also write user_picked flag This extends the semantics of user_pick somewhat: currently it is only used for UI purposes, to record if a package was picked in the current session. Now we also use it to record if an installed package has ever been picked via the UI (otherwise it is only installed because it is a dependency). So, we are careful not to set it when a currently installed package has it's installed version adjusted via the GUI. We also arrange for user_pick to be set when a package was selected for installation via CLI. Add a heuristic to initially populate user_pick when upgrading from older installed.db formats: All non-base installed packages which aren't dependenies are assumed to be user_pick-ed. Note: other tools (e.g. cygcheck) which read the installed.db file will need updating appropriately --- ini.cc | 4 ++ package_db.cc | 148 +++++++++++++++++++++++++++++++++++++++++++++++++------- package_db.h | 3 ++ package_meta.cc | 4 +- 4 files changed, 140 insertions(+), 19 deletions(-) diff --git a/ini.cc b/ini.cc index 456eb6e..f925bf5 100644 --- a/ini.cc +++ b/ini.cc @@ -51,6 +51,7 @@ #include "compress.h" #include "Exception.h" #include "crypto.h" +#include "package_db.h" extern ThreeBarProgressPage Progress; @@ -351,6 +352,9 @@ do_ini_thread (HINSTANCE h, HWND owner) else ini_count = do_remote_ini (owner); + packagedb db; + db.upgrade(); + if (ini_count == 0) return false; diff --git a/package_db.cc b/package_db.cc index f437daf..18f4f37 100644 --- a/package_db.cc +++ b/package_db.cc @@ -42,6 +42,7 @@ static const char *cvsid = #include "package_meta.h" #include "Exception.h" #include "Generic.h" +#include "LogSingleton.h" using namespace std; @@ -55,23 +56,26 @@ packagedb::packagedb () installeddbread = 1; if (!db) return; - /* flush_local_db_package_data */ - char line[1000], pkgname[1000], inst[1000]; - int instsz; + char line[1000], pkgname[1000]; if (db->gets (line, 1000)) { + /* Look for header line (absent in version 1) */ + int instsz; int dbver; sscanf (line, "%s %d", pkgname, &instsz); - if (!strcasecmp (pkgname, "INSTALLED.DB") && instsz == 2) - dbver = 2; + if (!strcasecmp (pkgname, "INSTALLED.DB") && instsz <= 3) + dbver = instsz; else dbver = 1; delete db; db = 0; + /* Later versions may not use installed.db other than to record the version. */ if (dbver == 1 || dbver == 2) { + char inst[1000]; + db = io_stream::open ("cygfile:///etc/setup/installed.db", "rt", 0); if (dbver == 2) @@ -106,19 +110,63 @@ packagedb::packagedb () packageversion binary = cygpackage::createInstance (pkgname, f.ver, - package_installed, - package_binary); + package_installed, + package_binary); + + pkg->add_version (binary); + pkg->set_installed (binary); + pkg->desired = pkg->installed; + } + delete db; + db = 0; + } + else if (dbver == 3) + { + char ver[1000]; + + db = io_stream::open ("cygfile:///etc/setup/installed.db", "rt", 0); + + // skip over already-parsed header line + db->gets (line, 1000); + + while (db->gets (line, 1000)) + { + pkgname[0] = '\0'; + ver[0] = '\0'; + int user_picked = 0; + + /* + In an INSTALLED.DB 3, the lines consist of: + packagename installed-version user-picked + */ + int res = sscanf (line, "%s %s %d", pkgname, ver, &user_picked); + if (res < 3 || pkgname[0] == '\0' || ver[0] == '\0') + continue; + + packagemeta *pkg = findBinary (PackageSpecification(pkgname)); + if (!pkg) + { + pkg = new packagemeta (pkgname); + packages.insert (packagedb::packagecollection::value_type(pkgname, pkg)); + } + + packageversion binary = cygpackage::createInstance (pkgname, ver, package_installed, package_binary); pkg->add_version (binary); pkg->set_installed (binary); pkg->desired = pkg->installed; + pkg->user_picked = (user_picked != 0); } delete db; db = 0; } else - // unknown dbversion - exit (1); + { + Log (LOG_PLAIN) << "unknown INSTALLED.DB version " << dbver << endLog; + exit (1); + } + + installeddbver = dbver; } } } @@ -138,21 +186,17 @@ packagedb::flush () if (!ndb) return errno ? errno : 1; - ndb->write ("INSTALLED.DB 2\n", strlen ("INSTALLED.DB 2\n")); + ndb->write ("INSTALLED.DB 3\n", strlen ("INSTALLED.DB 3\n")); for (packagedb::packagecollection::iterator i = packages.begin (); i != packages.end (); ++i) { packagemeta & pkgm = *(i->second); if (pkgm.installed) { - /* size here is irrelevant - as we can assume that this install source - * no longer exists, and it does not correlate to used disk space - * also note that we are writing a fictional install source - * to keep cygcheck happy. - */ std::string line; - line = pkgm.name + " " + pkgm.name + "-" + - std::string(pkgm.installed.Canonical_version()) + ".tar.bz2 0\n"; + line = pkgm.name + " " + + std::string(pkgm.installed.Canonical_version()) + " " + + (pkgm.user_picked ? "1" : "0") + "\n"; ndb->write (line.c_str(), line.size()); } } @@ -166,6 +210,18 @@ packagedb::flush () return 0; } +void +packagedb::upgrade() +{ + if (installeddbver < 3) + { + /* Guess which packages were user_picked. This has to take place after + setup.ini has been parsed as it needs dependency information. */ + guessUserPicked(); + installeddbver = 3; + } +} + packagemeta * packagedb::findBinary (PackageSpecification const &spec) const { @@ -199,13 +255,13 @@ packagedb::findSource (PackageSpecification const &spec) const /* static members */ int packagedb::installeddbread = 0; +int packagedb::installeddbver = 0; packagedb::packagecollection packagedb::packages; packagedb::categoriesType packagedb::categories; packagedb::packagecollection packagedb::sourcePackages; PackageDBActions packagedb::task = PackageDB_Install; std::vector packagedb::dependencyOrderedPackages; -#include "LogSingleton.h" #include class @@ -449,3 +505,59 @@ packagedb::defaultTrust (trusts trust) packagedb::categories.erase (n++); } } + +void +packagedb::guessUserPicked() +{ + /* + Assume that any non-base installed package which is a dependency of an + installed package wasn't user_picked + + i.e. only installed packages which aren't in the base category, and aren't + a dependency of any installed package are user_picked + */ + + /* First mark all installed non-base packages */ + for (packagedb::packagecollection::iterator i = packages.begin (); + i != packages.end (); ++i) + { + packagemeta & pkgm = *(i->second); + + if (pkgm.categories.find ("Base") != pkgm.categories.end ()) + continue; + + if (pkgm.installed) + pkgm.user_picked = TRUE; + } + + /* Then clear the mark for all dependencies of all installed packages */ + for (packagedb::packagecollection::iterator i = packages.begin (); + i != packages.end (); ++i) + { + packagemeta & pkgm = *(i->second); + + if (!pkgm.installed) + continue; + + /* walk through each and clause */ + vector *>::const_iterator dp = pkgm.installed.depends()->begin(); + while (dp != pkgm.installed.depends()->end()) + { + /* check each or clause for an installed match */ + vector ::const_iterator i = find_if ((*dp)->begin(), (*dp)->end(), checkForInstalled); + if (i != (*dp)->end()) + { + const packagedb::packagecollection::iterator n = packages.find((*i)->packageName()); + if (n != packages.end()) + { + packagemeta *pkgm2 = n->second; + pkgm2->user_picked = FALSE; + } + /* skip to next and clause */ + ++dp; + continue; + } + ++dp; + } + } +} diff --git a/package_db.h b/package_db.h index bc828a1..6a99398 100644 --- a/package_db.h +++ b/package_db.h @@ -65,6 +65,7 @@ public: packagedb (); /* 0 on success */ int flush (); + void upgrade (); packagemeta * findBinary (PackageSpecification const &) const; packagemeta * findSource (PackageSpecification const &) const; PackageDBConnectedIterator connectedBegin(); @@ -84,8 +85,10 @@ public: static PackageDBActions task; private: static int installeddbread; /* do we have to reread this */ + static int installeddbver; friend class ConnectedLoopFinder; static std::vector dependencyOrderedPackages; + void guessUserPicked(void); }; #endif /* SETUP_PACKAGE_DB_H */ diff --git a/package_meta.cc b/package_meta.cc index 21b21ef..3923b13 100644 --- a/package_meta.cc +++ b/package_meta.cc @@ -458,7 +458,8 @@ packagemeta::set_action (trusts const trust) else desired = packageversion (); /* Memorize the fact that the user picked at least once. */ - user_picked = true; + if (!installed) + user_picked = true; } int @@ -510,6 +511,7 @@ packagemeta::set_action (_actions action, packageversion const &default_version) if (desired != installed) if (desired.accessible ()) { + user_picked = true; desired.pick (true, this); desired.sourcePackage ().pick (false, NULL); } -- 2.8.3