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

Generated by: LCOV version 2.0-1