|
12 | 12 |
|
13 | 13 | #include <sw/manager/storage.h> |
14 | 14 |
|
| 15 | +#include <boost/thread/lock_types.hpp> |
| 16 | +#include <boost/thread/shared_mutex.hpp> |
15 | 17 | #include <primitives/executor.h> |
16 | 18 |
|
| 19 | +#include <regex> |
| 20 | + |
17 | 21 | namespace sw |
18 | 22 | { |
19 | 23 |
|
@@ -66,5 +70,53 @@ void SwBuilderContext::clearFileStorages() |
66 | 70 | file_storage.reset(); |
67 | 71 | } |
68 | 72 |
|
| 73 | +static Version gatherVersion(const path &program, const String &arg = "--version", const String &in_regex = {}) |
| 74 | +{ |
| 75 | + static std::regex r_default("(\\d+)\\.(\\d+)\\.(\\d+)(\\.(\\d+))?"); |
| 76 | + |
| 77 | + std::regex r_in; |
| 78 | + if (!in_regex.empty()) |
| 79 | + r_in.assign(in_regex); |
| 80 | + |
| 81 | + auto &r = in_regex.empty() ? r_default : r_in; |
| 82 | + |
| 83 | + Version V; |
| 84 | + builder::detail::ResolvableCommand c; // for nice program resolving |
| 85 | + c.setProgram(program); |
| 86 | + if (!arg.empty()) |
| 87 | + c.arguments = { arg }; |
| 88 | + error_code ec; |
| 89 | + c.execute(ec); |
| 90 | + |
| 91 | + if (c.pid == -1) |
| 92 | + throw SW_RUNTIME_ERROR(normalize_path(program) + ": " + ec.message()); |
| 93 | + |
| 94 | + std::smatch m; |
| 95 | + if (std::regex_search(c.err.text.empty() ? c.out.text : c.err.text, m, r)) |
| 96 | + { |
| 97 | + if (m[5].matched) |
| 98 | + V = { std::stoi(m[1].str()), std::stoi(m[2].str()), std::stoi(m[3].str()), std::stoi(m[5].str()) }; |
| 99 | + else |
| 100 | + V = { std::stoi(m[1].str()), std::stoi(m[2].str()), std::stoi(m[3].str()) }; |
| 101 | + } |
| 102 | + return V; |
| 103 | +} |
| 104 | + |
| 105 | +Version getVersion(const SwBuilderContext &swctx, const path &program, const String &arg, const String &in_regex) |
| 106 | +{ |
| 107 | + auto &vs = swctx.getVersionStorage(); |
| 108 | + static boost::upgrade_mutex m; |
| 109 | + |
| 110 | + boost::upgrade_lock lk(m); |
| 111 | + auto i = vs.versions.find(program); |
| 112 | + if (i != vs.versions.end()) |
| 113 | + return i->second; |
| 114 | + |
| 115 | + boost::upgrade_to_unique_lock lk2(lk); |
| 116 | + |
| 117 | + vs.versions[program] = gatherVersion(program, arg, in_regex); |
| 118 | + return vs.versions[program]; |
| 119 | +} |
| 120 | + |
69 | 121 | } |
70 | 122 |
|
0 commit comments