configurationengine/source/scripts/conesub_report.py
changeset 3 e7e0ae78773e
parent 0 2e8eeb919028
equal deleted inserted replaced
2:87cfa131b535 3:e7e0ae78773e
    14 # Description: 
    14 # Description: 
    15 #
    15 #
    16 
    16 
    17 import os
    17 import os
    18 import logging
    18 import logging
    19 import pickle
       
    20 from optparse import OptionParser, OptionGroup
    19 from optparse import OptionParser, OptionGroup
    21 import cone_common
    20 import cone_common
    22 import generation_report
    21 from cone.report import generation_report
    23 from cone.public import api, plugin, utils, exceptions
       
    24 
    22 
    25 
    23 
    26 VERSION     = '1.0'
    24 VERSION     = '1.0'
       
    25 ROOT_PATH = os.path.abspath(os.path.dirname(__file__))
    27 
    26 
    28 logger    = logging.getLogger('cone')
    27 logger    = logging.getLogger('cone')
    29 
    28 
    30 def main():
    29 def main():
       
    30     """ Create report of existing report data. """
    31     parser = OptionParser(version="%%prog %s" % VERSION)
    31     parser = OptionParser(version="%%prog %s" % VERSION)
    32     
    32     
    33     parser.add_options(cone_common.COMMON_OPTIONS)
    33     parser.add_options(cone_common.COMMON_OPTIONS)
    34     
    34     
    35     group = OptionGroup(parser, 'Report options',
    35     group = OptionGroup(parser, 'Report options',
    60                    help="Specifies the report file to create."\
    60                    help="Specifies the report file to create."\
    61                         "Example -r report.html.",
    61                         "Example -r report.html.",
    62                    metavar="FILE",\
    62                    metavar="FILE",\
    63                    default="report.html")
    63                    default="report.html")
    64     
    64     
       
    65     group.add_option("--report-option",\
       
    66                    action="append",
       
    67                    help="Specifies the report verbose options, that defines "\
       
    68                         "what data is included to the report. The option can be "\
       
    69                         "used multiple times."\
       
    70                         "choises=[default|all]"\
       
    71                         "Example --report-option=all",
       
    72                    metavar="OPTION",\
       
    73                    default=[])
       
    74 
    65     group.add_option("-t", "--template",\
    75     group.add_option("-t", "--template",\
    66                    dest="template",\
    76                    dest="template",\
    67                    action="store",
    77                    action="store",
    68                    type="string",
    78                    type="string",
    69                    help="Template used in report generation."\
    79                    help="Template used in report generation."\
    90     
   100     
    91     if len(files) == 0:
   101     if len(files) == 0:
    92         parser.error("At least one input data file must be specified.")
   102         parser.error("At least one input data file must be specified.")
    93     
   103     
    94     
   104     
    95     class DataEntry(object):
       
    96         def __init__(self, label, data):
       
    97             self.label = label
       
    98             self.data = data
       
    99     
   105     
   100     # Load all data files
   106     # Load all data files
   101     data_entries = []
   107     data_reports = []
   102     for data_file in files:
   108     for data_file in files:
   103         print "Loading data file '%s'" % data_file
   109         print "Loading data file '%s'" % data_file
   104         label = get_generation_run_label(data_file)
       
   105         data = generation_report.load_report_data(data_file)
   110         data = generation_report.load_report_data(data_file)
   106         data_entries.append(DataEntry(label, data))
   111         data_reports.append(data)
   107     
   112     
   108     # Sort by time stamp
   113     # Sort by time stamp
   109     data_entries.sort(key=lambda entry: entry.data.generation_timestamp)
   114     data_reports.sort(key=lambda entry: entry.generation_timestamp)
   110     
   115     
   111     # Use the first data object as the main report data
   116     # Generate the report
   112     main_entry = data_entries[0]
   117     print "Generating report to '%s'" % options.report
       
   118     generation_report.generate_report(data_reports, options.report, options.template, [ROOT_PATH], options.report_option)
   113     
   119     
   114     # Merge the rest of the data objects into the main data
   120     print "Done!'"
   115     if len(data_entries) > 1:
       
   116         # Update the generation_runs attribute of all implementations
       
   117         # in the main data
       
   118         for line in main_entry.data.lines:
       
   119             for impl in line.impls:
       
   120                 impl.generation_runs = [main_entry.label]
       
   121          
       
   122         # Load other report data files and merge them to the main data object
       
   123         for i in xrange(len(data_entries) - 1):
       
   124             entry = data_entries[i + 1]
       
   125             print "Merging data for '%s'" % entry.label
       
   126             merge_report_data(main_entry.data, entry.data, entry.label)
       
   127  
       
   128     # Generate the report
       
   129     main_entry.data.report_filename = options.report
       
   130     generation_report.generate_report(main_entry.data, options.report, options.template)
       
   131     
       
   132     print "Generated report to '%s'" % options.report
       
   133 
   121 
   134 def get_input_data_files(directory):
   122 def get_input_data_files(directory):
   135     files = []
   123     files = []
   136     for name in os.listdir(directory):
   124     for name in os.listdir(directory):
   137         path = os.path.join(directory, name)
   125         path = os.path.join(directory, name)
   138         if os.path.isfile(path):
   126         if os.path.isfile(path):
   139             files.append(path)
   127             files.append(path)
   140     return files
   128     return files
   141     
       
   142 
   129 
   143 def get_generation_run_label(datafile_path):
       
   144     filename = os.path.split(datafile_path)[1]
       
   145     filename_noext = os.path.splitext(filename)[0]
       
   146     return filename_noext
       
   147 
       
   148 def get_feature(rep_data, ref):
       
   149     for feat in rep_data.lines:
       
   150         if feat.ref == ref:
       
   151             return feat
       
   152     raise RuntimeError("Feature '%s' not found in refs with impl" % ref)
       
   153 
       
   154 def get_impl(rep_data, ref, impl_name):
       
   155     feat = get_feature(rep_data, ref)
       
   156     for impl in feat.impls:
       
   157         if impl.name == impl_name:
       
   158             return impl
       
   159     raise RuntimeError("Impl '%s' not found for feature '%s'" % (impl_name, ref))
       
   160 
       
   161 def merge_report_data(data, data_to_merge, generation_run_label):
       
   162     impls_by_ref = {}
       
   163     for feat in data.lines:
       
   164         impls_dict = {}
       
   165         impls_by_ref[feat.ref] = impls_dict
       
   166         for impl in feat.impls:
       
   167             impls_dict[impl.name] = impl
       
   168     
       
   169     for feat in data_to_merge.lines:
       
   170         if feat.ref in impls_by_ref:
       
   171             # Feature has implementations in both report data objects
       
   172             # -------------------------------------------------------
       
   173             impls_dict = impls_by_ref[feat.ref]
       
   174             
       
   175             for impl in feat.impls:
       
   176                 if impl.name in impls_dict:
       
   177                     # Same implementation in both: add the generation run to merge to the impl
       
   178                     impl = get_impl(data, feat.ref, impl.name)
       
   179                     impl.generation_runs.append(generation_run_label)
       
   180                 else:
       
   181                     # Implementation only in the data to merge: add to the main data
       
   182                     impl = get_impl(data_to_merge, feat.ref, impl.name)
       
   183                     impl.generation_runs = [generation_run_label]
       
   184                     feat = get_feature(data, feat.ref)
       
   185                     feat.impls.append(impl)
       
   186                     feat.nbr_impls += 1
       
   187         else:
       
   188             # Feature has implementations only in the data to merge
       
   189             # -----------------------------------------------------
       
   190             
       
   191             # Add the feature and impls to the main data
       
   192             feat = get_feature(data_to_merge, feat.ref)
       
   193             for impl in feat.impls:
       
   194                 impl.generation_runs = [generation_run_label]
       
   195             data.lines.append(feat)
       
   196             data.nbr_of_refs += 1
       
   197             
       
   198             # Remove from features with no impl in the main data
       
   199             for i, noimpl_feat in enumerate(data.ref_noimpl):
       
   200                 if feat.ref == noimpl_feat.ref:
       
   201                     del data.ref_noimpl[i]
       
   202                     data.nbr_of_refs_noimpl -= 1
       
   203                     break
       
   204 
   130 
   205 if __name__ == "__main__":
   131 if __name__ == "__main__":
   206     main()
   132     main()