From 7cf0854121525747b438b7f94bf2d050f61fb615 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Wed, 18 Apr 2018 12:35:37 +0200 Subject: Implement git repository handling transition (phase 0) --- libbpkg/manifest.cxx | 59 +++++++++++++++++------------------- libbpkg/manifest.hxx | 23 ++++++++------ tests/repository-location/driver.cxx | 42 +++++++++++++++---------- 3 files changed, 67 insertions(+), 57 deletions(-) diff --git a/libbpkg/manifest.cxx b/libbpkg/manifest.cxx index 951c6a6..e1dfb52 100644 --- a/libbpkg/manifest.cxx +++ b/libbpkg/manifest.cxx @@ -2092,7 +2092,9 @@ namespace bpkg { // Verify the URL fragment. // - git_reference r (url_.fragment); + if (url_.fragment) + git_ref_filter r (*url_.fragment); + break; } } @@ -2286,44 +2288,39 @@ namespace bpkg } } - // git_reference + // git_ref_filter // - git_reference:: - git_reference (const optional& frag) + git_ref_filter:: + git_ref_filter (const string& frag) { - if (frag) + size_t p (frag.find ('@')); + if (p != string::npos) { - const string& s (*frag); - - size_t p (s.find ('@')); - if (p != string::npos) - { - if (p != 0) - branch = string (s, 0, p); + if (p != 0) + name = string (frag, 0, p); - if (p + 1 != s.size ()) - commit = string (s, p + 1); - } - else if (!s.empty ()) - { - // A 40-characters fragment that consists of only hexadecimal digits is - // assumed to be a commit id. - // - if (s.size () == 40 && - find_if_not (s.begin (), s.end (), + if (p + 1 != frag.size ()) + commit = string (frag, p + 1); + } + else if (!frag.empty ()) + { + // A 40-characters fragment that consists of only hexadecimal digits is + // assumed to be a commit id. + // + if (frag.size () == 40 && + find_if_not (frag.begin (), frag.end (), - // Resolve the required overload. - // - static_cast (xdigit)) == s.end ()) - commit = s; - else - branch = s; - } + // Resolve the required overload. + // + static_cast (xdigit)) == frag.end ()) + commit = frag; + else + name = frag; } - if (!branch && !commit) + if (!name && !commit) throw invalid_argument ( - "missing branch/tag or commit id for git repository"); + "missing reference name or commit id for git repository"); if (commit && commit->size () != 40) throw invalid_argument ( diff --git a/libbpkg/manifest.hxx b/libbpkg/manifest.hxx index a44ffcc..fdec69e 100644 --- a/libbpkg/manifest.hxx +++ b/libbpkg/manifest.hxx @@ -834,25 +834,28 @@ namespace bpkg return os << l.string (); } - // Branch and/or commit. At least one of them must be present. If both of - // them are present then the commit is expected to belong to the branch - // history. Note that the branch member can also denote a tag. + // Git refname and/or commit. At least one of them must be present. If both + // are present then the commit is expected to belong to the history of the + // specified ref (e.g., tag or branch). Note that the name member can also + // be an abbreviated commit id (full, 40-character commit ids should always + // be stored in the commit member since then may refer to an unadvertised + // commit). // - class LIBBPKG_EXPORT git_reference + class LIBBPKG_EXPORT git_ref_filter { public: - butl::optional branch; + butl::optional name; butl::optional commit; public: - // Parse the [][@] repository URL fragment representation. + // Parse the [][@] repository URL fragment representation. // explicit - git_reference (const butl::optional&); + git_ref_filter (const std::string&); - git_reference (butl::optional b, - butl::optional c) - : branch (std::move (b)), + git_ref_filter (butl::optional n, + butl::optional c) + : name (std::move (n)), commit (std::move (c)) {} }; diff --git a/tests/repository-location/driver.cxx b/tests/repository-location/driver.cxx index 014b810..2e39c26 100644 --- a/tests/repository-location/driver.cxx +++ b/tests/repository-location/driver.cxx @@ -154,17 +154,8 @@ namespace bpkg assert (bad_loc ("c:\\aaa\\bbb")); #endif - // Invalid/absent URL fragment. + // Invalid URL fragment. // -#ifndef _WIN32 - assert (bad_loc ("file://localhost/", repository_type::git)); -#else - assert (bad_loc ("file://localhost/c:/", repository_type::git)); -#endif - - assert (bad_loc ("https://www.example.com/test.git", - repository_type::git)); - assert (bad_loc ("https://www.example.com/test.git#", repository_type::git)); @@ -320,6 +311,11 @@ namespace bpkg assert (l.canonical_name () == "git:/git/repo#branch"); } { + repository_location l (loc ("file://localhost/", repository_type::git)); + assert (l.string () == "/"); + assert (l.canonical_name () == "git:/"); + } + { repository_location l (loc ("file://localhost/#master", repository_type::git)); assert (l.string () == "file:/#master"); @@ -392,6 +388,12 @@ namespace bpkg assert (l.canonical_name () == "git:c:\\git\\repo#branch"); } { + repository_location l (loc ("file://localhost/c:/", + repository_type::git)); + assert (l.string () == "c:"); + assert (l.canonical_name () == "git:c:"); + } + { repository_location l (loc ("file://localhost/c:/#master", repository_type::git)); assert (l.string () == "file:/c:#master"); @@ -451,6 +453,14 @@ namespace bpkg assert (l.type () == repository_type::pkg); } { + repository_location l (loc ("https://www.example.com/test.git", + repository_type::git)); + assert (l.string () == "https://www.example.com/test.git"); + assert (l.canonical_name () == "git:example.com/test"); + assert (l.proto () == proto::https); + assert (l.type () == repository_type::git); + } + { repository_location l (loc ("git://example.com/test#master", repository_type::git)); assert (l.string () == "git://example.com/test#master"); @@ -805,13 +815,13 @@ namespace bpkg string branch ("master"); string commit ("0a53e9ddeaddad63ad106860237bbf53411d11a7"); - assert (*git_reference (branch).branch == branch); - assert (*git_reference (commit + "@").branch == commit); - assert (*git_reference (commit).commit == commit); - assert (*git_reference ("@" + commit).commit == commit); + assert (*git_ref_filter (branch).name == branch); + assert (*git_ref_filter (commit + "@").name == commit); + assert (*git_ref_filter (commit).commit == commit); + assert (*git_ref_filter ("@" + commit).commit == commit); - git_reference r (branch + "@" + commit); - assert (*r.branch == branch && *r.commit == commit); + git_ref_filter r (branch + "@" + commit); + assert (*r.name == branch && *r.commit == commit); } // repository_url -- cgit v1.1