diff -r 87cfa131b535 -r e7e0ae78773e configurationengine/source/scripts/generation_report.py --- a/configurationengine/source/scripts/generation_report.py Fri Mar 12 08:30:17 2010 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,315 +0,0 @@ -# -# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). -# All rights reserved. -# This component and the accompanying materials are made available -# under the terms of "Eclipse Public License v1.0" -# which accompanies this distribution, and is available -# at the URL "http://www.eclipse.org/legal/epl-v10.html". -# -# Initial Contributors: -# Nokia Corporation - initial contribution. -# -# Contributors: -# -# Description: -# - -import os, logging, pickle -import time -from time import gmtime, strftime -from jinja2 import Environment, PackageLoader, FileSystemLoader, Template -from cone.public import api, exceptions, utils, plugin -from cone.confml import model -import report_util - -ROOT_PATH = os.path.dirname(os.path.abspath(__file__)) - -def save_report_data(rep_data, file_path): - """ - Save report data into an intermediary report data file. - """ - dir = os.path.dirname(file_path) - if dir != '' and not os.path.exists(dir): - os.makedirs(dir) - - pickle_data = pickle.dumps(rep_data) - f = open(file_path, 'wb') - try: f.write(pickle_data) - finally: f.close() - -def load_report_data(file_path): - """ - Load report data from an intermediary report data file. - """ - f = open(file_path, "rb") - try: data = f.read() - finally: f.close() - - return pickle.loads(data) - -def _get_parent_sequence_or_self(feature): - current = feature._parent - while current is not None: - if isinstance(current, api.FeatureSequence): - return current - current = current._parent - return feature - -def collect_report_data(config, options, all_refs, impl_set, rule_exec_results): - """ - Collect data for report generation. - """ - impls = impl_set.get_all_implementations() - impls.sort(key=lambda impl: (impl.ref, impl.index)) - rep_data = ReportData() - - # Sort the rule results for unit testing purposes - rep_data.rule_exec_results = sorted(rule_exec_results, key=lambda e: (e.source, e.index)) - - # Collect a dictionary that maps refs shown in the report to a list of - # actual sub-refs used in the generation. - # This is done because for sequence settings only an entry for the main - # sequence setting is shown, but the actual refs used in generation point - # to the individual sub-settings (and possibly even under them). - # An example entry in the dictionary could be - # 'MyFeature.MySequence' : ['MyFeature.MySequence.Name', - # 'MyFeature.MySequence.File.localPath', - # 'MyFeature.MySequence.File.targetPath'] - dview = config.get_default_view() - refs_dict = {} - for ref in all_refs: - try: - feature = dview.get_feature(ref) - except exceptions.NotFound: - logging.getLogger('cone.generation_report').warning("Feature for data ref not found: %s" % ref) - continue - - feature = _get_parent_sequence_or_self(feature._obj) - ref_to_report = feature.fqr - - if ref_to_report not in refs_dict: - refs_dict[ref_to_report] = [] - refs_dict[ref_to_report].append(ref) - -# msg = [] -# for ref, sub_refs in refs_dict.iteritems(): -# msg.append("Ref: %s\nSub-refs:\n%s" % (ref, '\n'.join(sub_refs))) -# logging.getLogger('cone').debug('\n--------------------------------------\n'.join(msg)) - - # Go through the refs and create report data entries - for ref in sorted(refs_dict.iterkeys()): - sub_refs = refs_dict[ref] - - #print "Ref: %s" % ref - try: - feat = dview.get_feature(ref) - - # Skip imaker-internal settings - if isinstance(feat._obj, model.ConfmlSetting): - try: - prop = feat.get_property('cone-report-ignore') - if prop.value.lower() in ('1', 'true'): - continue - except exceptions.NotFound: - pass - - #print "Still %s" % ref - - found_output = False - line = RefLine(ref, feat.get_type()) - - if plugin.is_temp_feature(feat): - line.is_temp_feature = True - - if feat.get_type() == 'sequence': - for f in feat.list_all_features(): - line.add_sequence(feat.get_feature(f).get_name(), feat.get_feature(f).get_value()) - else: - if isinstance(feat.get_datas(), list): - for d in feat.get_datas(): - line.add_data(d.find_parent(type=api.Configuration).get_full_path(), d.get_value()) - else: - line.add_data(feat.get_data().find_parent(type=api.Configuration).get_full_path(), feat.get_value()) - - - # Impl and output files - has_impl = False - for impl in impls: - # Check for implementations using the actual sub-refs - if impl.has_ref(sub_refs): - has_impl = True - line.add_impl(impl.ref, impl.IMPL_TYPE_ID, impl.list_output_files()) - if has_impl: rep_data.add_line(line) - else: rep_data.add_ref_noimpl(line) - - - # For localPath and targetPath, the name should be the one from its parent file/folder setting - if isinstance(feat._obj, (model.ConfmlLocalPath, model.ConfmlTargetPath)): - name = feat._obj._parent.name - else: - name = feat.name - - line.set_feat_name(name) - line.set_config_path( feat._obj.find_parent(type=api.Configuration).get_full_path()) - - except Exception, e: - utils.log_exception(logging.getLogger('cone'), 'Failed to collect data for report. Exception: %s' % e) - - # create one list of not generated files - for myline in rep_data.lines: - for myimpl in myline.impls: - for output_file in myimpl.outputfiles: - if not output_file.exists and output_file not in rep_data.missing_output_files: - rep_data.missing_output_files.append(output_file) - - rep_data.set_options(options) - rep_data.set_output_dir(options.output) - rep_data.update_nbr_of_refs() - rep_data.update_nbr_of_refs_noimpl() - - return rep_data - -def generate_report(rep_data, report_file_path, template_file_path=None): - """ - Generate a generation report based on the given report data. - @param rep_data: The report data. - @param report_file_path: Path to the report file to generate. - @param template_file_path: Path to the template file to use. - If None, the default template is used. - """ - # Determine the template file and directory to use - if template_file_path is None: - template_file_path = os.path.join(ROOT_PATH, 'gen_report_template.html') - - report_util.generate_report(template_file_path, report_file_path, {'rep_data' : rep_data}) - -class ReportData(object): - """ - Data object that stores all information used in report generation. - """ - - def __init__(self): - self.generation_timestamp = time.time() - self.generation_time = strftime("%d.%m.%Y %H:%M:%S") - self.options = None - self.lines = [] - self.nbr_of_refs = 0 - self.nbr_of_refs_noimpl = 0 - self.cwd = os.getcwd() - self.ref_noimpl = [] - self.duration = 0 - self.output_dir = os.getcwd() - self.project_dir = '' - self.rule_exec_results = [] - self.missing_output_files = [] - - def set_output_dir(self, dir): - self.output_dir = os.path.abspath(os.path.normpath(dir)) - - def add_line(self, line): - self.lines.append(line) - - def set_duration(self, duration): - self.duration = duration - - def set_options(self, options): - self.options = options - self.project_dir = os.path.abspath(options.project) - - def set_report_filename(self, filename): - self.report_filename = filename - - def add_ref_noimpl(self, ref): - self.ref_noimpl.append(ref) - - def update_nbr_of_refs(self): - self.nbr_of_refs = len(self.lines) - - def update_nbr_of_refs_noimpl(self): - self.nbr_of_refs_noimpl = len(self.ref_noimpl) - - def __repr__(self): - return "ReportData(%s)" % [self.generation_timestamp, - self.generation_time, - self.options, - self.lines, - self.nbr_of_refs, - self.nbr_of_refs_noimpl, - self.cwd, - self.ref_noimpl, - self.duration, - self.output_dir, - self.project_dir, - self.rule_exec_results, - self.missing_output_files] - -class RefLine(object): - """ - Data object that stores information for one ref in report generation. - """ - - def __init__(self, ref, type): - self.ref = ref - self.feat_type = type - self.feat_name = None - self.feat_value = None - self.config_path = None - self.impls = [] - self.output = None - self.nbr_impls = 0 - self.nbr_outputfiles = 0 - self.datas = [] - self.nbr_of_datas = 0 - self.nbr_of_rows = 0 - self.seq_data = [] - self.is_temp_feature = False - - def add_impl(self, impl_file, impl_type, outputfiles): - self.impls.append(ImplLine(impl_file, impl_type, outputfiles)) - self.nbr_impls = len(self.impls) - self.nbr_outputfiles = len(outputfiles) + self.nbr_outputfiles - - def add_data(self, layer, value): - self.datas.append(DataLine(layer,value)) - self.nbr_of_datas = len(self.datas) - - def add_sequence(self, subsetting, values): - self.seq_data.append([subsetting, values]) - - def set_feat_name(self, name): - self.feat_name = name - - def set_feat_value(self, value): - self.feat_value = value - - def set_config_path(self, filename): - self.config_path = os.path.normpath(filename) - -class ImplLine(): - def __init__(self, impl_file, impl_type, outputfiles, generation_runs=[]): - self.name = os.path.normpath(impl_file) - self.type = impl_type - files = [] - - for outputfile in outputfiles: - files.append(Outputfile(outputfile)) - - self.outputfiles = files - self.generation_runs = generation_runs - -class Outputfile(): - def __init__(self, filename): - self.filename = os.path.normpath(filename) - self.abs_filename = os.path.abspath(filename) - self.exists = os.path.isfile(self.abs_filename) - - def __eq__(self, other): - if type(self) is type(other): - return self.filename == other.filename - else: - return False - -class DataLine(): - def __init__(self, layer, value): - self.layer = os.path.normpath(layer) - self.value = value \ No newline at end of file