LArSoft  v07_13_02
Liquid Argon Software toolkit - http://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 
23  inline std::string
24  plugin_suffix(std::size_t const sz)
25  {
26  return sz != 1ull ? "s" : "";
27  }
28 
29  // Auxiliary class for creating status bar.
30  class StatusBar {
31  public:
32  StatusBar(std::string const& libType,
33  std::size_t const width,
34  std::size_t const denom,
35  bool const verbose)
36  : libType_{libType}, w_{width}, d_{denom}, v_{verbose}
37  {
38  if (v_)
39  std::cerr << '\n';
40  }
41 
42  ~StatusBar()
43  {
44  if (v_)
45  std::cerr << '\n';
46  }
47 
48  void
49  print_progress(std::size_t const num) const
50  {
51  if (!v_)
52  return;
53  std::size_t const per{100 * num / d_};
54  std::cerr << " Loaded " << std::setw(w_) << std::right << num << '/'
55  << d_ << " " << libType_ << plugin_suffix(d_) << " (" << per
56  << "%) " << std::flush;
57  std::cerr << '\r';
58  }
59 
60  private:
61  std::string const libType_;
62  std::size_t const w_;
63  std::size_t const d_;
64  bool const v_;
65  };
66 
67  std::string
68  pattern(std::string const& spec)
69  {
70  std::string const canonSpec = std::regex_replace(spec, slash, "_");
71  return regex_prefix + canonSpec + "_";
72  }
73 
74  inline std::string
75  getProvider(std::string const& fullSpec)
76  {
77  return std::regex_search(fullSpec, std::regex{R"(\S*art/.*)"}) ? "art" :
78  "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  messagefacility_included(std::string const& spec,
91  LibraryInfoCollection& result)
92  {
93  bool const print_only_message = (spec == "message");
94  bool const print_available_services = (spec == dflt_spec_pattern());
95 
96  if (print_only_message || print_available_services) {
97  result.emplace(
98  "[ none ]",
99  std::make_pair("message", ""),
100  "[ See "
101  "https://cdcvs.fnal.gov/redmine/projects/art/wiki/Messagefacility ]",
103  fhicl::Name{"message"}),
104  "art",
105  "");
106  return true;
107  }
108  return false;
109  }
110 
112  using Suffixes = art::Suffixes;
113 
114  std::string
115  fhicl_name(suffix_type const st)
116  {
117  switch (st) {
118  case suffix_type::module:
119  return "<module_label>";
120  case suffix_type::plugin:
121  return "<plugin_label>";
122  case suffix_type::tool:
123  return "<tool_label>";
124  case suffix_type::source:
125  return "source";
127  return "<destination_label>";
129  return "<statistics_destination_label>";
130  default:
132  << "The '" << Suffixes::get(st)
133  << "' suffix is not supported for function: " << __func__ << '\n';
134  }
135  }
136 
137  template <suffix_type st>
139  getCollection(std::string const& spec, bool const verbose)
140  {
141  LibraryInfoCollection result;
142  LibraryManager const lm{Suffixes::get(st), pattern(spec)};
143  std::size_t i{};
144  auto const& libs = getLibraries(lm);
145  auto const sz = libs.size();
146  auto const w = std::to_string(sz).size();
147  StatusBar const status_bar{lm.libType(), w, sz, verbose};
148  for (auto const& lib : libs) {
149  auto const& libspecs = lm.getSpecsByPath(lib);
150  std::string const& spec =
151  libspecs.second.empty() ? libspecs.first : libspecs.second;
152 
153  result.emplace(lib,
154  libspecs,
155  getFilePath<st>(lm, spec),
156  getAllowedConfiguration<st>(lm, spec, fhicl_name(st)),
157  getProvider(spec),
158  getType<st>(lm, spec));
159 
160  status_bar.print_progress(++i);
161  }
162  return result;
163  }
164 
165  template <>
167  getCollection<suffix_type::service>(std::string const& spec,
168  bool const verbose)
169  {
170  // These services are not configurable by users.
171  std::set<std::string> const systemServicesToIgnore{
172  "CurrentModule", "ScheduleContext", "TriggerNamesService"};
173 
174  std::string const& pSpec = ServiceNames::libname(spec);
175 
176  LibraryManager const lm{Suffixes::get(suffix_type::service),
177  pattern(pSpec)};
178  auto libs = getLibraries(lm);
179 
180  // Remove libraries that should be ignored
181  libs.erase(std::remove_if(libs.begin(),
182  libs.end(),
183  [&lm, &systemServicesToIgnore](auto const& path) {
184  return cet::search_all(
185  systemServicesToIgnore,
186  lm.getSpecsByPath(path).first);
187  }),
188  libs.cend());
189 
190  auto const sz =
191  libs.size() + static_cast<std::size_t>(spec == dflt_spec_pattern());
192  StatusBar const status_bar{
193  lm.libType(), std::to_string(sz).size(), sz, verbose};
194  LibraryInfoCollection result;
195  std::size_t i{};
196  for (auto const& lib : libs) {
197  auto const& libspecs = lm.getSpecsByPath(lib);
198  std::string const& spec = libspecs.first;
199  std::string const& fullspec = libspecs.second;
200  auto const& fclname = ServiceNames::fclname(spec);
201 
202  result.emplace(
203  lib,
204  std::make_pair(fclname, fullspec),
205  getFilePath<suffix_type::service>(lm, spec), // full specs may be empty
206  getAllowedConfiguration<suffix_type::service>(
207  lm, spec, fclname), // for user-defined servicxes
208  getProvider(fullspec),
209  getType<suffix_type::service>(lm, libspecs.second));
210 
211  status_bar.print_progress(++i);
212  }
213  if (messagefacility_included(spec, result)) {
214  status_bar.print_progress(++i);
215  }
216 
217  return result;
218  }
219 
220 } // namespace
221 
224  std::string const& pattern,
225  bool const verbose)
226 {
227  switch (st) {
228  case suffix_type::module:
229  return getCollection<suffix_type::module>(pattern, verbose);
231  return getCollection<suffix_type::service>(pattern, verbose);
232  case suffix_type::source:
233  return getCollection<suffix_type::source>(pattern, verbose);
234  case suffix_type::plugin:
235  return getCollection<suffix_type::plugin>(pattern, verbose);
236  case suffix_type::tool:
237  return getCollection<suffix_type::tool>(pattern, verbose);
239  return getCollection<suffix_type::mfPlugin>(pattern, verbose);
241  return getCollection<suffix_type::mfStatsPlugin>(pattern, verbose);
242  // No default - allow compiler to warn if missing suffix_type.
243  }
244  return {};
245 }
constexpr auto const & right(const_AssnsIter< L, R, D, Dir > const &a, const_AssnsIter< L, R, D, Dir > const &b)
Definition: AssnsIter.h:112
auto getCollection(Event const &event, OptionalArgs &&...optionalArgs)
Creates a proxy to a data product collection.
Definition: getCollection.h:82
constexpr const char * dflt_spec_pattern()
LibraryInfoCollection get_LibraryInfoCollection(suffix_type suffix, std::string const &pattern, bool const verbose=false)
static std::string const & libname(std::string const &fclname)
Definition: ServiceNames.h:35
static std::string const & fclname(std::string const &libname)
Definition: ServiceNames.h:42
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
std::string to_string(Flag_t< Storage > const flag)
Convert a flag into a stream (shows its index).
Definition: BitMask.h:187
static std::string const & get(suffix_type st)
Float_t w
Definition: plot.C:23
std::multiset< LibraryInfo > LibraryInfoCollection