aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2018-11-14 16:12:25 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2018-11-16 14:43:20 +0300
commit5d69b98c5d62b05d1d6d6fd24aeac468af509365 (patch)
treea7d24e3b785e266fece5ff1fa66e691a4846ca75
parentdfd879004b1a66ff197c4d41d9fb2e0839781a38 (diff)
Add support for repository typed URLs (git+https://..., etc)
-rw-r--r--bpkg/manifest-utility.cxx27
-rw-r--r--bpkg/rep-add.cli6
-rw-r--r--bpkg/rep-fetch.cxx4
-rw-r--r--bpkg/repository-types.cli11
-rw-r--r--tests/rep-add.testscript149
-rw-r--r--tests/rep-fetch.testscript26
6 files changed, 144 insertions, 79 deletions
diff --git a/bpkg/manifest-utility.cxx b/bpkg/manifest-utility.cxx
index c329108..79c131b 100644
--- a/bpkg/manifest-utility.cxx
+++ b/bpkg/manifest-utility.cxx
@@ -92,7 +92,9 @@ namespace bpkg
parse_location (const string& s, optional<repository_type> ot)
try
{
- repository_url u (s);
+ typed_repository_url tu (s);
+
+ repository_url& u (tu.url);
assert (u.path);
// Make the relative path absolute using the current directory.
@@ -102,13 +104,24 @@ namespace bpkg
// Guess the repository type to construct the repository location:
//
- // 1. If type is specified as an option use that (but validate
- // incompatible scheme/type e.g., git/pkg).
+ // 1. If the type is specified in the URL scheme, then use that (but
+ // validate that it matches the --type option, if present).
+ //
+ // 2. If the type is specified as an option, then use that.
//
- // 2. See guess_type() function description in libbpkg/manifest.hxx for
- // the algorithm details.
+ // Validate the protocol/type compatibility (e.g. git:// vs pkg) for both
+ // cases.
//
- repository_type t (ot ? *ot : guess_type (u, true));
+ // 3. See the guess_type() function description in <libbpkg/manifest.hxx>
+ // for the algorithm details.
+ //
+ if (tu.type && ot && tu.type != ot)
+ fail << to_string (*ot) << " repository type mismatch for location '"
+ << s << "'";
+
+ repository_type t (tu.type ? *tu.type :
+ ot ? *ot :
+ guess_type (tu.url, true /* local */));
try
{
@@ -125,7 +138,7 @@ namespace bpkg
// If the pkg repository type was guessed, then suggest the user to
// specify the type explicitly.
//
- if (!ot && t == repository_type::pkg)
+ if (!tu.type && !ot && t == repository_type::pkg)
dr << info << "consider using --type to specify repository type";
dr << endf;
diff --git a/bpkg/rep-add.cli b/bpkg/rep-add.cli
index 481b30a..9605ac7 100644
--- a/bpkg/rep-add.cli
+++ b/bpkg/rep-add.cli
@@ -40,9 +40,9 @@ namespace bpkg
case of a local repository, its content (for example, the presence of the
\cb{.git/} subdirectory). Without any identifying information the
\cb{pkg} type is assumed unless explicitly specified with the \cb{--type}
- option. Note, however, that the \cb{dir} repository type is never guessed
- since it is not easily distinguishable from local \cb{pkg} and \cb{git}
- repositories.
+ option or in the URL scheme. Note, however, that the \cb{dir} repository
+ type is never guessed since it is not easily distinguishable from local
+ \cb{pkg} and \cb{git} repositories.
"
}
diff --git a/bpkg/rep-fetch.cxx b/bpkg/rep-fetch.cxx
index 77ffc10..ef42b03 100644
--- a/bpkg/rep-fetch.cxx
+++ b/bpkg/rep-fetch.cxx
@@ -537,8 +537,8 @@ namespace bpkg
}
catch (const invalid_argument& e)
{
- fail << "invalid relative repository location '" << l
- << "': " << e <<
+ fail << "invalid relative repository location '" << l << "': "
+ << e <<
info << "base repository location is " << rl;
}
diff --git a/bpkg/repository-types.cli b/bpkg/repository-types.cli
index 79c50f8..1471ecf 100644
--- a/bpkg/repository-types.cli
+++ b/bpkg/repository-types.cli
@@ -16,6 +16,17 @@ structure, and the format of their URLs. Currently three types of repositories
are supported: archive-based \cb{pkg}, directory-based \cb{dir}, and version
control-based \cb{git}.
+The repository location may specify the repository type as part of the URL
+scheme component in the \c{\i{type}\b{+}\i{protocol}} form. For example:
+
+\
+git+https://example.com/foo
+dir+file:///tmp/repo
+\
+
+Note that the explicit specification is only needed when the correct type
+cannot be guessed from the URL. See \l{bpkg-rep-add(1)} for details.
+
\h|PKG REPOSITORIES|
diff --git a/tests/rep-add.testscript b/tests/rep-add.testscript
index b57eb68..3280bc6 100644
--- a/tests/rep-add.testscript
+++ b/tests/rep-add.testscript
@@ -14,9 +14,9 @@ rep_list += -d cfg
: none
:
$* 2>>EOE != 0
- error: repository location argument expected
- info: run 'bpkg help rep-add' for more information
- EOE
+ error: repository location argument expected
+ info: run 'bpkg help rep-add' for more information
+ EOE
: empty
:
@@ -24,15 +24,15 @@ rep_list += -d cfg
$clone_cfg;
$* '' 2>>EOE != 0
- error: invalid repository location '': empty URL
- EOE
+ error: invalid repository location '': empty URL
+ EOE
}
: unknown-type
:
$* 'repo' --type unknown 2>>EOE != 0
- error: invalid value 'unknown' for option '--type'
- EOE
+ error: invalid value 'unknown' for option '--type'
+ EOE
: no-version
:
@@ -40,9 +40,9 @@ rep_list += -d cfg
$clone_cfg;
$* 'stable' 2>>/~%EOE% != 0
- %error: invalid pkg repository location '.+/no-version/stable': missing repository version%
- info: consider using --type to specify repository type
- EOE
+ %error: invalid pkg repository location '.+/no-version/stable': missing repository version%
+ info: consider using --type to specify repository type
+ EOE
}
: git-invalid-fragment
@@ -51,18 +51,28 @@ rep_list += -d cfg
$clone_cfg;
$* 'git://example.org/repo#' 2>>EOE != 0
- error: invalid git repository location 'git://example.org/repo#': missing refname or commit id for git repository
- EOE
+ error: invalid git repository location 'git://example.org/repo#': missing refname or commit id for git repository
+ EOE
}
- : pkg-git-scheme
+ : git-scheme-pkg-type
:
{
$clone_cfg;
$* 'git://example.org/repo' --type pkg 2>>EOE != 0
- error: invalid pkg repository location 'git://example.org/repo': unsupported scheme for pkg repository
- EOE
+ error: invalid pkg repository location 'git://example.org/repo': unsupported scheme for pkg repository
+ EOE
+ }
+
+ : git-pkg-types
+ :
+ {
+ $clone_cfg;
+
+ $* 'git+https://example.org/repo' --type pkg 2>>EOE != 0
+ error: pkg repository type mismatch for location 'git+https://example.org/repo'
+ EOE
}
: invalid-path
@@ -74,8 +84,8 @@ rep_list += -d cfg
$clone_cfg;
$* "$s" 2>>~%EOE% != 0
- %error: invalid repository path '.+/': invalid filesystem path%
- EOE
+ %error: invalid repository path '.+/': invalid filesystem path%
+ EOE
}
: type-detection
@@ -85,40 +95,53 @@ rep_list += -d cfg
: git-scheme
:
- $clone_cfg;
- $* 'git://example.org/repo#master' 2>>EOE
- added git:example.org/repo#master
- EOE
+ {
+ $clone_cfg;
+
+ $* 'git://example.org/repo#master' 2>>EOE
+ added git:example.org/repo#master
+ EOE
+ }
: http-git
:
- $clone_cfg;
- $* 'http://example.org/repo.git#master' 2>>EOE
- added git:example.org/repo#master
- EOE
+ {
+ $clone_cfg;
+
+ $* 'http://example.org/repo.git#master' 2>>EOE
+ added git:example.org/repo#master
+ EOE
+ }
: http-pkg
:
- $clone_cfg;
- $* 'http://example.org/1/repo' 2>>EOE
- added pkg:example.org/repo
- EOE
+ {
+ $clone_cfg;
+
+ $* 'http://example.org/1/repo' 2>>EOE
+ added pkg:example.org/repo
+ EOE
+ }
: file-git
:
- $clone_cfg && mkdir -p repo/.git;
+ {
+ $clone_cfg && mkdir -p repo/.git;
- $* 'repo' 2>>/~%EOE%
- %added git:.+/repo%
- EOE
+ $* 'repo' 2>>/~%EOE%
+ %added git:.+/repo%
+ EOE
+ }
: file-pkg
:
- $clone_cfg;
+ {
+ $clone_cfg;
- $* '1/repo' 2>>/~%EOE%
- %added .+/repo%
- EOE
+ $* '1/repo' 2>>/~%EOE%
+ %added .+/repo%
+ EOE
+ }
}
}
@@ -157,34 +180,52 @@ rep_list += -d cfg
: pkg
:
- $clone_cfg;
+ {
+ $clone_cfg;
- $* 'http://pkg.example.org/1/testing' 2>>EOE;
- added pkg:example.org/testing
- EOE
+ $* 'http://pkg.example.org/1/testing' 2>>EOE;
+ added pkg:example.org/testing
+ EOE
- $* 'https://www.example.org/1/testing' 2>>EOE;
- updated pkg:example.org/testing
- EOE
+ $* 'https://www.example.org/1/testing' 2>>EOE;
+ updated pkg:example.org/testing
+ EOE
- $rep_list >>EOO
- pkg:example.org/testing https://www.example.org/1/testing
- EOO
+ $rep_list >>EOO
+ pkg:example.org/testing https://www.example.org/1/testing
+ EOO
+ }
: git
:
- $clone_cfg;
+ {
+ $clone_cfg;
- $* 'git://example.org/testing.git#master' 2>>~%EOE%;
- %added git:example.org/testing#master%
- EOE
+ $* 'git://example.org/testing.git#master' 2>>~%EOE%;
+ %added git:example.org/testing#master%
+ EOE
+
+ $* 'https://www.example.org/testing.git#master' 2>>EOE;
+ updated git:example.org/testing#master
+ EOE
+
+ $rep_list >>EOO
+ git:example.org/testing#master https://www.example.org/testing.git#master
+ EOO
+ }
+}
+
+: typed-url
+:
+{
+ $clone_cfg;
- $* 'https://www.example.org/testing.git#master' 2>>EOE;
- updated git:example.org/testing#master
+ $* 'git+https://example.org/repo' 2>>EOE;
+ added git:example.org/repo
EOE
$rep_list >>EOO
- git:example.org/testing#master https://www.example.org/testing.git#master
+ git:example.org/repo git+https://example.org/repo
EOO
}
diff --git a/tests/rep-fetch.testscript b/tests/rep-fetch.testscript
index 8320f70..4138209 100644
--- a/tests/rep-fetch.testscript
+++ b/tests/rep-fetch.testscript
@@ -486,9 +486,9 @@ if ($remote != true)
3 package\(s\) in 2 repository\(s\)
EOE
- $rep_list >>"EOO"
- dir:($rep/libbar.git) ($rep/libbar.git)
- prerequisite dir:($rep/style-basic.git) ($rep/style-basic.git)
+ $rep_list >>~%EOO%
+ %dir:.+libbar\.git dir\+file:///.+libbar\.git%
+ % prerequisite dir:.+style-basic\.git dir\+file:///.+style-basic\.git%
EOO
}
@@ -506,9 +506,9 @@ if ($remote != true)
3 package\(s\) in 2 repository\(s\)
EOE
- $rep_list >>"EOO"
- dir:($rep/libbar.git) ($rep/libbar.git)
- prerequisite dir:($rep/style-basic.git) ($rep/style-basic.git)
+ $rep_list >>~%EOO%
+ %dir:.+libbar\.git dir\+file:///.+libbar\.git%
+ % prerequisite dir:.+style-basic\.git dir\+file:///.+style-basic\.git%
EOO
}
@@ -527,9 +527,9 @@ if ($remote != true)
3 package\(s\) in 2 repository\(s\)
EOE
- $rep_list >>"EOO"
- dir:($rep/libbar.git) ($rep/libbar.git)
- prerequisite dir:($rep/style-basic.git) ($rep/style-basic.git)
+ $rep_list >>~%EOO%
+ %dir:.+libbar\.git dir\+file:///.+libbar\.git%
+ % prerequisite dir:.+style-basic\.git dir\+file:///.+style-basic\.git%
EOO
}
@@ -544,9 +544,9 @@ if ($remote != true)
3 package\(s\) in 2 repository\(s\)
EOE
- $rep_list >>"EOO"
- dir:($rep/libbar.git) ($rep/libbar.git)
- prerequisite dir:($rep/style-basic.git) ($rep/style-basic.git)
+ $rep_list >>~%EOO%
+ %dir:.+libbar\.git dir\+file:///.+libbar\.git%
+ % prerequisite dir:.+style-basic\.git dir\+file:///.+style-basic\.git%
EOO
}
}
@@ -771,7 +771,7 @@ else
$rep_list >>~%EOO%
%git:.+libbar#master file:.+libbar\.git#master%
- % prerequisite git:.+style-basic#stable file:.+style-basic#stable \(heads/master\)%
+ % prerequisite git:.+style-basic#stable git\+file:.+style-basic#stable \(heads/master\)%
EOO
}