From ed0dd177c63bb7758e8633ffe26de2a8bc315d1b Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Mon, 7 Mar 2016 19:11:31 +0300 Subject: Display sha256sum on the package version details page --- brep/mod-package-version-details.cxx | 3 +- brep/package | 7 +- brep/package.cxx | 4 +- brep/package.xml | 1 + brep/page | 14 +++ brep/page.cxx | 11 +++ load/buildfile | 3 +- load/load.cli | 37 ++++++- load/load.cxx | 172 +++++++++++++++++++------------- migrate/buildfile | 4 +- migrate/migrate.cli | 31 ++++++ migrate/migrate.cxx | 110 ++++++++++++++------- tests/load/1/math/packages | 2 +- tests/load/1/misc/packages | 4 +- tests/load/driver.cxx | 183 ++++++++++++++++++++--------------- www/package-version-details-body.css | 6 ++ 16 files changed, 398 insertions(+), 194 deletions(-) diff --git a/brep/mod-package-version-details.cxx b/brep/mod-package-version-details.cxx index cbf9c86..992b829 100644 --- a/brep/mod-package-version-details.cxx +++ b/brep/mod-package-version-details.cxx @@ -161,7 +161,7 @@ handle (request& rq, response& rs) : P_DESCRIPTION (*d, options_->package_description (), url (!full, id))); - assert (pkg->location); + assert (pkg->location && pkg->sha256sum); s << TABLE(CLASS="proplist", ID="version") << TBODY @@ -175,6 +175,7 @@ handle (request& rq, response& rs) << TR_LOCATION (pkg->internal_repository.object_id (), root) << TR_DOWNLOAD (pkg->internal_repository.load ()->location.string () + "/" + pkg->location->string ()) + << TR_SHA256SUM (*pkg->sha256sum) << ~TBODY << ~TABLE diff --git a/brep/package b/brep/package index fa129f3..67f0e31 100644 --- a/brep/package +++ b/brep/package @@ -132,7 +132,7 @@ namespace brep std::chrono::nanoseconds::period>::value, "The following timestamp ODB mapping is invalid"); - // As it pointed out in butl/timestamp we will overflow in year 2262 but + // As it pointed out in butl/timestamp we will overflow in year 2262, but // by that time some larger basic type will be available for mapping. // #pragma db map type(timestamp) as(uint64_t) \ @@ -470,6 +470,7 @@ namespace brep dependencies_type, requirements_type, optional location, + optional sha256sum, shared_ptr); // Create external package object. @@ -506,6 +507,10 @@ namespace brep // optional location; + // Present only for internal packages. + // + optional sha256sum; + vector> other_repositories; // Database mapping. diff --git a/brep/package.cxx b/brep/package.cxx index 1f93a56..d1bbe21 100644 --- a/brep/package.cxx +++ b/brep/package.cxx @@ -62,6 +62,7 @@ namespace brep dependencies_type dp, requirements_type rq, optional lc, + optional sh, shared_ptr rp) : id (move (nm), vr), version (move (vr)), @@ -78,7 +79,8 @@ namespace brep dependencies (move (dp)), requirements (move (rq)), internal_repository (move (rp)), - location (move (lc)) + location (move (lc)), + sha256sum (move (sh)) { assert (internal_repository->internal); } diff --git a/brep/package.xml b/brep/package.xml index 6abbf1d..14598a5 100644 --- a/brep/package.xml +++ b/brep/package.xml @@ -87,6 +87,7 @@ + diff --git a/brep/page b/brep/page index 4f97ef8..512c11a 100644 --- a/brep/page +++ b/brep/page @@ -293,6 +293,20 @@ namespace brep const string& url_; }; + // Generates sha256sum element. + // + class TR_SHA256SUM + { + public: + TR_SHA256SUM (const string& s): sha256sum_ (s) {} + + void + operator() (xml::serializer&) const; + + private: + const string& sha256sum_; + }; + // Generates comment element. // class SPAN_COMMENT diff --git a/brep/page.cxx b/brep/page.cxx index 27e1b2a..689ee20 100644 --- a/brep/page.cxx +++ b/brep/page.cxx @@ -481,6 +481,17 @@ namespace brep << ~TR; } + // TR_SHA256SUM + // + void TR_SHA256SUM:: + operator() (serializer& s) const + { + s << TR(CLASS="sha256") + << TH << "sha256" << ~TH + << TD << SPAN(CLASS="value") << sha256sum_ << ~SPAN << ~TD + << ~TR; + } + // SPAN_COMMENT // void SPAN_COMMENT:: diff --git a/load/buildfile b/load/buildfile index 6b72dae..333c091 100644 --- a/load/buildfile +++ b/load/buildfile @@ -15,6 +15,7 @@ exe{brep-load}: \ ../brep/lib{brep} $libs cli.options += -I $src_root --include-with-brackets --include-prefix load \ ---guard-prefix LOAD +--guard-prefix LOAD --generate-specifier --page-usage print_ --ansi-color \ +--long-usage {hxx ixx cxx}{load-options}: cli{load} diff --git a/load/load.cli b/load/load.cli index 751d1bd..5c30c14 100644 --- a/load/load.cli +++ b/load/load.cli @@ -2,6 +2,7 @@ // copyright : Copyright (c) 2014-2016 Code Synthesis Ltd // license : MIT; see accompanying LICENSE file +include ; include ; include ; // uint16_t @@ -21,9 +22,9 @@ include ; // uint16_t \h|DESCRIPTION| \cb{brep-load} reads the list of repositories from the specified - configuration , fetches their manifest files, and loads the repository - and package information into the database, suitable for consumption by the - \cb{brep} web module. + configuration , fetches their manifest files, and loads the + repository and package information into the database, suitable for + consumption by the \cb{brep} web module. Note that \cb{brep-load} expects the database schema to have already been created using \l{brep-migrate(1)}." @@ -67,6 +68,36 @@ class options "Database port number. If not specified, the default port is used." } + std::string --pager // String to allow empty value. + { + "", + "The pager program to be used to show long text. Commonly used pager + programs are \cb{less} and \cb{more}. You can also specify additional + options that should be passed to the pager program with + \cb{--pager-option}. If an empty string is specified as the pager + program, then no pager will be used. If the pager program is not + explicitly specified, then \cb{brep-load} will try to use \cb{less}. If + it is not available, then no pager will be used." + } + + std::vector --pager-option + { + "", + "Additional option to be passed to the pager program. See \cb{--pager} + for more information on the pager program. Repeat this option to + specify multiple pager options." + } + bool --help {"Print usage information and exit."} bool --version {"Print version and exit."} }; + +"\h|EXIT STATUS| + +\cb{0} Successful termination. + +\cb{1} \cb{brep-load} or \l{brep-migrate(1)} instance is running. Try + again. + +\cb{2} Fatal error. +" diff --git a/load/load.cxx b/load/load.cxx index b4dcd11..7556449 100644 --- a/load/load.cxx +++ b/load/load.cxx @@ -2,7 +2,6 @@ // copyright : Copyright (c) 2014-2016 Code Synthesis Ltd // license : MIT; see accompanying LICENSE file -#include #include #include #include // find(), find_if() @@ -14,6 +13,7 @@ #include +#include #include #include // manifest_parsing @@ -34,15 +34,12 @@ using namespace butl; using namespace bpkg; using namespace brep; -static void -usage (ostream& os) -{ - os << "Usage: brep-load [options] " << endl - << "File lists internal repositories." << endl - << "Options:" << endl; +// Operation failed, diagnostics has already been issued. +// +struct failed: std::exception {}; - options::print_usage (os); -} +static const char* help_info ( + " info: run 'brep-load --help' for more information"); static inline bool space (char c) noexcept @@ -75,7 +72,10 @@ load_repositories (path p) ifstream ifs (p.string ()); if (!ifs.is_open ()) - throw ifstream::failure (p.string () + ": unable to open"); + { + cerr << "error: unable to open " << p << " in read mode" << endl; + throw failed (); + } ifs.exceptions (ifstream::badbit); @@ -108,11 +108,13 @@ load_repositories (path p) auto pb (i); // Location begin. skip (false); // Find end of location. - auto bad_line ([&p, l, &pb, &b](const string& d) { - ostringstream os; - os << p << ':' << l << ':' << pb - b + 1 << ": error: " << d; - throw runtime_error (os.str ()); - }); + auto bad_line = [&p, l, &pb, &b](const string& d) + { + cerr << p << ':' << l << ':' << pb - b + 1 << ": error: " << d + << endl; + + throw failed (); + }; repository_location location; @@ -186,7 +188,8 @@ load_repositories (path p) } catch (const ifstream::failure&) { - throw ifstream::failure (p.string () + ": io failure"); + cerr << "error: unable to read " << p << endl; + throw failed (); } return repos; @@ -208,7 +211,8 @@ changed (const internal_repositories& repos, database& db) db.find (r.location.canonical_name ())); if (pr == nullptr || r.location.string () != pr->location.string () || - r.display_name != pr->display_name || r.local_path != pr->local_path || + r.display_name != pr->display_name || + r.local_path != pr->local_path || file_mtime (r.packages_path ()) != pr->packages_timestamp || file_mtime (r.repositories_path ()) != pr->repositories_timestamp || !pr->internal) @@ -224,8 +228,8 @@ changed (const internal_repositories& repos, database& db) // return !db.query ( - query::internal && !query::name.in_range (names.begin (), names.end ())). - empty (); + query::internal && + !query::name.in_range (names.begin (), names.end ())).empty (); } static timestamp @@ -233,7 +237,10 @@ manifest_stream (const path& p, ifstream& f) { f.open (p.string ()); if (!f.is_open ()) - throw ifstream::failure (p.string () + ": unable to open"); + { + cerr << "error: unable to open " << p << " in read mode" << endl; + throw failed (); + } f.exceptions (ifstream::badbit | ifstream::failbit); return file_mtime (p); @@ -268,7 +275,13 @@ load_packages (const shared_ptr& rp, database& db) for (auto& pm: pkm) { - shared_ptr p (db.find (package_id (pm.name, pm.version))); + shared_ptr p ( + db.find (package_id (pm.name, pm.version))); + + // sha256sum should always be present if the package manifest comes from + // the 'packages' file. + // + assert (pm.sha256sum); if (p == nullptr) { @@ -338,6 +351,7 @@ load_packages (const shared_ptr& rp, database& db) move (ds), move (pm.requirements), move (pm.location), + move (pm.sha256sum), rp); } else @@ -349,16 +363,19 @@ load_packages (const shared_ptr& rp, database& db) } else { - // @@ Need to ensure that the same packages coming from different - // repositories are equal. Probably will invent hashsum at some point - // for this purpose. - // - // As soon as internal repositories get loaded first, the internal // package can duplicate an internal package only. // assert (!rp->internal || p->internal ()); + if (rp->internal && pm.sha256sum != p->sha256sum) + cerr << "warning: sha256sum mismatch for package " << p->id.name + << " " << p->version << endl + << " info: " << p->internal_repository.load ()->location + << " has " << *p->sha256sum << endl + << " info: " << rp->location << " has " << *pm.sha256sum + << endl; + p->other_repositories.push_back (rp); db.update (p); } @@ -402,7 +419,8 @@ load_repositories (const shared_ptr& rp, database& db) for (auto& rm: rpm) { - if (rm.effective_role () == repository_role::prerequisite && !rp->internal) + if (rm.effective_role () == repository_role::prerequisite && + !rp->internal) continue; // Ignore the external repository prerequisite entry. if (rm.effective_role () == repository_role::base) @@ -449,12 +467,12 @@ load_repositories (const shared_ptr& rp, database& db) auto bad_location ( [&rp, &rm]() { - ostringstream o; - o << "invalid location '" << rm.location.string () - << "' of the prerequisite repository for internal " - "repository '" << rp->location.string () << "'"; + cerr << "error: invalid prerequisite repository location " + << rm.location << endl + << " info: base (internal) repository location is " + << rp->location << endl; - throw runtime_error (o.str ()); + throw failed (); }); try @@ -508,12 +526,12 @@ load_repositories (const shared_ptr& rp, database& db) } catch (const invalid_path&) { - ostringstream o; - o << "can't normalize local path'" << lp.string () - << "' of the prerequisite repository for internal " - "repository '" << rp->location.string () << "'"; + cerr << "error: can't normalize prerequisite repository local path '" + << lp << "'" << endl + << " info: base (internal) repository location is " + << rp->location << endl; - throw runtime_error (o.str ()); + throw failed (); } } @@ -536,7 +554,8 @@ find (const lazy_shared_ptr& r, assert (r != nullptr); const auto& o (p.other_repositories); - if (r == p.internal_repository || find (o.begin (), o.end (), r) != o.end ()) + if (r == p.internal_repository || + find (o.begin (), o.end (), r) != o.end ()) return true; auto rp (r.load ()); @@ -629,17 +648,18 @@ resolve_dependencies (package& p, database& db) if (d.package.object_id ().version.empty ()) { - ostringstream o; - o << "can't resolve dependency " << d << " of the package " - << p.id.name << " " << p.version.string () - << " (" << p.internal_repository.load ()->name << ")"; + cerr << "error: can't resolve dependency " << d << " of the package " + << p.id.name << " " << p.version << endl + << " info: repository " + << p.internal_repository.load ()->location + << " appears to be broken" << endl; // Practically it is enough to resolve at least one dependency // alternative to build a package. Meanwhile here we consider an error // specifying in the manifest file an alternative which can't be // resolved. // - throw runtime_error (o.str ()); + throw failed (); } } } @@ -650,14 +670,15 @@ resolve_dependencies (package& p, database& db) using package_ids = vector; // Ensure the package dependency chain do not contain the package id. Throw -// runtime_error otherwise. Continue the chain with the package id and call -// itself recursively for each prerequisite of the package. Should be called -// once per internal package. +// failed otherwise. Continue the chain with the package id and call itself +// recursively for each prerequisite of the package. Should be called once per +// internal package. // // @@ This should probably be eventually moved to bpkg. // static void -detect_dependency_cycle (const package_id& id, package_ids& chain, database& db) +detect_dependency_cycle ( + const package_id& id, package_ids& chain, database& db) { // Package of one version depending on the same package of another version // is something obscure. So the comparison is made up to a package name. @@ -667,11 +688,10 @@ detect_dependency_cycle (const package_id& id, package_ids& chain, database& db) if (i != chain.end ()) { - ostringstream o; - o << "package dependency cycle: "; + cerr << "error: package dependency cycle: "; auto prn ( - [&o, &db](const package_id& id) + [&db](const package_id& id) { shared_ptr p (db.load (id)); assert (p->internal () || !p->other_repositories.empty ()); @@ -681,17 +701,18 @@ detect_dependency_cycle (const package_id& id, package_ids& chain, database& db) ? p->internal_repository.load () : p->other_repositories[0].load ()); - o << id.name << " " << p->version.string () << " (" << r->name << ")"; + cerr << id.name << " " << p->version << " (" << r->name << ")"; }); for (; i != chain.end (); ++i) { prn (*i); - o << " -> "; + cerr << " -> "; } prn (id); - throw runtime_error (o.str ()); + cerr << endl; + throw failed (); } chain.push_back (id); @@ -731,22 +752,30 @@ try // if (ops.help ()) { - usage (cout); - return 0; + pager p ("brep-load help", + false, + ops.pager_specified () ? &ops.pager () : nullptr, + &ops.pager_option ()); + + print_usage (p.stream ()); + + // If the pager failed, assume it has issued some diagnostics. + // + return p.wait () ? 0 : 2; } if (argc < 2) { - cerr << " argument not provided" << endl; - usage (cerr); - return 1; + cerr << "error: configuration file path argument expected" << endl + << help_info << endl; + return 2; } if (argc > 2) { - cerr << "unexpected argument encountered" << endl; - usage (cerr); - return 1; + cerr << "error: unexpected argument encountered" << endl + << help_info << endl; + return 2; } odb::pgsql::database db (ops.db_user (), @@ -766,8 +795,9 @@ try // if (schema_catalog::current_version (db) != db.schema_version ()) { - cerr << "database schema differs from the current one" << endl; - return 1; + cerr << "error: database schema differs from the current one" << endl + << " info: use brep-migrate to migrate the database" << endl; + return 2; } // Load the description of all the internal repositories from the @@ -827,22 +857,26 @@ try } t.commit (); + return 0; } catch (const database_locked&) { cerr << "brep-load or brep-migrate instance is running" << endl; - return 2; + return 1; } catch (const cli::exception& e) { - cerr << e << endl; - usage (cerr); - return 1; + cerr << "error: " << e << endl << help_info << endl; + return 2; +} +catch (const failed&) +{ + return 2; // Diagnostics has already been issued. } // Fully qualified to avoid ambiguity with odb exception. // catch (const std::exception& e) { - cerr << e.what () << endl; - return 1; + cerr << "error: " << e.what () << endl; + return 2; } diff --git a/migrate/buildfile b/migrate/buildfile index cd0b9c8..1722fea 100644 --- a/migrate/buildfile +++ b/migrate/buildfile @@ -2,6 +2,7 @@ # copyright : Copyright (c) 2014-2016 Code Synthesis Ltd # license : MIT; see accompanying LICENSE file +import libs += libbutl%lib{butl} import libs += libodb-pgsql%lib{odb-pgsql} import libs += libodb%lib{odb} @@ -13,6 +14,7 @@ exe{brep-migrate}: \ ../brep/lib{brep} $libs cli.options += -I $src_root --include-with-brackets --include-prefix migrate \ ---guard-prefix MIGRATE +--guard-prefix MIGRATE --generate-specifier --page-usage print_ --ansi-color \ +--long-usage {hxx ixx cxx}{migrate-options}: cli{migrate} diff --git a/migrate/migrate.cli b/migrate/migrate.cli index 35d082f..dcbf667 100644 --- a/migrate/migrate.cli +++ b/migrate/migrate.cli @@ -2,6 +2,7 @@ // copyright : Copyright (c) 2014-2016 Code Synthesis Ltd // license : MIT; see accompanying LICENSE file +include ; include ; include ; // uint16_t @@ -85,6 +86,36 @@ class options "Database port number. If not specified, the default port is used." } + std::string --pager // String to allow empty value. + { + "", + "The pager program to be used to show long text. Commonly used pager + programs are \cb{less} and \cb{more}. You can also specify additional + options that should be passed to the pager program with + \cb{--pager-option}. If an empty string is specified as the pager + program, then no pager will be used. If the pager program is not + explicitly specified, then \cb{brep-migrate} will try to use \cb{less}. + If it is not available, then no pager will be used." + } + + std::vector --pager-option + { + "", + "Additional option to be passed to the pager program. See \cb{--pager} + for more information on the pager program. Repeat this option to + specify multiple pager options." + } + bool --help {"Print usage information and exit."} bool --version {"Print version and exit."} }; + +"\h|EXIT STATUS| + +\cb{0} Successful termination. + +\cb{1} \cb{brep-migrate} or \l{brep-load(1)} instance is running. Try + again. + +\cb{2} Fatal error. +" diff --git a/migrate/migrate.cxx b/migrate/migrate.cxx index 702eba0..70ba54f 100644 --- a/migrate/migrate.cxx +++ b/migrate/migrate.cxx @@ -13,6 +13,8 @@ #include +#include + #include #include #include @@ -25,6 +27,13 @@ using namespace std; using namespace odb::core; using namespace brep; +// Operation failed, diagnostics has already been issued. +// +struct failed: std::exception {}; + +static const char* help_info ( + " info: run 'brep-migrate --help' for more information"); + // Helper class that encapsulates both the ODB-generated schema and the // extra that comes from a .sql file (via xxd). // @@ -108,19 +117,28 @@ schema (const char* s) if (strcasecmp (kw.c_str (), "FUNCTION") == 0) { if (!read_until ("$$") || !read_until ("$$")) - throw invalid_argument ( - "function body must be defined using $$-quoted strings"); + { + cerr << "error: function body must be defined using $$-quoted " + "strings" << endl; + throw failed (); + } } else if (strcasecmp (kw.c_str (), "TYPE") == 0) { // Fall through. } else - throw invalid_argument ("unexpected CREATE statement"); + { + cerr << "error: unexpected CREATE statement" << endl; + throw failed (); + } if (!read_until (";\n")) - throw invalid_argument ( - "expected ';\\n' at the end of CREATE statement"); + { + cerr << "error: expected ';\\n' at the end of CREATE statement" + << endl; + throw failed (); + } assert (!statement.empty ()); create_statements_.emplace_back (move (statement)); @@ -128,15 +146,21 @@ schema (const char* s) else if (strcasecmp (op.c_str (), "DROP") == 0) { if (!read_until (";\n")) - throw invalid_argument ( - "expected ';\\n' at the end of DROP statement"); + { + cerr << "error: expected ';\\n' at the end of DROP statement" + << endl; + throw failed (); + } assert (!statement.empty ()); drop_statements_.emplace_back (move (statement)); } else - throw invalid_argument ( - "unexpected statement starting with '" + op + "'"); + { + cerr << "error: unexpected statement starting with '" << op << "'" + << endl; + throw failed (); + } } } } @@ -166,17 +190,6 @@ create (database& db) const db.execute (s); } -// Utility functions -// -static void -usage (ostream& os) -{ - os << "Usage: brep-migrate [options]" << endl - << "Options:" << endl; - - options::print_usage (os); -} - // main() function // int @@ -204,22 +217,30 @@ try // if (ops.help ()) { - usage (cout); - return 0; + butl::pager p ("brep-migrate help", + false, + ops.pager_specified () ? &ops.pager () : nullptr, + &ops.pager_option ()); + + print_usage (p.stream ()); + + // If the pager failed, assume it has issued some diagnostics. + // + return p.wait () ? 0 : 2; } if (argc > 1) { - cerr << "unexpected argument encountered" << endl; - usage (cerr); - return 1; + cerr << "error: unexpected argument encountered" << endl + << help_info << endl; + return 2; } if (ops.recreate () && ops.drop ()) { - cerr << "inconsistent options specified" << endl; - usage (cerr); - return 1; + cerr << "error: inconsistent options specified" << endl + << help_info << endl; + return 2; } odb::pgsql::database db (ops.db_user (), @@ -247,10 +268,16 @@ try if (schema_version > 0) { if (schema_version < schema_catalog::base_version (db)) - throw runtime_error ("database schema is too old"); + { + cerr << "error: database schema is too old" << endl; + throw failed (); + } if (schema_version > schema_catalog::current_version (db)) - throw runtime_error ("database schema is too new"); + { + cerr << "error: database schema is too new" << endl; + throw failed (); + } } bool drop (ops.drop ()); @@ -264,7 +291,12 @@ try // if ((create || drop) && schema_version != 0 && schema_version != schema_catalog::current_version (db)) - throw runtime_error ("database schema requires migration"); + { + cerr << "error: database schema requires migration" << endl + << " info: either migrate the database first or drop the entire " + "database using, for example, psql" << endl; + throw failed (); + } transaction t (db.begin ()); @@ -292,22 +324,26 @@ try } t.commit (); + return 0; } catch (const database_locked&) { cerr << "brep-migrate or brep-load instance is running" << endl; - return 2; + return 1; } catch (const cli::exception& e) { - cerr << e << endl; - usage (cerr); - return 1; + cerr << "error: " << e << endl << help_info << endl; + return 2; +} +catch (const failed&) +{ + return 2; // Diagnostics has already been issued. } // Fully qualified to avoid ambiguity with odb exception. // catch (const std::exception& e) { - cerr << e.what () << endl; - return 1; + cerr << "error: " << e.what () << endl; + return 2; } diff --git a/tests/load/1/math/packages b/tests/load/1/math/packages index 9c8bfea..115e3f1 100644 --- a/tests/load/1/math/packages +++ b/tests/load/1/math/packages @@ -74,4 +74,4 @@ license: MIT url: http://www.example.com/foo/ email: foo-users@example.com location: libfoo-1.0.tar.gz -sha256sum: 45ccba3da34dd0296866027a26b6bacf08cacc80f54516d3b8d8eeccbe31ab93 +sha256sum: 754cba3da34dd0296866027a26b6bacf08cacc80f54516d3b8d8eeccbe31ab93 diff --git a/tests/load/1/misc/packages b/tests/load/1/misc/packages index 9cffca5..f4f7f59 100644 --- a/tests/load/1/misc/packages +++ b/tests/load/1/misc/packages @@ -24,7 +24,7 @@ license: MIT url: http://www.example.com/foo/ email: foo-users@example.com location: libfoo-1.0.tar.gz -sha256sum: 71ccba3da34dd0296866027a26b6bacf08cacc80f54516d3b8d8eeccbe31ab93 +sha256sum: 754cba3da34dd0296866027a26b6bacf08cacc80f54516d3b8d8eeccbe31ab93 : name: libfoo version: 0.1 @@ -42,7 +42,7 @@ license: MIT url: http://www.example.com/foo/ email: foo-users@example.com location: libfoo-1.2.4+1.tar.gz -sha256sum: 73ccba3da34dd0296866027a26b6bacf08cacc80f54516d3b8d8eeccbe31ab93 +sha256sum: 35ccba3da34dd0296866027a26b6bacf08cacc80f54516d3b8d8eeccbe31ab93 : name: libfoo version: 1.2.4+2 diff --git a/tests/load/driver.cxx b/tests/load/driver.cxx index 41e4623..a9b9823 100644 --- a/tests/load/driver.cxx +++ b/tests/load/driver.cxx @@ -39,11 +39,11 @@ static bool check_external (const package& p) { return p.summary.empty () && p.tags.empty () && !p.description && - p.url.empty () && !p.package_url && p.email.empty () && !p.package_email && - !p.internal () && p.other_repositories.size () > 0 && + p.url.empty () && !p.package_url && p.email.empty () && + !p.package_email && !p.internal () && p.other_repositories.size () > 0 && p.priority == priority () && p.changes.empty () && p.license_alternatives.empty () && p.dependencies.empty () && - p.requirements.empty (); + p.requirements.empty () && !p.sha256sum; } int @@ -122,27 +122,6 @@ main (int argc, char* argv[]) assert (sr->repositories_timestamp == file_mtime (dir_path (sr->local_path) / path ("repositories"))); assert (sr->internal); - - shared_ptr fpv1 ( - db.load (package_id ("libfoo", version ("1.0")))); - assert (check_location (fpv1)); - - shared_ptr fpv2 ( - db.load (package_id ("libfoo", version ("1.2.2")))); - assert (check_location (fpv2)); - - shared_ptr fpv2a ( - db.load (package_id ("libfoo", version ("1.2.2-alpha.1")))); - assert (check_location (fpv2a)); - - shared_ptr fpv3 ( - db.load (package_id ("libfoo", version ("1.2.3+4")))); - assert (check_location (fpv3)); - - shared_ptr fpv4 ( - db.load (package_id ("libfoo", version ("1.2.4")))); - assert (check_location (fpv4)); - assert (sr->complements.empty ()); assert (sr->prerequisites.size () == 2); assert (sr->prerequisites[0].load () == cr); @@ -152,6 +131,9 @@ main (int argc, char* argv[]) // // libfoo-1.0 // + shared_ptr fpv1 ( + db.load (package_id ("libfoo", version ("1.0")))); + assert (fpv1->summary == "The Foo Library"); assert (fpv1->tags.empty ()); assert (!fpv1->description); @@ -175,8 +157,16 @@ main (int argc, char* argv[]) assert (fpv1->dependencies.empty ()); assert (fpv1->requirements.empty ()); + assert (check_location (fpv1)); + + assert (fpv1->sha256sum && *fpv1->sha256sum == + "754cba3da34dd0296866027a26b6bacf08cacc80f54516d3b8d8eeccbe31ab93"); + // libfoo-1.2.2 // + shared_ptr fpv2 ( + db.load (package_id ("libfoo", version ("1.2.2")))); + assert (fpv2->summary == "The Foo library"); assert (fpv2->tags == strings ({"c++", "foo"})); assert (!fpv2->description); @@ -202,7 +192,8 @@ main (int argc, char* argv[]) [&db](const char* n, const optional& c) -> dependency { - return {lazy_shared_ptr (db, package_id (n, version ())), c}; + return { + lazy_shared_ptr (db, package_id (n, version ())), c}; }); assert (fpv2->dependencies[0][0] == @@ -219,8 +210,16 @@ main (int argc, char* argv[]) dependency_constraint ( version ("1~1.2"), false, version ("1~1.2"), false)))); + assert (check_location (fpv2)); + + assert (fpv2->sha256sum && *fpv2->sha256sum == + "751cba3da34dd0296866027a26b6bacf08cacc80f54516d3b8d8eeccbe31ab93"); + // libfoo-1.2.2-alpha.1 // + shared_ptr fpv2a ( + db.load (package_id ("libfoo", version ("1.2.2-alpha.1")))); + assert (fpv2a->summary == "The Foo library"); assert (fpv2a->tags == strings ({"c++", "foo"})); assert (!fpv2a->description); @@ -280,8 +279,16 @@ main (int argc, char* argv[]) assert (fpv2a->requirements.empty ()); + assert (check_location (fpv2a)); + + assert (fpv2a->sha256sum && *fpv2a->sha256sum == + "752cba3da34dd0296866027a26b6bacf08cacc80f54516d3b8d8eeccbe31ab93"); + // libfoo-1.2.3-4 // + shared_ptr fpv3 ( + db.load (package_id ("libfoo", version ("1.2.3+4")))); + assert (fpv3->summary == "The Foo library"); assert (fpv3->tags == strings ({"c++", "foo"})); assert (!fpv3->description); @@ -309,8 +316,16 @@ main (int argc, char* argv[]) dependency_constraint ( version ("2.0.0"), false, nullopt, true)))); + assert (check_location (fpv3)); + + assert (fpv3->sha256sum && *fpv3->sha256sum == + "750cba3da34dd0296866027a26b6bacf08cacc80f54516d3b8d8eeccbe31ab93"); + // libfoo-1.2.4 // + shared_ptr fpv4 ( + db.load (package_id ("libfoo", version ("1.2.4")))); + assert (fpv4->summary == "The Foo Library"); assert (fpv4->tags == strings ({"c++", "foo"})); assert (*fpv4->description == "Very good foo library."); @@ -339,6 +354,11 @@ main (int argc, char* argv[]) dependency_constraint ( version ("2.0.0"), false, nullopt, true)))); + assert (check_location (fpv4)); + + assert (fpv4->sha256sum && *fpv4->sha256sum == + "753cba3da34dd0296866027a26b6bacf08cacc80f54516d3b8d8eeccbe31ab93"); + // Verify 'math' repository. // assert (mr->location.canonical_name () == "cppget.org/math"); @@ -362,24 +382,15 @@ main (int argc, char* argv[]) file_mtime (dir_path (mr->local_path) / path ("repositories"))); assert (mr->internal); - shared_ptr epv ( - db.load (package_id ("libexp", version ("1~1.2+1")))); - assert (check_location (epv)); - - shared_ptr fpv5 ( - db.load (package_id ("libfoo", version ("1.2.4+1")))); - assert (check_location (fpv5)); - - shared_ptr xpv ( - db.load (package_id ("libstudxml", version ("1.0.0+1")))); - assert (check_location (xpv)); - assert (mr->complements.empty ()); assert (mr->prerequisites.size () == 1); assert (mr->prerequisites[0].load () == cr); // Verify libstudxml package version. // + shared_ptr xpv ( + db.load (package_id ("libstudxml", version ("1.0.0+1")))); + assert (xpv->summary == "Modern C++ XML API"); assert (xpv->tags == strings ({"c++", "xml", "parser", "serializer", "pull", "streaming", "modern"})); @@ -417,18 +428,26 @@ main (int argc, char* argv[]) assert (xpv->requirements.empty ()); + assert (check_location (xpv)); + + assert (xpv->sha256sum && *xpv->sha256sum == + "05ccba3da34dd0296866027a26b6bacf08cacc80f54516d3b8d8eeccbe31ab93"); + // Verify libfoo package versions. // // libfoo-1.2.4-1 // + shared_ptr fpv5 ( + db.load (package_id ("libfoo", version ("1.2.4+1")))); + assert (fpv5->summary == "The Foo Math Library"); assert (fpv5->tags == strings ({"c++", "foo", "math"})); assert (*fpv5->description == - "A modern C++ library with easy to use linear algebra and lot of " - "optimization\ntools.\n\nThere are over 100 functions in total " - "with an extensive test suite. The API is\nsimilar to MATLAB." - "\n\nUseful for conversion of research code into production " - "environments."); + "A modern C++ library with easy to use linear algebra and lot " + "of optimization\ntools.\n\nThere are over 100 functions in " + "total with an extensive test suite. The API is\nsimilar to " + "MATLAB.\n\nUseful for conversion of research code into " + "production environments."); assert (fpv5->url == "http://www.example.com/foo/"); assert (fpv5->package_url && *fpv5->package_url == "http://www.example.com/foo/pack"); @@ -518,10 +537,18 @@ main (int argc, char* argv[]) assert (fpvr5[3].conditional); assert (fpvr5[3].comment == "Only if using VC++ on Windows."); + assert (check_location (fpv5)); + + assert (fpv5->sha256sum && *fpv5->sha256sum == + "35ccba3da34dd0296866027a26b6bacf08cacc80f54516d3b8d8eeccbe31ab93"); + // Verify libexp package version. // // libexp-1+1.2 // + shared_ptr epv ( + db.load (package_id ("libexp", version ("1~1.2+1")))); + assert (epv->summary == "The exponent"); assert (epv->tags == strings ({"c++", "exponent"})); assert (epv->description && *epv->description == @@ -546,6 +573,11 @@ main (int argc, char* argv[]) assert (epv->requirements.empty ()); + assert (check_location (epv)); + + assert (epv->sha256sum && *epv->sha256sum == + "15ccba3da34dd0296866027a26b6bacf08cacc80f54516d3b8d8eeccbe31ab93"); + // Verify 'misc' repository. // assert (cr->location.canonical_name () == "cppget.org/misc"); @@ -566,19 +598,6 @@ main (int argc, char* argv[]) assert (cr->repositories_timestamp == file_mtime (dir_path (cr->local_path) / path ("repositories"))); assert (!cr->internal); - - shared_ptr bpv ( - db.load (package_id ("libbar", version ("2.4.0+3")))); - assert (check_location (bpv)); - - shared_ptr fpv0 ( - db.load (package_id ("libfoo", version ("0.1")))); - assert (check_location (fpv0)); - - shared_ptr fpv6 ( - db.load (package_id ("libfoo", version ("1.2.4+2")))); - assert (check_location (fpv6)); - assert (cr->prerequisites.empty ()); assert (cr->complements.size () == 1); assert (cr->complements[0].load () == tr); @@ -587,23 +606,35 @@ main (int argc, char* argv[]) // // libbar-2.4.0+3 // + shared_ptr bpv ( + db.load (package_id ("libbar", version ("2.4.0+3")))); + assert (check_external (*bpv)); assert (bpv->other_repositories.size () == 1); assert (bpv->other_repositories[0].load () == cr); + assert (check_location (bpv)); // Verify libfoo package versions. // // libfoo-0.1 // + shared_ptr fpv0 ( + db.load (package_id ("libfoo", version ("0.1")))); + assert (check_external (*fpv0)); assert (fpv0->other_repositories.size () == 1); assert (fpv0->other_repositories[0].load () == cr); + assert (check_location (fpv0)); // libfoo-1.2.4-2 // + shared_ptr fpv6 ( + db.load (package_id ("libfoo", version ("1.2.4+2")))); + assert (check_external (*fpv6)); assert (fpv6->other_repositories.size () == 1); assert (fpv6->other_repositories[0].load () == cr); + assert (check_location (fpv6)); // Verify 'testing' repository. // @@ -625,15 +656,6 @@ main (int argc, char* argv[]) assert (tr->repositories_timestamp == file_mtime (dir_path (tr->local_path) / path ("repositories"))); assert (!tr->internal); - - shared_ptr mpv0 ( - db.load (package_id ("libmisc", version ("2.4.0")))); - assert (check_location (mpv0)); - - shared_ptr mpv1 ( - db.load (package_id ("libmisc", version ("2.3.0+1")))); - assert (check_location (mpv1)); - assert (tr->prerequisites.empty ()); assert (tr->complements.size () == 1); assert (tr->complements[0].load () == gr); @@ -642,15 +664,23 @@ main (int argc, char* argv[]) // // libmisc-2.4.0 // + shared_ptr mpv0 ( + db.load (package_id ("libmisc", version ("2.4.0")))); + assert (check_external (*mpv0)); assert (mpv0->other_repositories.size () == 1); assert (mpv0->other_repositories[0].load () == tr); + assert (check_location (mpv0)); // libmisc-2.3.0+1 // + shared_ptr mpv1 ( + db.load (package_id ("libmisc", version ("2.3.0+1")))); + assert (check_external (*mpv1)); assert (mpv1->other_repositories.size () == 1); assert (mpv1->other_repositories[0].load () == tr); + assert (check_location (mpv1)); // Verify 'staging' repository. // @@ -672,19 +702,6 @@ main (int argc, char* argv[]) assert (gr->repositories_timestamp == file_mtime (dir_path (gr->local_path) / path ("repositories"))); assert (!gr->internal); - - shared_ptr tpv ( - db.load (package_id ("libexpat", version ("5.1")))); - assert (check_location (tpv)); - - shared_ptr gpv ( - db.load (package_id ("libgenx", version ("1.0")))); - assert (check_location (gpv)); - - shared_ptr mpv2 ( - db.load (package_id ("libmisc", version ("1.0")))); - assert (check_location (mpv2)); - assert (gr->prerequisites.empty ()); assert (gr->complements.empty ()); @@ -692,25 +709,37 @@ main (int argc, char* argv[]) // // libexpat-5.1 // + shared_ptr tpv ( + db.load (package_id ("libexpat", version ("5.1")))); + assert (check_external (*tpv)); assert (tpv->other_repositories.size () == 1); assert (tpv->other_repositories[0].load () == gr); + assert (check_location (tpv)); // Verify libgenx package version. // // libgenx-1.0 // + shared_ptr gpv ( + db.load (package_id ("libgenx", version ("1.0")))); + assert (check_external (*gpv)); assert (gpv->other_repositories.size () == 1); assert (gpv->other_repositories[0].load () == gr); + assert (check_location (gpv)); // Verify libmisc package version. // // libmisc-1.0 // + shared_ptr mpv2 ( + db.load (package_id ("libmisc", version ("1.0")))); + assert (check_external (*mpv2)); assert (mpv2->other_repositories.size () == 1); assert (mpv2->other_repositories[0].load () == gr); + assert (check_location (mpv2)); // Change package summary, update the object persistent state, rerun // loader and ensure the model were not rebuilt. diff --git a/www/package-version-details-body.css b/www/package-version-details-body.css index 8af54bc..2b16668 100644 --- a/www/package-version-details-body.css +++ b/www/package-version-details-body.css @@ -103,6 +103,12 @@ h1, h2, h3 font-size: 0.94em; } +#version tr.sha256 td .value +{ + /* Increase the chances of 64-char value not to be truncated. */ + font-size: 0.9em; +} + /* * Package details table. */ -- cgit v1.1