aboutsummaryrefslogtreecommitdiff
path: root/bpkg/manifest-utility.cxx
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2018-03-09 14:02:32 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2018-03-09 14:58:10 +0300
commit61adcbd5ca83762c02cfa421e09fbd65c52b6da9 (patch)
tree4eaf5089ad37104a53ca74464c26b597ed2414bc /bpkg/manifest-utility.cxx
parent538711543c68be94b3e7e3192394bc2f19f49516 (diff)
Fix up package manifest version for pkg-unpack
Diffstat (limited to 'bpkg/manifest-utility.cxx')
-rw-r--r--bpkg/manifest-utility.cxx95
1 files changed, 95 insertions, 0 deletions
diff --git a/bpkg/manifest-utility.cxx b/bpkg/manifest-utility.cxx
index 50ee4e8..b35af4a 100644
--- a/bpkg/manifest-utility.cxx
+++ b/bpkg/manifest-utility.cxx
@@ -6,8 +6,11 @@
#include <libbutl/url.mxx>
#include <libbutl/sha256.mxx>
+#include <libbutl/process.mxx>
+#include <libbutl/process-io.mxx> // operator<<(ostream, process_path)
#include <bpkg/diagnostics.hxx>
+#include <bpkg/common-options.hxx>
using namespace std;
using namespace butl;
@@ -180,4 +183,96 @@ namespace bpkg
return false;
}
}
+
+ optional<version>
+ package_version (const common_options& o, const dir_path& d)
+ {
+ const char* b (name_b (o));
+
+ try
+ {
+ process_path pp (process::path_search (b, exec_dir));
+
+ fdpipe pipe (open_pipe ());
+
+ process pr (
+ process_start_callback (
+ [] (const char* const args[], size_t n)
+ {
+ if (verb >= 2)
+ print_process (args, n);
+ },
+ 0 /* stdin */, pipe /* stdout */, 2 /* stderr */,
+ pp,
+
+ verb < 2
+ ? strings ({"-q"})
+ : verb == 2
+ ? strings ({"-v"})
+ : strings ({"--verbose", to_string (verb)}),
+
+ o.build_option (),
+ "info:",
+ d.representation ()));
+
+ // Shouldn't throw, unless something is severely damaged.
+ //
+ pipe.out.close ();
+
+ try
+ {
+ optional<version> r;
+
+ ifdstream is (move (pipe.in),
+ fdstream_mode::skip,
+ ifdstream::badbit);
+
+ for (string l; !eof (getline (is, l)); )
+ {
+ if (l.compare (0, 9, "version: ") == 0)
+ try
+ {
+ string v (l, 9);
+
+ // An empty version indicates that the version module is not
+ // enabled for the project.
+ //
+ if (!v.empty ())
+ r = version (v);
+
+ break;
+ }
+ catch (const invalid_argument&)
+ {
+ fail << "no package version in '" << l << "'" <<
+ info << "produced by '" << pp << "'; use --build to override";
+ }
+ }
+
+ is.close ();
+
+ if (pr.wait ())
+ return r;
+
+ // Fall through.
+ }
+ catch (const io_error&)
+ {
+ if (pr.wait ())
+ fail << "unable to read '" << b << "' output";
+
+ // Fall through.
+ }
+
+ // We should only get here if the child exited with an error status.
+ //
+ assert (!pr.wait ());
+
+ fail << "unable to obtain version using '" << b << "'" << endf;
+ }
+ catch (const process_error& e)
+ {
+ fail << "unable to execute '" << b << "': " << e << endf;
+ }
+ }
}