diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2015-09-25 07:12:49 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2015-09-25 07:12:49 +0200 |
commit | 0143c3ff25a753df6f73d6319f7fb4a62a4d53c6 (patch) | |
tree | 82e8e799b6479cd17d646955e7b469f56b2117e4 | |
parent | 287c71ddc00f0db1436d557042b69c03dc448b13 (diff) |
Implement rep-info command
-rw-r--r-- | bpkg/bpkg-options.cli | 7 | ||||
-rw-r--r-- | bpkg/bpkg.cxx | 2 | ||||
-rw-r--r-- | bpkg/buildfile | 4 | ||||
-rw-r--r-- | bpkg/rep-info | 17 | ||||
-rw-r--r-- | bpkg/rep-info-options.cli | 51 | ||||
-rw-r--r-- | bpkg/rep-info.cxx | 117 | ||||
-rwxr-xr-x | bpkg/test.sh | 14 |
7 files changed, 210 insertions, 2 deletions
diff --git a/bpkg/bpkg-options.cli b/bpkg/bpkg-options.cli index 029c5a8..c67f8d7 100644 --- a/bpkg/bpkg-options.cli +++ b/bpkg/bpkg-options.cli @@ -105,6 +105,13 @@ namespace bpkg "" }; + bool rep-info + { + "<rep>", + "Print information about repository.", + "" + }; + bool rep-create { "[<dir>]", diff --git a/bpkg/bpkg.cxx b/bpkg/bpkg.cxx index 75684cb..3ac5002 100644 --- a/bpkg/bpkg.cxx +++ b/bpkg/bpkg.cxx @@ -30,6 +30,7 @@ #include <bpkg/rep-add> #include <bpkg/rep-fetch> +#include <bpkg/rep-info> #include <bpkg/rep-create> using namespace std; @@ -201,6 +202,7 @@ try REP_COMMAND (add); REP_COMMAND (fetch); + REP_COMMAND (info); REP_COMMAND (create); // @@ Would be nice to check that args doesn't contain any junk left. diff --git a/bpkg/buildfile b/bpkg/buildfile index e57ec5e..919f5fe 100644 --- a/bpkg/buildfile +++ b/bpkg/buildfile @@ -28,6 +28,7 @@ exe{bpkg}: cxx{fetch package package-odb database diagnostics \ cxx{cfg-create} cli.cxx{cfg-create-options} \ cxx{rep-add} cli.cxx{rep-add-options} \ cxx{rep-fetch} cli.cxx{rep-fetch-options} \ + cxx{rep-info} cli.cxx{rep-info-options} \ cxx{rep-create} cli.cxx{rep-create-options} \ $libs @@ -77,5 +78,8 @@ cli.cxx{rep-add-options}: cli.options += --exclude-base cli.cxx{rep-fetch-options}: cli{rep-fetch-options} cli.cxx{rep-fetch-options}: cli.options += --exclude-base +cli.cxx{rep-info-options}: cli{rep-info-options} +cli.cxx{rep-info-options}: cli.options += --exclude-base + cli.cxx{rep-create-options}: cli{rep-create-options} cli.cxx{rep-create-options}: cli.options += --exclude-base diff --git a/bpkg/rep-info b/bpkg/rep-info new file mode 100644 index 0000000..8437a53 --- /dev/null +++ b/bpkg/rep-info @@ -0,0 +1,17 @@ +// file : bpkg/rep-info -*- C++ -*- +// copyright : Copyright (c) 2014-2015 Code Synthesis Ltd +// license : MIT; see accompanying LICENSE file + +#ifndef BPKG_REP_INFO +#define BPKG_REP_INFO + +#include <bpkg/types> +#include <bpkg/rep-info-options> + +namespace bpkg +{ + void + rep_info (const rep_info_options&, cli::scanner& args); +} + +#endif // BPKG_REP_INFO diff --git a/bpkg/rep-info-options.cli b/bpkg/rep-info-options.cli new file mode 100644 index 0000000..2d3aa33 --- /dev/null +++ b/bpkg/rep-info-options.cli @@ -0,0 +1,51 @@ +// file : bpkg/rep-info-options.cli +// copyright : Copyright (c) 2014-2015 Code Synthesis Ltd +// license : MIT; see accompanying LICENSE file + +include <bpkg/common-options.cli>; + +/* +"\section=1" +"\name=bpkg-rep-info" + +"\h{SYNOPSIS} + +bpkg rep-info [<options>] <rep>" + +"\h{DESCRIPTION} + +The \cb{rep-info} command prints information about the specified repository. +By default it print the repository's name and location as the first line +followed by the list of prerequisite/complement repositories and the list +of available packages. This default behavior, however, can be altered in +various ways using options listed below." +*/ + +namespace bpkg +{ + class rep_info_options: common_options + { + bool --name|-n + { + "Print the specified repository's name and location." + }; + + bool --repositories|-r + { + "Print information about prerequisite/complement repositories." + }; + + bool --packages|-p + { + "Print information about available packages." + }; + + bool --manifest|-m + { + "Instead of printing the information in the human-readable form, dump + it as manifest(s). Normally you would use this option in combination + with \cb{--packages|-p} or \cb{--repositories|-r} to only dump one + of the manifests." + }; + }; +} diff --git a/bpkg/rep-info.cxx b/bpkg/rep-info.cxx new file mode 100644 index 0000000..64ac9b1 --- /dev/null +++ b/bpkg/rep-info.cxx @@ -0,0 +1,117 @@ +// file : bpkg/rep-info.cxx -*- C++ -*- +// copyright : Copyright (c) 2014-2015 Code Synthesis Ltd +// license : MIT; see accompanying LICENSE file + +#include <bpkg/rep-info> + +#include <iostream> // cout +#include <stdexcept> // invalid_argument + +#include <bpkg/manifest> +#include <bpkg/manifest-serializer> + +#include <bpkg/fetch> +#include <bpkg/types> +#include <bpkg/utility> +#include <bpkg/diagnostics> + +using namespace std; +using namespace butl; + +namespace bpkg +{ + void + rep_info (const rep_info_options& o, cli::scanner& args) + { + tracer trace ("rep_info"); + + if (!args.more ()) + fail << "repository location argument expected" << + info << "run 'bpkg help rep-info' for more information"; + + // Figure out the repository location. + // + // @@ The same code as in rep-add, factor out. + // + const char* arg (args.next ()); + repository_location rl; + try + { + rl = repository_location (arg, repository_location ()); + + if (rl.relative ()) // Throws if location is empty. + rl = repository_location ( + dir_path (arg).complete ().normalize ().string ()); + } + catch (const invalid_argument& e) + { + fail << "invalid repository location '" << arg << "': " << e.what (); + } + + // Fetch everything we will need before printing anything. + // + repository_manifests rms (fetch_repositories (o, rl)); + package_manifests pms (fetch_packages (o, rl)); + + // Now print. + // + bool all (!o.name () && !o.repositories () && !o.packages ()); + + try + { + cout.exceptions (ostream::badbit | ostream::failbit); + + if (all || o.name ()) + cout << rl.canonical_name () << " " << rl << endl; + + // Repositories. + // + if (all || o.repositories ()) + { + if (o.manifest ()) + { + manifest_serializer s (cout, "STDOUT"); + rms.serialize (s); + } + else + { + for (const repository_manifest& rm: rms) + { + if (rm.location.empty ()) + continue; // Itself. + + repository_location l (rm.location, rl); // Complete. + + //@@ Handle complements. + // + cout << "prerequisite " << l.canonical_name () << " " << l << endl; + } + } + } + + // Packages. + // + if (all || o.packages ()) + { + if (o.manifest ()) + { + manifest_serializer s (cout, "STDOUT"); + pms.serialize (s); + } + else + { + for (const package_manifest& pm: pms) + cout << pm.name << " " << pm.version << endl; + } + } + } + catch (const manifest_serialization& e) + { + fail << "unable to serialize manifest: " << e.description; + } + catch (const ostream::failure&) + { + fail << "unable to write to STDOUT"; + } + } +} diff --git a/bpkg/test.sh b/bpkg/test.sh index 75555f8..d1ab6f2 100755 --- a/bpkg/test.sh +++ b/bpkg/test.sh @@ -23,7 +23,7 @@ function test () local cmd=$1; shift local ops= - if [ "$cmd" != "rep-create" ]; then + if [ "$cmd" != "rep-create" -a "$cmd" != "rep-info" ]; then ops="-d $cfg" fi @@ -39,7 +39,7 @@ function fail () local cmd=$1; shift local ops= - if [ "$cmd" != "rep-create" ]; then + if [ "$cmd" != "rep-create" -a "$cmd" != "rep-info" ]; then ops="-d $cfg" fi @@ -86,6 +86,16 @@ test rep-create ../tests/repository/1/math/testing test rep-create ../tests/repository/1/math/unstable ## +## rep-info +## + +fail rep-info # repository location expected + +test rep-info ../tests/repository/1/misc/testing +test rep-info -m ../tests/repository/1/math/unstable +test rep-info http://pkg.cppget.org/1/hello + +## ## cfg-create ## |