def test_4(self):
        body = [
            u'#### ISSUE TYPE',
            u'- Feature Idea',
            u'#### COMPONENT NAME',
            u'Modules openssl_privatekey and openssl_publickey',
            u'#### ANSIBLE VERSION',
            u'```',
            u'ansible 2.2.1.0',
            u'  config file = /home/kellerfuchs/hashbang/admin-tools/ansible.cfg',
            u'  configured module search path = Default w/o overrides',
            u'```',
            u'#### SUMMARY',
            u'the widget AND thingamig modules are broken!!!'
        ]
        body = u'\r\n'.join(body)
        issue_number = 0
        issue_class = u'issue'
        sections = [u'ISSUE TYPE', u'COMPONENT NAME', u'ANSIBLE VERSION', u'SUMMARY']
        tdata = extract_template_data(
            body, issue_number=issue_number,
            issue_class=issue_class, sections=sections
        )

        #import epdb; epdb.st()
        assert tdata.get(u'ansible version').split(u'\n')[0] == u'ansible 2.2.1.0'
        assert tdata.get(u'issue type') == u'feature idea'
        assert tdata.get(u'component name') == u'openssl_privatekey'
        assert tdata.get(u'component_raw') == u'Modules openssl_privatekey and openssl_publickey'
        assert tdata.get(u'summary') == u'the widget AND thingamig modules are broken!!!'
    def get_template_data(self):
        """Extract templated data from an issue body"""

        if self.is_issue():
            tfile = '.github/ISSUE_TEMPLATE.md'
        else:
            tfile = '.github/PULL_REQUEST_TEMPLATE.md'

        # use the fileindexer whenever possible to conserve ratelimits
        if self.file_indexer:
            tf_content = self.file_indexer.get_file_content(tfile)
        else:
            tf = self.repo.get_file_contents(tfile)
            tf_content = tf.decoded_content

        tf_sections = extract_template_sections(tf_content)

        self._required_template_sections = \
            [x.lower() for x in tf_sections.keys()
             if tf_sections[x]['required']]

        template_data = \
            extract_template_data(
                self.instance.body,
                issue_number=self.number,
                issue_class=self.github_type,
                SECTIONS=tf_sections.keys()
            )

        return template_data
Beispiel #3
0
    def test_4(self):
        body = [
            '#### ISSUE TYPE',
            '- Feature Idea',
            '#### COMPONENT NAME',
            'Modules openssl_privatekey and openssl_publickey',
            '#### ANSIBLE VERSION',
            '```',
            'ansible 2.2.1.0',
            '  config file = /home/kellerfuchs/hashbang/admin-tools/ansible.cfg',
            '  configured module search path = Default w/o overrides',
            '```',
            '#### SUMMARY',
            'the widget AND thingamig modules are broken!!!'
        ]
        body = '\r\n'.join(body)
        issue_class = 'issue'
        sections = ['ISSUE TYPE', 'COMPONENT NAME', 'ANSIBLE VERSION', 'SUMMARY']
        tdata = extract_template_data(
            body, issue_class=issue_class, sections=sections
        )

        #import epdb; epdb.st()
        assert tdata.get('ansible version').split('\n')[0] == 'ansible 2.2.1.0'
        assert tdata.get('issue type') == 'feature idea'
        assert tdata.get('component name') == 'openssl_privatekey'
        assert tdata.get('component_raw') == 'Modules openssl_privatekey and openssl_publickey'
        assert tdata.get('summary') == 'the widget AND thingamig modules are broken!!!'
