From 61adcbd5ca83762c02cfa421e09fbd65c52b6da9 Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Fri, 9 Mar 2018 14:02:32 +0300 Subject: Fix up package manifest version for pkg-unpack --- bpkg/manifest-utility.cxx | 95 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) (limited to 'bpkg/manifest-utility.cxx') 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 #include +#include +#include // operator<<(ostream, process_path) #include +#include using namespace std; using namespace butl; @@ -180,4 +183,96 @@ namespace bpkg return false; } } + + optional + 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 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; + } + } } -- cgit v1.1