Line data Source code
1 : #ifndef ARTDAQ_ARTDAQ_ARTMODULES_BUILDINFO_MODULE_HH_
2 : #define ARTDAQ_ARTDAQ_ARTMODULES_BUILDINFO_MODULE_HH_
3 :
4 : #include "TRACE/tracemf.h"
5 : #define TRACE_NAME "BuildInfo"
6 :
7 : #include "art/Framework/Core/EDProducer.h"
8 : #include "art/Framework/Core/ModuleMacros.h"
9 : #include "art/Framework/Principal/Run.h"
10 : #include "artdaq-core/Data/PackageBuildInfo.hh"
11 : #include "fhiclcpp/ParameterSet.h"
12 :
13 : #include <iostream>
14 : #include <memory>
15 : #include <string>
16 : #include <utility>
17 : #include <vector>
18 :
19 : namespace artdaq {
20 : /**
21 : * \brief BuildInfo is an art::EDProducer which saves information about package builds to the data file
22 : * \tparam instanceName Tag which the BuildInfo objects will be saved under
23 : * \tparam Pkgs List of package BuildInfo types
24 : */
25 : template<std::string* instanceName, typename... Pkgs>
26 : class BuildInfo : public art::EDProducer
27 : {
28 : public:
29 : /**
30 : * \brief BuildInfo module Constructor
31 : * \param p ParameterSet used to configure BuildInfo module
32 : *
33 : * BuildInfo_module expects the following Parameters:
34 : * "instance_name": Name which the BuildInfo information will be saved under
35 : */
36 : explicit BuildInfo(fhicl::ParameterSet const& p);
37 :
38 : /**
39 : * \brief Default Destructor
40 : */
41 0 : virtual ~BuildInfo() = default;
42 :
43 : /**
44 : * \brief Perform actions at the beginning of the Run
45 : * \param r art::Run object
46 : *
47 : * The BuildInfo information is stored in the Run-level provenance, so this
48 : * method performs most of the "work" for this module.
49 : */
50 : void beginRun(art::Run& r) override;
51 :
52 : /**
53 : * \brief Perform actions for each event
54 : * \param e art::Event object
55 : *
56 : * This function is a required override for EDProducer, and is a No-Op in BuildInfo_module.
57 : */
58 : void produce(art::Event& e) final override;
59 :
60 : private:
61 : BuildInfo(BuildInfo const&) = delete;
62 : BuildInfo(BuildInfo&&) = delete;
63 : BuildInfo& operator=(BuildInfo const&) = delete;
64 : BuildInfo& operator=(BuildInfo&&) = delete;
65 :
66 : std::unique_ptr<std::vector<PackageBuildInfo>> packages_;
67 : std::string instanceName_;
68 :
69 : template<typename... Args>
70 : struct fill_packages;
71 :
72 : template<typename Arg>
73 : struct fill_packages<Arg>
74 : {
75 0 : static void doit(std::vector<PackageBuildInfo>& packages)
76 : {
77 0 : packages.emplace_back(Arg::getPackageBuildInfo());
78 0 : }
79 : };
80 :
81 : template<typename Arg, typename... Args>
82 : struct fill_packages<Arg, Args...>
83 : {
84 0 : static void doit(std::vector<PackageBuildInfo>& packages)
85 : {
86 0 : packages.emplace_back(Arg::getPackageBuildInfo());
87 0 : fill_packages<Args...>::doit(packages);
88 0 : }
89 : };
90 : };
91 :
92 : template<std::string* instanceName, typename... Pkgs>
93 0 : BuildInfo<instanceName, Pkgs...>::BuildInfo(fhicl::ParameterSet const& ps)
94 : : EDProducer(ps)
95 0 : , packages_(new std::vector<PackageBuildInfo>())
96 0 : , instanceName_(ps.get<std::string>("instance_name", *instanceName))
97 : {
98 0 : fill_packages<Pkgs...>::doit(*packages_);
99 :
100 0 : produces<std::vector<PackageBuildInfo>, art::InRun>(instanceName_);
101 0 : }
102 :
103 : template<std::string* instanceName, typename... Pkgs>
104 0 : void BuildInfo<instanceName, Pkgs...>::beginRun(art::Run& r)
105 : {
106 : // JCF, 9/22/14
107 :
108 : // Previously, the vector pointed to by the member variable
109 : // packages_ itself got stored in output on the call to "r.put()"
110 : // below; what would then happen is that at the start of a new run
111 : // or subrun, when r.put() got called again an exception would be
112 : // thrown because packages_ would now be null thanks to the
113 : // previous call to std::move. To make sure this doesn't happen, I
114 : // now stash a copy of the vector pointed to by packages_, not the
115 : // original member vector
116 :
117 0 : auto packages_deep_copy_ptr = std::make_unique<std::vector<PackageBuildInfo>>(*packages_);
118 :
119 0 : TLOG(TLVL_INFO, "BuildInfo") << "Placing BuildInfo with instance name \"" << instanceName_ << "\"";
120 0 : for (auto& pbi : *packages_)
121 : {
122 0 : TLOG(TLVL_DEBUG) << "Package " << pbi.getPackageName() << ": version " << pbi.getPackageVersion() << " built at " << pbi.getBuildTimestamp();
123 : }
124 0 : r.put(std::move(packages_deep_copy_ptr), instanceName_, art::fullRun());
125 0 : }
126 :
127 : template<std::string* instanceName, typename... Pkgs>
128 0 : void BuildInfo<instanceName, Pkgs...>::produce(art::Event&)
129 : {
130 : // nothing to be done for individual events
131 0 : }
132 : } // namespace artdaq
133 :
134 : #endif // ARTDAQ_ARTDAQ_ARTMODULES_BUILDINFO_MODULE_HH_
|