Beispiel #4
0
    def test_generic_template_with_no_input_sections(self):

        # https://github.com/ansible/ansibullbot/issues/1163

        body = [
            u'<!--- Verify first that your feature was not already discussed on GitHub -->',
            u'<!--- Complete *all* sections as described, this form is processed automatically -->',
            u'', u'##### SUMMARY',
            u'<!--- Describe the new feature/improvement briefly below -->',
            u'I was using vcenter_license to apply a license to ESXi hosts. Since the last commit on Jan 10, 2019, that module only supports licensing a vCenter. Add support for ESXi licensing',
            u'##### ISSUE TYPE', u'- Feature Idea', u'',
            u'##### COMPONENT NAME', u'vcenter_license ', u'or ',
            u'vmware_host', u'', u'##### ADDITIONAL INFORMATION',
            u'<!--- Describe how the feature would be used, why it is needed and what it would solve -->',
            u'',
            u'<!--- Paste example playbooks or commands between quotes below -->',
            u'```yaml', u'', u'```', u'',
            u'<!--- HINT: You can also paste gist.github.com links for larger files -->',
            u''
        ]
        body = u'\r\n'.join(body)
        tdata = extract_template_data(body)

        assert u'component name' in tdata
        assert tdata[u'component name'] == 'vcenter_license'
        assert u'component_raw' in tdata
        assert tdata[u'component_raw'] == 'vcenter_license\nor\nvmware_host'
        assert u'issue type' in tdata
        assert tdata[u'issue type'] == u'feature idea'
        assert u'summary' in tdata
        assert u'additional information' in tdata
    def test_component_matching(self):

        print('')

        AT = AnsibleTriage(args={})
        AT.file_indexer.get_files()

        jfile = 'tests/fixtures/issue_template_meta.json'
        with open(jfile, 'rb') as f:
            jdata = json.load(f)

        keys = sorted([int(x) for x in jdata.keys()])

        for key in keys:

            k = to_text(key)
            v = jdata[k]

            if '/pull/' in v['html_url']:
                continue

            if not v.get('labels'):
                continue

            if 'module' in v['labels']:
                continue

            clabels = [x for x in v['labels'] if x.startswith('c:')]
            #if not clabels:
            #    continue

            print(v['html_url'])

            # extract fields from the body
            td = extract_template_data(
                v['body'],
                issue_number=key,
                issue_class=None
            )

            components = AT.file_indexer.find_component_match(
                v['title'],
                v['body'],
                td
            )
            if components and clabels:
                comp_labels = AT.file_indexer.get_component_labels(
                    AT.valid_labels,
                    components
                )
                print('\t' + to_text(comp_labels))
 def test_0(self):
     body = [
         '#### ONE', 'section one', '#### TWO', 'section two', '#### THREE',
         'section three'
     ]
     body = '\r\n'.join(body)
     issue_class = 'issue'
     sections = ['ONE', 'TWO', 'THREE']
     tdata = extract_template_data(body,
                                   issue_class=issue_class,
                                   sections=sections)
     assert tdata.get('one') == 'section one'
     assert tdata.get('two') == 'section two'
     assert tdata.get('three') == 'section three'
    def test_module_matching(self):

        print('')

        AT = AnsibleTriage(args={})

        jfile = 'tests/fixtures/issue_template_meta.json'
        with open(jfile, 'rb') as f:
            jdata = json.load(f)

        keys = sorted([int(x) for x in jdata.keys()])

        for key in keys:

            k = str(key)
            v = jdata[k]

            if '/pull/' in v['html_url']:
                continue

            print(v['html_url'])

            # extract fields from the body
            td = extract_template_data(v['body'],
                                       issue_number=key,
                                       issue_class=None)

            # schema tests
            assert isinstance(td, dict)
            assert 'component_raw' in td
            assert 'component name' in td

            # confirm the raw converted to the component name
            assert td['component_raw'] == v['component_raw']
            assert td['component name'] == v['component_name']

            # confirm module matching works.
            mm = AT.find_module_match(v['title'], td)
            if v['module_match']:
                if mm is None:
                    import epdb
                    epdb.st()
                elif mm['filepath'] != v['module_match'] and \
                        mm['name'] != v['module_match']:
                    import epdb
                    epdb.st()
            elif mm is not None:
                import epdb
                epdb.st()
Beispiel #8
0
    def test_module_matching(self):

        print('')

        AT = AnsibleTriage(args={})

        jfile = 'tests/fixtures/issue_template_meta.json'
        with open(jfile, 'rb') as f:
            jdata = json.load(f)

        keys = sorted([int(x) for x in jdata.keys()])

        for key in keys:

            k = to_text(key)
            v = jdata[k]

            if '/pull/' in v['html_url']:
                continue

            print(v['html_url'])

            # extract fields from the body
            td = extract_template_data(
                v['body'],
                issue_number=key,
                issue_class=None
            )

            # schema tests
            assert isinstance(td, dict)
            assert 'component_raw' in td
            assert 'component name' in td

            # confirm the raw converted to the component name
            assert td['component_raw'] == v['component_raw']
            assert td['component name'] == v['component_name']

            # confirm module matching works.
            mm = AT.find_module_match(v['title'], td)
            if v['module_match']:
                if mm is None:
                    import epdb; epdb.st()
                elif mm['filepath'] != v['module_match'] and \
                        mm['name'] != v['module_match']:
                    import epdb; epdb.st()
            elif mm is not None:
                import epdb; epdb.st()
