Ejemplo n.º 1
0
    }
for k, v in default_parameters.items():
    if not hasattr(config, k):
        setattr(config, k, v)


# 2.2. Check generic parameters
#
# Defect tracker specific configuration parameters are checked by the
# configuration generator for that defect tracker.

if config.administrator_address != None:
    check_config.check_email(config, 'administrator_address')
check_config.check_changelist_url(config, 'changelist_url')
check_config.check_string_or_none(config, 'closed_state')
check_config.check_string(config, 'configure_name')
check_config.check_string_or_none(config, 'log_file')
check_config.check_job_url(config, 'job_url')
check_config.check_bool(config, 'keep_jobspec')
check_config.check_int(config, 'log_level')
check_config.check_int(config, 'log_max_message_length')
check_config.check_function(config, 'migrate_p')
check_config.check_string(config, 'p4_client_executable')
check_config.check_string(config, 'p4_port')
check_config.check_string(config, 'p4_user')
check_config.check_string(config, 'p4_password')
check_config.check_string(config, 'p4_server_description')
check_config.check_int(config, 'poll_period')
check_config.check_function(config, 'prepare_issue')
check_config.check_function(config, 'replicate_job_p')
check_config.check_function(config, 'replicate_p')
Ejemplo n.º 2
0
def configuration(config):
    # Check Bugzilla specific configuration parameters.
    check_config.check_string_or_none(config, 'bugzilla_directory')
    check_config.check_host(config, 'dbms_host')
    check_config.check_int(config, 'dbms_port')
    check_config.check_string(config, 'dbms_database')
    check_config.check_string(config, 'dbms_user')
    check_config.check_string(config, 'dbms_password')
    check_config.check_string(config, 'migrated_user_password')
    check_config.check_list_of(config, 'migrated_user_groups',
                               types.StringType, 'strings')
    check_config.check_list_of(config, 'replicated_fields',
                               types.StringType, 'strings')
    check_config.check_list_of(config, 'omitted_fields',
                               types.StringType, 'strings')
    check_config.check_list_of_string_pairs(config, 'field_names')

    check_bugzilla_directory(config)
    check_field_lists(config)

    # Handle logger.  We need a list of logger objects:
    log_params = {
        'priority': config.log_level,
        'max_length': config.log_max_message_length,
        }
    # The log messages should go to (up to) three places:
    # 1. to standard output (if running from a command line);
    loggers = []
    if config.use_stdout_log:
        loggers.append(apply(logger.file_logger, (), log_params))
    # 2. to the file named by the log_file configuration parameter (if
    # not None);
    if config.log_file != None:
        loggers.append(apply(logger.file_logger,
                             (open(config.log_file, "a"),),
                             log_params))
    # 3. to the Windows event log (if use_windows_event_log is true).
    if os.name == 'nt' and config.use_windows_event_log:
        loggers.append(apply(logger.win32_event_logger,
                             (config.rid,),
                             log_params))
    # 4. to the Unix syslog (if use_system_log is true).
    if os.name == 'posix' and config.use_system_log:
        loggers.append(apply(logger.sys_logger,
                             (),
                             log_params))

    # now a single logger object which logs to all of the logger objects
    # in our list:
    config.logger = logger.multi_logger(loggers)

    # Open a connection to the Bugzilla database.  This makes a DB-API
    # v2.0 connection object.  To work with a database other than
    # MySQL, change this to make an appropriate connection object.
    # Note that in that case changes are also needed in bugzilla.py
    # where we deal with MySQL-specific types such as tinyint.
    db = mysqldb_support.connect(config)

    # Make a Bugzilla DB object.  Note that this same object is used
    # subsequently by the replicator itself.
    config.bugzilla = bugzilla.bugzilla(db, config)

    # Get the types of the 'bugs' table from Bugzilla
    bugs_types = config.bugzilla.get_types('bugs')

    # Check field names against Bugzilla database and construct
    # a map, Bugzilla field name to Perforce field name.
    fields_bz_to_p4 = get_fields_bz_to_p4(config, bugs_types)

    user_name_length = get_user_name_length(config)

    # strict user translator doesn't allow unknown users
    strict_user_translator = dt_bugzilla.user_translator(
        config.replicator_address, config.p4_user, allow_unknown = 0)

    # lax user translator does allow unknown users
    lax_user_translator = dt_bugzilla.user_translator(
        config.replicator_address, config.p4_user, allow_unknown = 1)

    # p4_fields maps Bugzilla field name to the jobspec data (number,
    # name, type, length, dispositon, preset, values, help text,
    # translator).  The fields Job and Date are special: they are not
    # replicated from Bugzilla but are required by Perforce, so we
    # have them here.  Note that their help text is given (the other
    # help texts will be obtained from the bz_field_map).

    p4_fields = { \
        '(JOB)':       ( 101, 'Job', 'word', 32, 'required',
                         None, None,
                         "The job name.",
                         None ),
        '(DATE)':      ( 104, 'Date', 'date', 20, 'always',
                         '$now', None,
                         "The date this job was last modified.",
                         None ),
        # P4DTI fields:
        '(FILESPECS)': ( 191, 'P4DTI-filespecs', 'text', 0, 'optional',
                         None, None,
                         "Associated filespecs.",
                         None ),
        '(RID)':       ( 192, 'P4DTI-rid', 'word', 32, 'required',
                         'None', None,
                         "P4DTI replicator identifier. Do not edit!",
                         None ),
        '(ISSUE)':     ( 193, 'P4DTI-issue-id', 'word', 32, 'required',
                         'None', None,
                         "Bugzilla issue database identifier. Do not "
                         "edit!",
                         None ),
        '(USER)':      ( 194, 'P4DTI-user', 'word', 32, 'always',
                         '$user', None,
                         "Last user to edit this job. You can't edit "
                         "this!",
                         None ),
        }

    if fields_bz_to_p4.has_key('bug_status'):
        if bugs_types['bug_status']['type'] != 'enum':
            # "The 'bug_status' column of Bugzilla's 'bugs' table is not an
            # enum type."
            raise error, catalog.msg(308)
        # Make a list of (Bugzilla state, Perforce state) pairs.
        state_pairs = make_state_pairs(bugs_types['bug_status']['values'],
                                       config.closed_state)


        # Work out the legal values of the State field in the jobspec.  Note
        # that "closed" must be a legal state because "p4 fix -c CHANGE
        # JOBNAME" always sets the State to "closed" even if "closed" is not
        # a legal value.  See job000225.
        legal_states = map((lambda x: x[1]), state_pairs)
        if 'closed' not in legal_states:
            legal_states.append('closed')
        state_values = string.join(legal_states, '/')
        p4_fields['bug_status'] = ( 102,
                                    fields_bz_to_p4['bug_status'],
                                    'select',
                                    bugs_types['bug_status']['length'],
                                    'required',
                                    state_pairs[0][1],
                                    state_values,
                                    bz_field_map['bug_status'][1],
                                    dt_bugzilla.status_translator(state_pairs))

    if fields_bz_to_p4.has_key('assigned_to'):
        p4_fields['assigned_to'] = ( 103,
                                     fields_bz_to_p4['assigned_to'],
                                     'word', user_name_length,
                                     'required',
                                     '$user', None,
                                     bz_field_map['assigned_to'][1],
                                     strict_user_translator)

    if fields_bz_to_p4.has_key('short_desc'):
        p4_fields['short_desc'] = ( 105,
                                    fields_bz_to_p4['short_desc'],
                                    'text',
                                    bugs_types['short_desc']['length'],
                                    'required',
                                    '$blank', None,
                                    bz_field_map['short_desc'][1],
                                    dt_bugzilla.text_translator() )

    if fields_bz_to_p4.has_key('resolution'):
        if bugs_types['resolution']['type'] != 'enum':
            # "The 'resolution' column of Bugzilla's 'bugs' table is not an
            # enum type."
            raise error, catalog.msg(309)
        if not 'FIXED' in bugs_types['resolution']['values']:
            # "The 'resolution' column of Bugzilla's 'bugs' table does not
            # have a 'FIXED' value."
            raise error, catalog.msg(310)

        # Make a list of possible resolutions.
        (resolutions,
         default_resolution) = translate_enum('resolution',
                                              bugs_types['resolution'])
        p4_fields['resolution'] = ( 106,
                                    fields_bz_to_p4['resolution'],
                                    'select',
                                    bugs_types['resolution']['length'],
                                    'required',
                                    default_resolution,
                                    resolutions,
                                    bz_field_map['resolution'][1],
                                    enum_translator)

    # Additional replicated fields will be sequential from this field id.
    p4_field_id = 110

    # Go through the replicated_fields list, build structures and add
    # them to p4_fields.
    for bz_field in config.replicated_fields:
        p4_field = fields_bz_to_p4[bz_field]
        p4_fields[bz_field] = ((p4_field_id, ) +
                               make_p4_field_spec(bz_field, p4_field,
                                                  bugs_types[bz_field],
                                                  user_name_length,
                                                  strict_user_translator))
        p4_field_id = p4_field_id + 1
        if p4_field_id >= 191:
            # "Too many fields to replicate: Perforce jobs can contain
            # only 99 fields."
            raise error, catalog.msg(317)

    comment = ("# A Perforce Job Specification automatically "
               "produced by the\n"
               "# Perforce Defect Tracking Integration\n")

    jobspec = (comment, p4_fields.values())

    # Set configuration parameters needed by dt_bugzilla.
    config.append_only_fields = append_only_fields
    config.read_only_fields = read_only_fields
    config.jobname_function = lambda bug: 'bug%d' % bug['bug_id']

    # Set configuration parameters needed by the replicator.
    config.date_translator = dt_bugzilla.date_translator()
    config.job_owner_field = fields_bz_to_p4.get('assigned_to', 'User')
    config.job_status_field = fields_bz_to_p4.get('bug_status', 'Status')
    config.job_date_field = 'Date'
    config.jobspec = jobspec
    config.prepare_issue_advanced = prepare_issue_advanced
    config.text_translator = dt_bugzilla.text_translator()
    config.translate_jobspec_advanced = translate_jobspec_advanced
    config.user_translator = lax_user_translator

    # The field_map parameter is a list of triples (Bugzilla database
    # field name, Perforce field name, translator) required by the
    # replicator.  We use the filter to remove the fields that aren't
    # replicated: these have no translator.
    config.field_map = \
        map(lambda item: (item[0], item[1][1], item[1][8]),
            filter(lambda item: item[1][8] != None, p4_fields.items()))

    return config