aboutsummaryrefslogtreecommitdiff
path: root/libbpkg/manifest.hxx
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2018-11-14 13:28:26 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2018-11-16 14:38:01 +0300
commit39c4230a41cdda3ba47ce1bb70cd2780d9da988d (patch)
treeb1342cea86fdc3cf197dd1e41d03065a019075a2 /libbpkg/manifest.hxx
parent3b064176e467f690a94544d511be2fe57a8f48c4 (diff)
Add support for repository typed URLs (git+https://..., etc)
Diffstat (limited to 'libbpkg/manifest.hxx')
-rw-r--r--libbpkg/manifest.hxx66
1 files changed, 58 insertions, 8 deletions
diff --git a/libbpkg/manifest.hxx b/libbpkg/manifest.hxx
index a017772..20c9caf 100644
--- a/libbpkg/manifest.hxx
+++ b/libbpkg/manifest.hxx
@@ -698,7 +698,7 @@ namespace bpkg
version_control
};
- // Guess the repository type for the URL:
+ // Guess the repository type from the URL:
//
// 1. If scheme is git then git.
//
@@ -714,6 +714,38 @@ namespace bpkg
LIBBPKG_EXPORT repository_type
guess_type (const repository_url&, bool local);
+ // Repository URL that may have a repository type specified as part of its
+ // scheme in the [<type>'+']<protocol> form. For example:
+ //
+ // git+http://example.com/repo (repository type + protocol)
+ // git://example.com/repo (protocol only)
+ //
+ // If the substring preceding the '+' character is not a valid repository
+ // type or the part that follows doesn't conform to the repository URL
+ // notation, then the whole string is considered to be a repository URL.
+ // For example, for all of the following strings the repository URL is
+ // untyped (local) and relative:
+ //
+ // foo+http://example.com/repo (invalid repository type)
+ // git+ftp://example.com/repo (invalid repository protocol)
+ // git+file://example.com/repo (invalid authority)
+ // git+c:/repo (not a URL notation)
+ //
+ // Note also that in quite a few manifests where we specify the location we
+ // also allow specifying the type as a separate value. While this may seem
+ // redundant (and it now is in a few cases, at least for the time being),
+ // keep in mind that for the local relative path the type cannot be
+ // specified as part of the URL (since its representation is a non-URL).
+ //
+ struct LIBBPKG_EXPORT typed_repository_url
+ {
+ repository_url url;
+ butl::optional<repository_type> type;
+
+ explicit
+ typed_repository_url (const std::string&);
+ };
+
class LIBBPKG_EXPORT repository_location
{
public:
@@ -721,6 +753,23 @@ namespace bpkg
//
repository_location () = default;
+ // Create a remote or absolute repository location from a potentially
+ // typed repository URL (see above).
+ //
+ // If the type is not specified in the URL scheme then use the one passed
+ // as an argument or, if not present, guess it according to the specified
+ // local flag (see above). Throw std::invalid_argument if the argument
+ // doesn't represent a valid remote or absolute repository location or
+ // mismatching types are specified in the URL scheme and in the argument.
+ // Underlying OS errors (which may happen when guessing the type when the
+ // local flag is set) are reported by throwing std::system_error.
+ //
+ explicit
+ repository_location (
+ const std::string&,
+ const butl::optional<repository_type>& = butl::nullopt,
+ bool local = false);
+
// Create remote, absolute or empty repository location making sure that
// the URL matches the repository type. Throw std::invalid_argument if the
// URL object is a relative local path.
@@ -746,7 +795,7 @@ namespace bpkg
//
repository_location (repository_url, repository_type);
- // Create a potentially relative pkg repository location. If base is not
+ // Create a potentially relative repository location. If base is not
// empty, use it to complete the relative location to the remote/absolute
// one. Throw std::invalid_argument if base is not empty but the location
// is empty, base itself is relative, or the resulting completed location
@@ -830,7 +879,7 @@ namespace bpkg
return repository_basis::archive;
}
- // URL of an empty location is empty.
+ // Note that the URL of an empty location is empty.
//
const repository_url&
url () const
@@ -906,13 +955,14 @@ namespace bpkg
return basis () == repository_basis::version_control;
}
- // String representation of an empty location is the empty string.
+ // Return an untyped URL if the correct type can be guessed just from
+ // the URL. Otherwise, return the typed URL.
+ //
+ // String representation is empty for an empty location and is always
+ // untyped for the relative location (which is a non-URL).
//
std::string
- string () const
- {
- return url_.string ();
- }
+ string () const;
private:
std::string canonical_name_;