Beispiel #9
0
 def test_0(self):
     body = [
         u'#### ONE', u'section one', u'#### TWO', u'section two',
         u'#### THREE', u'section three'
     ]
     body = u'\r\n'.join(body)
     issue_number = 0
     issue_class = u'issue'
     sections = [u'ONE', u'TWO', u'THREE']
     tdata = extract_template_data(body,
                                   issue_number=issue_number,
                                   issue_class=issue_class,
                                   sections=sections)
     assert tdata.get(u'one') == u'section one'
     assert tdata.get(u'two') == u'section two'
     assert tdata.get(u'three') == u'section three'
    def test_component_matching(self):

        print('')

        AT = AnsibleTriage(args={})
        AT.file_indexer.get_files()

        jfile = 'tests/fixtures/issue_template_meta.json'
        with open(jfile, 'rb') as f:
            jdata = json.load(f)

        keys = sorted([int(x) for x in jdata.keys()])

        for key in keys:

            k = str(key)
            v = jdata[k]

            if '/pull/' in v['html_url']:
                continue

            if not v.get('labels'):
                continue

            if 'module' in v['labels']:
                continue

            clabels = [x for x in v['labels'] if x.startswith('c:')]
            #if not clabels:
            #    continue

            print(v['html_url'])

            # extract fields from the body
            td = extract_template_data(v['body'],
                                       issue_number=key,
                                       issue_class=None)

            components = AT.file_indexer.find_component_match(
                v['title'], v['body'], td)
            if components and clabels:
                comp_labels = AT.file_indexer.get_component_labels(
                    AT.valid_labels, components)
                print('\t' + str(comp_labels))
 def test_2(self):
     body = [
         '*** issue type ***:', '- Bug Report', '*** component name ***:',
         'widget module', '*** ansible version ***:', '1.9.x'
         '*** summary ***:', 'the widget module does not work for me!!!'
     ]
     body = '\r\n'.join(body)
     issue_class = 'issue'
     sections = [
         'ISSUE TYPE', 'COMPONENT NAME', 'ANSIBLE VERSION', 'SUMMARY'
     ]
     tdata = extract_template_data(body,
                                   issue_class=issue_class,
                                   sections=sections)
     assert tdata.get('ansible version') == '1.9.x'
     assert tdata.get('issue type') == 'bug report'
     assert tdata.get('component name') == 'widget'
     assert tdata.get('component_raw') == 'widget module'
     assert tdata.get(
         'summary') == 'the widget module does not work for me!!!'
 def test_3(self):
     body = [
         '#### ISSUE TYPE', '- Bug Report', '#### COMPONENT NAME',
         'widget, thingamajig', '#### ANSIBLE VERSION', '1.9.x'
         '#### SUMMARY', 'the widget AND thingamig modules are broken!!!'
     ]
     body = '\r\n'.join(body)
     issue_class = 'issue'
     sections = [
         'ISSUE TYPE', 'COMPONENT NAME', 'ANSIBLE VERSION', 'SUMMARY'
     ]
     tdata = extract_template_data(body,
                                   issue_class=issue_class,
                                   sections=sections)
     assert tdata.get('ansible version') == '1.9.x'
     assert tdata.get('issue type') == 'bug report'
     assert tdata.get('component name') == 'widget'
     assert tdata.get('component_raw') == 'widget, thingamajig'
     assert tdata.get(
         'summary') == 'the widget AND thingamig modules are broken!!!'
 def test_0(self):
     body = [
         u'#### ONE',
         u'section one',
         u'#### TWO',
         u'section two',
         u'#### THREE',
         u'section three'
     ]
     body = u'\r\n'.join(body)
     issue_number = 0
     issue_class = u'issue'
     sections = [u'ONE', u'TWO', u'THREE']
     tdata = extract_template_data(
         body, issue_number=issue_number,
         issue_class=issue_class, sections=sections
     )
     assert tdata.get(u'one') == u'section one'
     assert tdata.get(u'two') == u'section two'
     assert tdata.get(u'three') == u'section three'
    def test_generic_template_with_no_input_sections(self):

        # https://github.com/ansible/ansibullbot/issues/1163

        body = [
            u'<!--- Verify first that your feature was not already discussed on GitHub -->',
            u'<!--- Complete *all* sections as described, this form is processed automatically -->',
            u'',
            u'##### SUMMARY',
            u'<!--- Describe the new feature/improvement briefly below -->',
            u'I was using vcenter_license to apply a license to ESXi hosts. Since the last commit on Jan 10, 2019, that module only supports licensing a vCenter. Add support for ESXi licensing',
            u'##### ISSUE TYPE',
            u'- Feature Idea',
            u'',
            u'##### COMPONENT NAME',
            u'vcenter_license ',
            u'or ',
            u'vmware_host',
            u'',
            u'##### ADDITIONAL INFORMATION',
            u'<!--- Describe how the feature would be used, why it is needed and what it would solve -->',
            u'',
            u'<!--- Paste example playbooks or commands between quotes below -->',
            u'```yaml',
            u'',
            u'```',
            u'',
            u'<!--- HINT: You can also paste gist.github.com links for larger files -->',
            u''
        ]
        body = u'\r\n'.join(body)
        tdata = extract_template_data(body)

        assert u'component name' in tdata
        assert tdata[u'component name'] == 'vcenter_license'
        assert u'component_raw' in tdata
        assert tdata[u'component_raw'] == 'vcenter_license\nor\nvmware_host'
        assert u'issue type' in tdata
        assert tdata[u'issue type'] == u'feature idea'
        assert u'summary' in tdata
        assert u'additional information' in tdata
