From a8218ef3b2f2706a810d10f3956982e5b0bd6c57 Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Thu, 8 Mar 2018 20:07:40 +0300 Subject: Search for repository location in database before parsing for pkg-build --- bpkg/pkg-build.cxx | 85 +++++++++++++++++++++++++++++++++--------------------- 1 file changed, 52 insertions(+), 33 deletions(-) (limited to 'bpkg/pkg-build.cxx') diff --git a/bpkg/pkg-build.cxx b/bpkg/pkg-build.cxx index efe7e20..5395d8d 100644 --- a/bpkg/pkg-build.cxx +++ b/bpkg/pkg-build.cxx @@ -1081,7 +1081,7 @@ namespace bpkg // Note that we consider '@' to be such a delimiter only if it comes // before ":/" (think a URL which could contain its own '@'). // - auto location = [] (const string& arg) -> size_t + auto find_location = [] (const string& arg) -> size_t { using url_traits = butl::url::traits; @@ -1109,6 +1109,35 @@ namespace bpkg return p; }; + database db (open (c, trace)); // Also populates the system repository. + + // Search for the repository location in the database before trying to + // parse it. Note that the straight parsing could otherwise fail, being + // unable to properly guess the repository type. + // + auto location = [&db] (const string& l) -> repository_location + { + using query = query; + + shared_ptr r ( + db.query_one (query::location.url == l)); + + if (r != nullptr) + return r->location; + + return parse_location (l, nullopt /* type */); + }; + + // Note that the session spans all our transactions. The idea here is + // that selected_package objects in the build_packages list below will + // be cached in this session. When subsequent transactions modify any + // of these objects, they will modify the cached instance, which means + // our list will always "see" their updated state. + // + // Also note that rep_fetch() must be called in session. + // + session s; + // Collect repository locations from @ arguments, // suppressing duplicates. // @@ -1117,44 +1146,36 @@ namespace bpkg // strings args; vector locations; - - while (a.more ()) { - string arg (a.next ()); - size_t p (location (arg)); + transaction t (db.begin ()); - if (p != string::npos) + while (a.more ()) { - repository_location l ( - parse_location (string (arg, p), nullopt /* type */)); + string arg (a.next ()); + size_t p (find_location (arg)); - auto pr = [&l] (const repository_location& i) -> bool + if (p != string::npos) { - return i.canonical_name () == l.canonical_name (); - }; + repository_location l (location (string (arg, p))); - auto i (find_if (locations.begin (), locations.end (), pr)); + auto pr = [&l] (const repository_location& i) -> bool + { + return i.canonical_name () == l.canonical_name (); + }; - if (i != locations.end ()) - *i = move (l); - else - locations.push_back (move (l)); - } + auto i (find_if (locations.begin (), locations.end (), pr)); - args.push_back (move (arg)); - } + if (i != locations.end ()) + *i = move (l); + else + locations.push_back (move (l)); + } - database db (open (c, trace)); // Also populates the system repository. + args.push_back (move (arg)); + } - // Note that the session spans all our transactions. The idea here is - // that selected_package objects in the build_packages list below will - // be cached in this session. When subsequent transactions modify any - // of these objects, they will modify the cached instance, which means - // our list will always "see" their updated state. - // - // Also note that rep_fetch() must be called in session. - // - session s; + t.commit (); + } if (!locations.empty ()) rep_fetch (o, c, db, locations); @@ -1167,7 +1188,7 @@ namespace bpkg for (string& arg: args) { - size_t p (location (arg)); + size_t p (find_location (arg)); if (p == string::npos) { @@ -1175,9 +1196,7 @@ namespace bpkg continue; } - repository_location l ( - parse_location (string (arg, p), nullopt /* type */)); - + repository_location l (location (string (arg, p))); shared_ptr r (db.load (l.canonical_name ())); // If no packages are specified explicitly (the argument starts with -- cgit v1.1