LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
get_LibraryInfoCollection.cc
Go to the documentation of this file.
5 #include "cetlib/LibraryManager.h"
7 
8 #include <iomanip>
9 #include <iostream>
10 #include <regex>
11 #include <set>
12 #include <utility>
13 
14 using namespace art::detail;
15 using namespace std::string_literals;
16 using cet::LibraryManager;
17 
18 namespace {
19 
20  std::string const regex_prefix{"([-A-Za-z0-9]*_)*"};
21  std::regex const slash{"/"};
22  std::regex const artPrefix{R"(\S*art/.*)"};
23 
24  inline std::string
25  plugin_suffix(std::size_t const sz)
26  {
27  return sz != 1ull ? "s" : "";
28  }
29 
30  // Auxiliary class for creating status bar.
31  class StatusBar {
32  public:
33  StatusBar(std::string const& libType,
34  std::size_t const width,
35  std::size_t const denom,
36  bool const verbose)
37  : libType_{libType}, w_{width}, d_{denom}, v_{verbose}
38  {
39  if (v_)
40  std::cerr << '\n';
41  }
42 
43  ~StatusBar()
44  {
45  if (v_)
46  std::cerr << '\n';
47  }
48 
49  void
50  print_progress(std::size_t const num) const
51  {
52  if (!v_)
53  return;
54  std::size_t const per{100 * num / d_};
55  std::cerr << " Loaded " << std::setw(w_) << std::right << num << '/'
56  << d_ << " " << libType_ << plugin_suffix(d_) << " (" << per
57  << "%) " << std::flush;
58  std::cerr << '\r';
59  }
60 
61  private:
62  std::string const libType_;
63  std::size_t const w_;
64  std::size_t const d_;
65  bool const v_;
66  };
67 
68  std::string
69  pattern(std::string const& spec)
70  {
71  std::string const canonSpec = std::regex_replace(spec, slash, "_");
72  return regex_prefix + canonSpec + "_";
73  }
74 
75  inline std::string
76  getProvider(std::string const& fullSpec)
77  {
78  return std::regex_search(fullSpec, artPrefix) ? "art" : "user";
79  }
80 
81  inline std::vector<std::string>
82  getLibraries(LibraryManager const& lm)
83  {
84  std::vector<std::string> result;
85  lm.getLoadableLibraries(result);
86  return result;
87  }
88 
89  bool
90  scheduler_included(std::string const& spec, LibraryInfoCollection& result)
91  {
92  bool const print_only_message = (spec == "scheduler");
93  bool const print_available_services = (spec == dflt_spec_pattern());
94 
95  if (print_only_message || print_available_services) {
96  result.emplace(
97  "[ none ]",
98  std::make_pair("scheduler", ""),
99  "[ none ]",
101  fhicl::Name{"scheduler"}),
102  "art",
103  "");
104  return true;
105  }
106  return false;
107  }
108 
109  bool
110  messagefacility_included(std::string const& spec,
111  LibraryInfoCollection& result)
112  {
113  bool const print_only_message = (spec == "message");
114  bool const print_available_services = (spec == dflt_spec_pattern());
115 
116  if (print_only_message || print_available_services) {
117  result.emplace(
118  "[ none ]",
119  std::make_pair("message", ""),
120  "[ See "
121  "https://cdcvs.fnal.gov/redmine/projects/art/wiki/Messagefacility ]",
123  fhicl::Name{"message"}),
124  "art",
125  "");
126  return true;
127  }
128  return false;
129  }
130 
132  using Suffixes = art::Suffixes;
133 
134  std::string
135  fhicl_name(std::string const& suffix)
136  {
137  if (suffix == art::Suffixes::module()) {
138  return "<module_label>";
139  }
140  if (suffix == art::Suffixes::plugin()) {
141  return "<plugin_label>";
142  }
143  if (suffix == art::Suffixes::tool()) {
144  return "<tool_label>";
145  }
146  if (suffix == art::Suffixes::source()) {
147  return "source";
148  }
149  if (suffix == art::Suffixes::mfPlugin()) {
150  return "<destination_label>";
151  }
152  if (suffix == art::Suffixes::mfStatsPlugin()) {
153  return "<statistics_destination_label>";
154  }
155  return "<name>";
156  }
157 
159  collection_for_plugins(std::string const& suffix,
160  std::string const& spec,
161  bool const verbose)
162  {
163  LibraryInfoCollection result;
164  LibraryManager const lm{suffix, pattern(spec)};
165  std::size_t i{};
166  auto const& libs = getLibraries(lm);
167  auto const sz = libs.size();
168  auto const w = std::to_string(sz).size();
169  StatusBar const status_bar{lm.libType(), w, sz, verbose};
170  for (auto const& lib : libs) {
171  auto const& libspecs = lm.getSpecsByPath(lib);
172  std::string const& spec =
173  libspecs.second.empty() ? libspecs.first : libspecs.second;
174 
175  result.emplace(lib,
176  libspecs,
177  getFilePath(lm, spec),
178  getAllowedConfiguration(lm, spec, fhicl_name(suffix)),
179  getProvider(spec),
180  getType(lm, spec));
181 
182  status_bar.print_progress(++i);
183  }
184  return result;
185  }
186 
188  collection_for_services(std::string const& spec, bool const verbose)
189  {
190  // These services are not configurable by users.
191  std::set<std::string> const systemServicesToIgnore{"TriggerNamesService"};
192 
193  LibraryManager const lm{Suffixes::service(), pattern(spec)};
194  auto libs = getLibraries(lm);
195 
196  // Remove libraries that should be ignored
197  libs.erase(std::remove_if(libs.begin(),
198  libs.end(),
199  [&lm, &systemServicesToIgnore](auto const& path) {
200  return cet::search_all(
201  systemServicesToIgnore,
202  lm.getSpecsByPath(path).first);
203  }),
204  libs.cend());
205 
206  auto const sz =
207  libs.size() + static_cast<std::size_t>(spec == dflt_spec_pattern());
208  StatusBar const status_bar{
209  lm.libType(), std::to_string(sz).size(), sz, verbose};
210  LibraryInfoCollection result;
211  std::size_t i{};
212  for (auto const& lib : libs) {
213  auto const& libspecs = lm.getSpecsByPath(lib);
214  auto const& [shortspec, fullspec] = libspecs;
215 
216  result.emplace(lib,
217  libspecs,
218  getFilePath(lm, shortspec), // full specs may be empty
220  lm, shortspec, shortspec), // for user-defined servicxes
221  getProvider(fullspec),
222  getType(lm, fullspec));
223 
224  status_bar.print_progress(++i);
225  }
226  if (scheduler_included(spec, result)) {
227  status_bar.print_progress(++i);
228  }
229  if (messagefacility_included(spec, result)) {
230  status_bar.print_progress(++i);
231  }
232 
233  return result;
234  }
235 
236 } // namespace
237 
239 art::detail::get_LibraryInfoCollection(std::string const& suffix,
240  std::string const& pattern,
241  bool const verbose)
242 {
243  if (suffix == art::Suffixes::service()) {
244  return collection_for_services(pattern, verbose);
245  }
246  return collection_for_plugins(suffix, pattern, verbose);
247 }
std::string getType(cet::LibraryManager const &lm, std::string const &fullSpec)
static std::string const & mfStatsPlugin()
constexpr auto const & right(const_AssnsIter< L, R, D, Dir > const &a, const_AssnsIter< L, R, D, Dir > const &b)
Definition: AssnsIter.h:102
LibraryInfoCollection get_LibraryInfoCollection(std::string const &suffix, std::string const &pattern, bool verbose=false)
static std::string const & source()
std::unique_ptr< fhicl::ConfigurationTable > getAllowedConfiguration(cet::LibraryManager const &lm, std::string const &fullSpec, std::string const &name)
decltype(auto) constexpr to_string(T &&obj)
ADL-aware version of std::to_string.
std::string getFilePath(cet::LibraryManager const &lm, std::string const &fullspec)
static std::string const & plugin()
static std::string const & tool()
static std::string const & mfPlugin()
static std::string const & service()
static std::string const & module()
constexpr char const * dflt_spec_pattern()
Float_t w
Definition: plot.C:20
std::multiset< LibraryInfo > LibraryInfoCollection