Beispiel #15
0
 def test_1(self):
     body = [
         u'#### ISSUE TYPE', u'- Bug Report', u'#### COMPONENT NAME',
         u'widget module', u'#### ANSIBLE VERSION', u'1.9.x'
         u'#### SUMMARY', u'the widget module does not work for me!!!'
     ]
     body = u'\r\n'.join(body)
     issue_number = 0
     issue_class = u'issue'
     sections = [
         u'ISSUE TYPE', u'COMPONENT NAME', u'ANSIBLE VERSION', u'SUMMARY'
     ]
     tdata = extract_template_data(body,
                                   issue_number=issue_number,
                                   issue_class=issue_class,
                                   sections=sections)
     assert tdata.get(u'ansible version') == u'1.9.x'
     assert tdata.get(u'issue type') == u'bug report'
     assert tdata.get(u'component name') == u'widget'
     assert tdata.get(u'component_raw') == u'widget module'
     assert tdata.get(
         u'summary') == u'the widget module does not work for me!!!'
Beispiel #16
0
    def get_template_data(self):
        """Extract templated data from an issue body"""

        if self.is_issue():
            tfile = '.github/ISSUE_TEMPLATE.md'
        else:
            tfile = '.github/PULL_REQUEST_TEMPLATE.md'


        # use the fileindexer whenever possible to conserve ratelimits
        if self.file_indexer:
            tf_content = self.file_indexer.get_file_content(tfile)
        else:
            try:
                tf = self.repo.get_file_contents(tfile)
                tf_content = tf.decoded_content
            except Exception as e:
                logging.warning('repo does not have {}'.format(tfile))
                tf_content = ''

        # pull out the section names from the tempalte
        tf_sections = extract_template_sections(tf_content, header=self.TEMPLATE_HEADER)

        # what is required?
        self._required_template_sections = \
            [x.lower() for x in tf_sections.keys()
             if tf_sections[x]['required']]

        # extract ...
        template_data = \
            extract_template_data(
                self.instance.body,
                issue_number=self.number,
                issue_class=self.github_type,
                sections=tf_sections.keys()
            )

        return template_data
