LCOV - code coverage report
Current view: top level - conffwk/apps - config_dump.cxx (source / functions) Coverage Total Hit
Test: code.result Lines: 0.0 % 164 0
Test Date: 2026-10-11 15:05:20 Functions: 0.0 % 20 0

            Line data    Source code
       1              : //
       2              : // DUNE DAQ modification notice:
       3              : // This file has been modified from the original ATLAS config source for the DUNE DAQ project.
       4              : // Fork baseline commit: 67a24e731 (2022-10-27).
       5              : // Renamed since fork: yes (from bin/config_dump.cpp to apps/config_dump.cxx).
       6              : //
       7              : 
       8              : #include <stdlib.h>
       9              : 
      10              : #include <iostream>
      11              : #include <string>
      12              : 
      13              : #include <boost/program_options.hpp>
      14              : 
      15              : #include "conffwk/ConfigObject.hpp"
      16              : #include "conffwk/Configuration.hpp"
      17              : #include "conffwk/Schema.hpp"
      18              : 
      19              : using namespace dunedaq::conffwk;
      20              : 
      21            0 : ERS_DECLARE_ISSUE(config_dump, BadCommandLine, "bad command line: " << reason, ((const char*)reason))
      22              : 
      23            0 : ERS_DECLARE_ISSUE(config_dump, ConfigException, "caught dunedaq::conffwk::Exception exception", )
      24              : 
      25              : struct SortByName
      26              : {
      27            0 :   bool operator()(const ConfigObject* o1, const ConfigObject* o2) const { return o1->UID() < o2->UID(); }
      28              : };
      29              : 
      30              : static void
      31            0 : print_referenced_by(const ConfigObject& obj, const char* prefix)
      32              : {
      33            0 :   std::vector<ConfigObject> values;
      34            0 :   obj.referenced_by(values, "*", false, 0, 0);
      35            0 :   if (values.size() == 0) {
      36            0 :     std::cout << prefix << "is not referenced by others objects\n";
      37              :   } else {
      38            0 :     std::cout << prefix << "is referenced by " << values.size() << " object" << (values.size() == 1 ? "" : "s")
      39            0 :               << ":\n";
      40            0 :     for (const auto& iobj : values)
      41            0 :       std::cout << prefix << " * " << iobj << std::endl;
      42              :   }
      43            0 : }
      44              : 
      45              : static void
      46            0 : print_versions(const std::vector<dunedaq::conffwk::Version>& versions)
      47              : {
      48            0 :   const auto len = versions.size();
      49            0 :   unsigned int idx = 1;
      50            0 :   for (const auto& x : versions) {
      51            0 :     char buf[50];
      52            0 :     std::time_t t(x.get_timestamp());
      53            0 :     std::strftime(buf, 50, "%F %T %Z", std::localtime(&t));
      54            0 :     std::cout << " * version [" << idx++ << '/' << len
      55              :               << "]\n"
      56              :                  "    id: "
      57            0 :               << x.get_id()
      58              :               << "\n"
      59              :                  "    user: "
      60            0 :               << x.get_user()
      61              :               << "\n"
      62              :                  "    date: "
      63              :               << buf
      64              :               << "\n"
      65              :                  "    comment: "
      66            0 :               << x.get_comment()
      67              :               << "\n"
      68            0 :                  "    files:\n";
      69              : 
      70            0 :     for (const auto& f : x.get_files())
      71            0 :       std::cout << "     - \"" << f << "\"\n";
      72              :   }
      73            0 : }
      74              : 
      75              : int
      76            0 : main(int argc, char* argv[])
      77              : {
      78            0 :   const std::string any("*");
      79            0 :   std::string db_name, class_name, object_id, since, until;
      80              : 
      81            0 :   bool changes = false;
      82              : 
      83            0 :   bool skip_irrelevant = true;
      84            0 :   dunedaq::conffwk::Version::QueryType query_type = dunedaq::conffwk::Version::query_by_tag;
      85              : 
      86            0 :   bool direct_info = false;
      87            0 :   bool objects_details = false;
      88            0 :   bool contained_in = false;
      89            0 :   bool referenced_by = false;
      90              : 
      91            0 :   boost::program_options::options_description desc("Dumps class and objects descriptions using abstract conffwk API.\n"
      92              :                                                    "Without -c or -o options, the utility lists all classes.\n"
      93              :                                                    "\n"
      94            0 :                                                    "Options/Arguments");
      95              : 
      96            0 :   try {
      97            0 :     std::vector<std::string> vesrions_str;
      98            0 :     std::string class_name2;
      99              : 
     100            0 :     desc.add_options()("database,d",
     101            0 :                        boost::program_options::value<std::string>(&db_name)->required(),
     102            0 :                        "database specification in format plugin-name:parameters")(
     103            0 :       "changes,a", "print details of new repository versions or modified files")(
     104              :       "versions,v",
     105            0 :       boost::program_options::value<std::vector<std::string>>(&vesrions_str)->multitoken()->zero_tokens(),
     106            0 :       "print details of versions from archive providing 4 parameters \"all|skip\" \"date|id|tag\" \"since\" \"until\"")(
     107              :       "class-direct-info,c",
     108            0 :       boost::program_options::value<std::string>(&class_name)->default_value("")->implicit_value(any),
     109            0 :       "print direct properties of all classes, or given class if name is provided")(
     110              :       "class-all-info,C",
     111            0 :       boost::program_options::value<std::string>(&class_name2)->default_value("")->implicit_value(any),
     112            0 :       "similar to -c, but prints all properties of class (all attributes, all superclasses, etc.)")(
     113            0 :       "list-objects,o", "list objects of class")("print-referenced-by,r",
     114            0 :                                                  "print objects referencing given object (only with -o option)")(
     115              :       "dump-objects,O",
     116            0 :       boost::program_options::value<std::string>(&object_id)->default_value("")->implicit_value(any),
     117            0 :       "dump all objects of class or details of given object, if id is provided (-c is required)")(
     118            0 :       "show-contained-in,n", "when dump an object, print out the database file it belongs to")("help,h",
     119              :                                                                                                "print help message");
     120              : 
     121            0 :     boost::program_options::variables_map vm;
     122            0 :     boost::program_options::store(boost::program_options::parse_command_line(argc, argv, desc), vm);
     123              : 
     124            0 :     if (vm.count("help")) {
     125            0 :       std::cout << desc << std::endl;
     126            0 :       return EXIT_SUCCESS;
     127              :     }
     128              : 
     129            0 :     boost::program_options::notify(vm);
     130              : 
     131            0 :     if (!class_name.empty())
     132            0 :       direct_info = true;
     133              : 
     134            0 :     if (!class_name2.empty()) {
     135            0 :       if (!class_name.empty())
     136            0 :         throw std::runtime_error("cannot use -c and -C options simultaneously");
     137              :       else
     138            0 :         class_name = std::move(class_name2);
     139              :     }
     140              : 
     141            0 :     if (vm.count("changes"))
     142            0 :       changes = true;
     143              : 
     144            0 :     if (!vesrions_str.empty()) {
     145            0 :       if (vesrions_str.size() != 4) {
     146            0 :         throw std::runtime_error("-v option must have 4 parameters, see help");
     147              :       } else {
     148            0 :         if (vesrions_str[0] == "all")
     149              :           skip_irrelevant = false;
     150            0 :         else if (vesrions_str[0] != "skip")
     151            0 :           throw std::runtime_error("first parameter of -v has to be \"all\" or \"skip\"");
     152              : 
     153            0 :         if (vesrions_str[1] == "date")
     154              :           query_type = dunedaq::conffwk::Version::query_by_date;
     155            0 :         else if (vesrions_str[1] == "id")
     156              :           query_type = dunedaq::conffwk::Version::query_by_id;
     157            0 :         else if (vesrions_str[1] != "tag")
     158            0 :           throw std::runtime_error("second versions parameter must be \"date\", \"id\" or \"tag\"");
     159              : 
     160            0 :         since = vesrions_str[2];
     161            0 :         until = vesrions_str[3];
     162              :       }
     163              :     }
     164              : 
     165            0 :     if (!object_id.empty())
     166            0 :       objects_details = true;
     167              : 
     168            0 :     if (vm.count("list-objects")) {
     169            0 :       objects_details = false;
     170            0 :       object_id = any;
     171              :     }
     172              : 
     173            0 :     if (vm.count("print-referenced-by"))
     174            0 :       referenced_by = true;
     175              : 
     176            0 :     if (vm.count("show-contained-in"))
     177            0 :       contained_in = true;
     178              : 
     179            0 :     if (class_name.empty() && !object_id.empty() && object_id != any)
     180            0 :       throw std::runtime_error("object id is set, but no class name given (use -c option)");
     181            0 :   } catch (std::exception& ex) {
     182            0 :     ers::fatal(config_dump::BadCommandLine(ERS_HERE, ex.what()));
     183            0 :     return EXIT_FAILURE;
     184            0 :   }
     185              : 
     186            0 :   try {
     187            0 :     Configuration conf(db_name);
     188              : 
     189              :     // get versions if any
     190            0 :     if (changes) {
     191            0 :       std::cout << "Changes:\n";
     192            0 :       print_versions(conf.get_changes());
     193            0 :       return EXIT_SUCCESS;
     194              :     }
     195              : 
     196            0 :     if (!since.empty()) {
     197            0 :       std::cout << "Versions:\n";
     198            0 :       print_versions(conf.get_versions(since, until, query_type, skip_irrelevant));
     199            0 :       return EXIT_SUCCESS;
     200              :     }
     201              : 
     202            0 :     std::set<std::string> classes;
     203              : 
     204            0 :     if (!class_name.empty() && class_name != any)
     205            0 :       classes.insert(class_name);
     206              :     else
     207            0 :       for (const auto& i : conf.superclasses())
     208            0 :         classes.insert(*i.first);
     209              : 
     210              :     // if there are no options, just list classes
     211            0 :     if (class_name.empty() && object_id.empty()) {
     212            0 :       std::cout << "The database schema has " << classes.size() << " class(es):\n";
     213            0 :       for (const auto& i : classes)
     214            0 :         std::cout << " - \'" << i << "\'\n";
     215            0 :       return EXIT_SUCCESS;
     216              :     }
     217              : 
     218              :     // only print details of classes
     219            0 :     if (!class_name.empty() && object_id.empty()) {
     220            0 :       if (class_name == any)
     221            0 :         std::cout << "The database schema has " << classes.size() << " class(es):\n";
     222              : 
     223            0 :       for (const auto& i : classes)
     224            0 :         conf.get_class_info(i, direct_info).print(std::cout, "  ");
     225              : 
     226            0 :       return EXIT_SUCCESS;
     227              :     }
     228              : 
     229            0 :     const char* prefix = "";
     230            0 :     const char* prefix2 = "  ";
     231            0 :     const char* prefix3 = "    ";
     232              : 
     233              :     // list or print all objects of class(es)
     234            0 :     if (object_id == any) {
     235            0 :       if (class_name.empty() || class_name == any) {
     236            0 :         std::cout << "The database schema has " << classes.size() << " class(es):\n";
     237              :         prefix = "  ";
     238              :         prefix2 = "    ";
     239              :         prefix3 = "      ";
     240              :       }
     241              : 
     242            0 :       for (std::set<std::string>::const_iterator i = classes.begin(); i != classes.end(); ++i) {
     243            0 :         std::vector<ConfigObject> objects;
     244            0 :         conf.get(*i, objects);
     245            0 :         if (objects.empty()) {
     246            0 :           std::cout << prefix << "The class \'" << *i << "\' has no objects\n";
     247              :         } else {
     248            0 :           std::cout << prefix << "The class \'" << *i << "\' has " << objects.size()
     249            0 :                     << " object(s) including sub-classes:\n";
     250              : 
     251              :           // sort by ID for consistent output
     252            0 :           std::set<const ConfigObject*, SortByName> sorted_by_id;
     253              : 
     254            0 :           for (const auto& j : objects)
     255            0 :             sorted_by_id.insert(&j);
     256              : 
     257            0 :           for (const auto& j : sorted_by_id)
     258            0 :             if (j->class_name() == *i) {
     259            0 :               if (objects_details)
     260            0 :                 j->print_ref(std::cout, conf, prefix2, contained_in);
     261              :               else
     262            0 :                 std::cout << prefix << " - \'" << j->UID() << "\'\n";
     263              : 
     264            0 :               if (referenced_by)
     265            0 :                 print_referenced_by(*j, prefix3);
     266              :             } else {
     267            0 :               std::cout << prefix << " - \'" << j->UID() << "\' (database class name = \'" << j->class_name()
     268            0 :                         << "\')\n";
     269              :             }
     270            0 :         }
     271            0 :       }
     272              :     } else {
     273            0 :       ConfigObject obj;
     274            0 :       conf.get(class_name, object_id, obj);
     275            0 :       obj.print_ref(std::cout, conf, "", contained_in);
     276            0 :       if (referenced_by)
     277            0 :         print_referenced_by(obj, prefix2);
     278            0 :     }
     279            0 :   } catch (dunedaq::conffwk::Exception& ex) {
     280            0 :     ers::fatal(config_dump::ConfigException(ERS_HERE, ex));
     281            0 :     return EXIT_FAILURE;
     282            0 :   }
     283              : 
     284            0 :   return EXIT_SUCCESS;
     285            0 : }
        

Generated by: LCOV version 2.0-1