Beispiel #17
0
 def test_5(self):
     body = [
         u'#### ISSUE TYPE ####', u'- Bug Report',
         u'#### COMPONENT NAME ####', u'widget, thingamajig',
         u'#### ANSIBLE VERSION ####', u'1.9.x'
         u'#### SUMMARY ####',
         u'the widget AND thingamig modules are broken!!!'
     ]
     body = u'\r\n'.join(body)
     issue_number = 0
     issue_class = u'issue'
     sections = [
         u'ISSUE TYPE', u'COMPONENT NAME', u'ANSIBLE VERSION', u'SUMMARY'
     ]
     tdata = extract_template_data(body,
                                   issue_number=issue_number,
                                   issue_class=issue_class,
                                   sections=sections)
     assert tdata.get(u'ansible version') == u'1.9.x'
     assert tdata.get(u'issue type') == u'bug report'
     assert tdata.get(u'component name') == u'widget'
     assert tdata.get(u'component_raw') == u'widget, thingamajig'
     assert tdata.get(
         u'summary') == u'the widget AND thingamig modules are broken!!!'
 def test_3(self):
     body = [
         u'#### ISSUE TYPE',
         u'- Bug Report',
         u'#### COMPONENT NAME',
         u'widget, thingamajig',
         u'#### ANSIBLE VERSION',
         u'1.9.x'
         u'#### SUMMARY',
         u'the widget AND thingamig modules are broken!!!'
     ]
     body = u'\r\n'.join(body)
     issue_number = 0
     issue_class = u'issue'
     sections = [u'ISSUE TYPE', u'COMPONENT NAME', u'ANSIBLE VERSION', u'SUMMARY']
     tdata = extract_template_data(
         body, issue_number=issue_number,
         issue_class=issue_class, sections=sections
     )
     assert tdata.get(u'ansible version') == u'1.9.x'
     assert tdata.get(u'issue type') == u'bug report'
     assert tdata.get(u'component name') == u'widget'
     assert tdata.get(u'component_raw') == u'widget, thingamajig'
     assert tdata.get(u'summary') == u'the widget AND thingamig modules are broken!!!'
 def test_2(self):
     body = [
         u'*** issue type ***:',
         u'- Bug Report',
         u'*** component name ***:',
         u'widget module',
         u'*** ansible version ***:',
         u'1.9.x'
         u'*** summary ***:',
         u'the widget module does not work for me!!!'
     ]
     body = u'\r\n'.join(body)
     issue_number = 0
     issue_class = u'issue'
     sections = [u'ISSUE TYPE', u'COMPONENT NAME', u'ANSIBLE VERSION', u'SUMMARY']
     tdata = extract_template_data(
         body, issue_number=issue_number,
         issue_class=issue_class, sections=sections
     )
     assert tdata.get(u'ansible version') == u'1.9.x'
     assert tdata.get(u'issue type') == u'bug report'
     assert tdata.get(u'component name') == u'widget'
     assert tdata.get(u'component_raw') == u'widget module'
     assert tdata.get(u'summary') == u'the widget module does not work for me!!!'
Beispiel #20
0
    def get_template_data(self):
        """Extract templated data from an issue body"""

        if self.is_issue():
            tfile = '.github/ISSUE_TEMPLATE.md'
        else:
            tfile = '.github/PULL_REQUEST_TEMPLATE.md'

        # use the fileindexer whenever possible to conserve ratelimits
        if self.file_indexer:
            tf_content = self.file_indexer.get_file_content(tfile)
        else:
            try:
                tf = self.repo.get_file_contents(tfile)
                tf_content = tf.decoded_content
            except Exception:
                logging.warning('repo does not have {}'.format(tfile))
                tf_content = ''

        # pull out the section names from the tempalte
        tf_sections = extract_template_sections(tf_content,
                                                header=self.TEMPLATE_HEADER)

        # what is required?
        self._required_template_sections = \
            [x.lower() for x in tf_sections.keys()
             if tf_sections[x]['required']]

        # extract ...
        template_data = \
            extract_template_data(
                self.instance.body,
                issue_number=self.number,
                issue_class=self.github_type,
                sections=tf_sections.keys()
            )

        # try comments if the description was insufficient
        if len(template_data.keys()) <= 2:
            s_comments = self.history.get_user_comments(self.submitter)
            for s_comment in s_comments:

                _template_data = extract_template_data(
                    s_comment,
                    issue_number=self.number,
                    issue_class=self.github_type,
                    sections=tf_sections.keys())

                if _template_data:
                    for k, v in _template_data.items():
                        if not v:
                            continue
                        if v and (k not in template_data
                                  or not template_data.get(k)):
                            template_data[k] = v

        if 'ANSIBLE VERSION' in tf_sections and 'ansible version' not in template_data:

            # FIXME - abstract this into a historywrapper method
            vlabels = [
                x for x in self.history.history if x['event'] == 'labeled'
            ]
            vlabels = [
                x for x in vlabels
                if x['actor'] not in ['ansibot', 'ansibotdev']
            ]
            vlabels = [
                x['label'] for x in vlabels
                if x['label'].startswith('affects_')
            ]
            vlabels = [x for x in vlabels if x.startswith('affects_')]

            versions = [x.split('_')[1] for x in vlabels]
            versions = [float(x) for x in versions]
            if versions:
                version = versions[-1]
                template_data['ansible version'] = str(version)

        if 'COMPONENT NAME' in tf_sections and 'component name' not in template_data:
            if self.is_pullrequest():
                fns = self.files
                if fns:
                    template_data['component name'] = '\n'.join(fns)
                    template_data['component_raw'] = '\n'.join(fns)
            else:
                clabels = [x for x in self.labels if x.startswith('c:')]
                if clabels:
                    fns = []
                    for clabel in clabels:
                        clabel = clabel.replace('c:', '')
                        fns.append('lib/ansible/' + clabel)
                    template_data['component name'] = '\n'.join(fns)
                    template_data['component_raw'] = '\n'.join(fns)

                elif 'documentation' in template_data.get('issue type',
                                                          '').lower():
                    template_data['component name'] = 'docs'
                    template_data['component_raw'] = 'docs'

        if 'ISSUE TYPE' in tf_sections and 'issue type' not in template_data:

            # FIXME - turn this into a real classifier based on work done in
            # jctanner/pr-triage repo.

            itype = None

            while not itype:

                for label in self.labels:
                    if label.startswith('bug'):
                        itype = 'bug'
                        break
                    elif label.startswith('feature'):
                        itype = 'feature'
                        break
                    elif label.startswith('doc'):
                        itype = 'docs'
                        break
                if itype:
                    break

                if self.is_pullrequest():
                    fns = self.files
                    for fn in fns:
                        if fn.startswith('doc'):
                            itype = 'docs'
                            break
                if itype:
                    break

                msgs = [self.title, self.body]
                if self.is_pullrequest():
                    msgs += [
                        x['message'] for x in self.history.history
                        if x['event'] == 'committed'
                    ]

                msgs = [x for x in msgs if x]
                msgs = [x.lower() for x in msgs]

                for msg in msgs:
                    if 'fix' in msg:
                        itype = 'bug'
                        break
                    if 'addresses' in msg:
                        itype = 'bug'
                        break
                    if 'broke' in msg:
                        itype = 'bug'
                        break
                    if 'add' in msg:
                        itype = 'feature'
                        break
                    if 'should' in msg:
                        itype = 'feature'
                        break
                    if 'please' in msg:
                        itype = 'feature'
                        break
                    if 'feature' in msg:
                        itype = 'feature'
                        break

                # quit now
                break

            if itype and itype == 'bug' and self.is_issue():
                template_data['issue type'] = 'bug report'
            elif itype and itype == 'bug' and not self.is_issue():
                template_data['issue type'] = 'bugfix pullrequest'
            elif itype and itype == 'feature' and self.is_issue():
                template_data['issue type'] = 'feature idea'
            elif itype and itype == 'feature' and not self.is_issue():
                template_data['issue type'] = 'feature pullrequest'
            elif itype and itype == 'docs' and self.is_issue():
                template_data['issue type'] = 'documentation report'
            elif itype and itype == 'docs' and not self.is_issue():
                template_data['issue type'] = 'documenation pullrequest'

        return template_data
Beispiel #21
0
    def get_template_data(self):
        """Extract templated data from an issue body"""

        if self.is_issue():
            tfile = u'.github/ISSUE_TEMPLATE.md'
        else:
            tfile = u'.github/PULL_REQUEST_TEMPLATE.md'

        # use the fileindexer whenever possible to conserve ratelimits
        if self.file_indexer:
            tf_content = self.file_indexer.get_file_content(tfile)
        else:
            try:
                tf = self.repo.get_file_contents(tfile)
                tf_content = tf.decoded_content
            except Exception:
                logging.warning(u'repo does not have {}'.format(tfile))
                tf_content = u''

        # pull out the section names from the tempalte
        tf_sections = extract_template_sections(tf_content, header=self.TEMPLATE_HEADER)

        # what is required?
        self._required_template_sections = \
            [x.lower() for x in tf_sections.keys()
             if tf_sections[x][u'required']]

        # extract ...
        template_data = \
            extract_template_data(
                self.instance.body,
                issue_number=self.number,
                issue_class=self.github_type,
                sections=tf_sections.keys()
            )

        # try comments if the description was insufficient
        if len(template_data.keys()) <= 2:
            s_comments = self.history.get_user_comments(self.submitter)
            for s_comment in s_comments:

                _template_data = extract_template_data(
                    s_comment,
                    issue_number=self.number,
                    issue_class=self.github_type,
                    sections=tf_sections.keys()
                )

                if _template_data:
                    for k, v in _template_data.items():
                        if not v:
                            continue
                        if v and (k not in template_data or not template_data.get(k)):
                            template_data[k] = v

        if u'ANSIBLE VERSION' in tf_sections and u'ansible version' not in template_data:

            # FIXME - abstract this into a historywrapper method
            vlabels = [x for x in self.history.history if x[u'event'] == u'labeled']
            vlabels = [x for x in vlabels if x[u'actor'] not in [u'ansibot', u'ansibotdev']]
            vlabels = [x[u'label'] for x in vlabels if x[u'label'].startswith(u'affects_')]
            vlabels = [x for x in vlabels if x.startswith(u'affects_')]

            versions = [x.split(u'_')[1] for x in vlabels]
            versions = [float(x) for x in versions]
            if versions:
                version = versions[-1]
                template_data[u'ansible version'] = to_text(version)

        if u'COMPONENT NAME' in tf_sections and u'component name' not in template_data:
            if self.is_pullrequest():
                fns = self.files
                if fns:
                    template_data[u'component name'] = u'\n'.join(fns)
                    template_data[u'component_raw'] = u'\n'.join(fns)
            else:
                clabels = [x for x in self.labels if x.startswith(u'c:')]
                if clabels:
                    fns = []
                    for clabel in clabels:
                        clabel = clabel.replace(u'c:', u'')
                        fns.append(u'lib/ansible/' + clabel)
                    template_data[u'component name'] = u'\n'.join(fns)
                    template_data[u'component_raw'] = u'\n'.join(fns)

                elif u'documentation' in template_data.get(u'issue type', u'').lower():
                    template_data[u'component name'] = u'docs'
                    template_data[u'component_raw'] = u'docs'

        if u'ISSUE TYPE' in tf_sections and u'issue type' not in template_data:

            # FIXME - turn this into a real classifier based on work done in
            # jctanner/pr-triage repo.

            itype = None

            while not itype:

                for label in self.labels:
                    if label.startswith(u'bug'):
                        itype = u'bug'
                        break
                    elif label.startswith(u'feature'):
                        itype = u'feature'
                        break
                    elif label.startswith(u'doc'):
                        itype = u'docs'
                        break
                if itype:
                    break

                if self.is_pullrequest():
                    fns = self.files
                    for fn in fns:
                        if fn.startswith(u'doc'):
                            itype = u'docs'
                            break
                if itype:
                    break

                msgs = [self.title, self.body]
                if self.is_pullrequest():
                    msgs += [x[u'message'] for x in self.history.history if x[u'event'] == u'committed']

                msgs = [x for x in msgs if x]
                msgs = [x.lower() for x in msgs]

                for msg in msgs:
                    if u'fix' in msg:
                        itype = u'bug'
                        break
                    if u'addresses' in msg:
                        itype = u'bug'
                        break
                    if u'broke' in msg:
                        itype = u'bug'
                        break
                    if u'add' in msg:
                        itype = u'feature'
                        break
                    if u'should' in msg:
                        itype = u'feature'
                        break
                    if u'please' in msg:
                        itype = u'feature'
                        break
                    if u'feature' in msg:
                        itype = u'feature'
                        break

                # quit now
                break

            if itype and itype == u'bug' and self.is_issue():
                template_data[u'issue type'] = u'bug report'
            elif itype and itype == u'bug' and not self.is_issue():
                template_data[u'issue type'] = u'bugfix pullrequest'
            elif itype and itype == u'feature' and self.is_issue():
                template_data[u'issue type'] = u'feature idea'
            elif itype and itype == u'feature' and not self.is_issue():
                template_data[u'issue type'] = u'feature pullrequest'
            elif itype and itype == u'docs' and self.is_issue():
                template_data[u'issue type'] = u'documentation report'
            elif itype and itype == u'docs' and not self.is_issue():
                template_data[u'issue type'] = u'documenation pullrequest'

        return template_data
def run_template_extract(FI, body, number, gtype, sections):
    template_data = extract_template_data(body, number, gtype, sections)
    return template_data