Skip to content
This repository has been archived by the owner on Oct 13, 2023. It is now read-only.

Transition to using python-bugzilla library #10

Merged
merged 1 commit into from
Jan 15, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
15 changes: 1 addition & 14 deletions README.md
Expand Up @@ -10,7 +10,6 @@ tedious and error prone.

* [Basics & Terminology](#basics--terminology)
* [Setup and Installation](#setup-and-installation)
* [Additional Softwares](#additional-softwares)
* [Authenticating](#authenticating)
* [Tests](#tests)
* [Usage](#usage)
Expand Down Expand Up @@ -70,18 +69,6 @@ software and bug fixes

`pip install rh-elliott`

## Additional Softwares

Elliott requires additional command line tools to fully function:

1. `brew` - Installation instructions are
[available in Mojo](https://mojo.redhat.com/docs/DOC-1071519). Requires
an active kerberos ticket to use.
1. `bugzilla` - Available through DNF repos as the
`python-bugzilla-cli` package. **Ensure** that you run `bugzilla
login` after installation!


## Authenticating

Ensure you have a valid kerberos ticket before proceeding. A valid
Expand Down Expand Up @@ -389,4 +376,4 @@ Add or remove any other `*_test.py` tests you wish.

If that works then you can open the HTML coverage report:

* `xdg-open cover/index.html`
* `xdg-open cover/index.html`
79 changes: 7 additions & 72 deletions elliott
Expand Up @@ -21,7 +21,7 @@ import sys
from elliottlib import version
from elliottlib import Runtime
import elliottlib.constants
import elliottlib.bugzilla
import elliottlib.bzutil
import elliottlib.brew
import elliottlib.errata
import elliottlib.exceptions
Expand All @@ -31,6 +31,7 @@ from elliottlib.exceptions import ElliottFatalError
from elliottlib.util import *

# 3rd party
import bugzilla
import click
import requests
import dotconfig
Expand Down Expand Up @@ -353,9 +354,10 @@ manually. Provide one or more --id's for manual bug addition.
raise click.BadParameter("If not using --auto then one or more --id's must be provided")

if auto:
bug_ids = elliottlib.bugzilla.search_for_bugs(bz_data, status)
bug_ids = elliottlib.bzutil.search_for_bugs(bz_data, status)
else:
bug_ids = [elliottlib.bugzilla.Bug(id=i) for i in id]
bzapi = elliottlib.bzutil.get_bzapi(bz_data)
bug_ids = [bzapi.getbug(i) for i in id]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are the best at duplicating code


bug_count = len(bug_ids)

Expand All @@ -377,13 +379,13 @@ manually. Provide one or more --id's for manual bug addition.

if len(flag) > 0:
for bug in bug_ids:
bug.add_flags(flag)
bug.update_flags({flag: "+"})

advs.addBugs([bug.id for bug in bug_ids])
advs.commit()
else: # Add bug is false (noop)
green_prefix("Would have added {n} bugs: ".format(n=bug_count))
click.echo(", ".join([str(b) for b in bug_ids]))
click.echo(", ".join([str(b.bug_id) for b in bug_ids]))


#
Expand Down Expand Up @@ -699,73 +701,6 @@ Example to add standard metadata to a 3.10 images release
exit(1)


#
# Find transitions
# bugzilla:find-transitions
#
@cli.command("find-bug-transitions", short_help="Find bugs that have gone through the specifed transition")
@click.option("--currently", 'current_state',
required=True,
type=click.Choice(elliottlib.constants.VALID_BUG_STATES),
help="State that the bug is in now")
@click.option("--from", 'changed_from',
required=True,
type=click.Choice(elliottlib.constants.VALID_BUG_STATES),
help="State that the bug started in")
@click.option("--to", 'changed_to',
required=True,
type=click.Choice(elliottlib.constants.VALID_BUG_STATES),
help="State that the bug ended in")
@click.option("--add-comment", "add_comment", is_flag=True, default=False,
help="Add the nag comment to found bugs")
@pass_runtime
def find_transitions(runtime, current_state, changed_from, changed_to, add_comment):
"""Find Red Hat Bugzilla bugs that have gone through a specifed state change. This is mainly useful for
finding "bad" state transitions to catch bugzilla users operating outside of a specified workflow.

\b
$ elliott bugzilla:find-transitions --currently VERIFIED --from ASSIGNED --to ON_QA
"""
bz_data = runtime.gitdata.load_data(key='bugzilla').data

bug_ids = elliottlib.bugzilla.search_for_bug_transitions(bz_data, current_state, changed_from, changed_to)

click.echo('Found the following bugs matching that transition: {}'.format(bug_ids))

if(add_comment):
# check if we've already commented
for bug in bug_ids:
if not bug.has_whiteboard_value('ocp_art_invalid_transition'):
bug.add_comment(elliottlib.constants.bugzilla_invalid_transition_comment, is_private=True)
click.echo('Added comment to {}'.format(bug.id))
bug.add_whiteboard_value('ocp_art_invalid_transition')
else:
click.echo('Skipping {} because it has already been flagged.'.format(bug))

#
# Add a comment to a bug
# bugzilla:add-comment
#
@cli.command("add-bug-comment", short_help="Add a comment to a bug")
@click.option("--id", "bug_ids",
multiple=True, required=True,
help="Bugzilla ID to add the comment to --auto [MULTIPLE]")
@click.option("--comment", "-c", "comment",
required=True,
help="Text of the added comment")
@click.option("--private", "is_private", is_flag=True, default=False,
help="Make the added comment private")
@pass_runtime
def add_comment(runtime, bug_ids, comment, is_private):
bug_list = [elliottlib.bugzilla.Bug(id=i) for i in bug_ids]
click.echo(bug_list)

for bug in bug_list:
click.echo(bug)
bug.add_comment(comment, is_private)

click.echo('Added comment to {}'.format(bug.id))

# -----------------------------------------------------------------------------
# CLI Entry point
# -----------------------------------------------------------------------------
Expand Down
66 changes: 8 additions & 58 deletions elliottlib/bugzilla.py → elliottlib/bzutil.py
Expand Up @@ -13,6 +13,7 @@

# 3rd party
import click
import bugzilla

logger = logutil.getLogger(__name__)

Expand All @@ -22,6 +23,7 @@ def search_for_bugs(bz_data, status, verbose=False):

:return: A list of Bug objects
"""
bzapi = get_bzapi(bz_data)
sosiouxme marked this conversation as resolved.
Show resolved Hide resolved
query_url = SearchURL(bz_data)

for f in bz_data.get('filter'):
Expand All @@ -40,65 +42,13 @@ def search_for_bugs(bz_data, status, verbose=False):
if verbose:
click.echo(query_url)

new_bugs = check_output(
['bugzilla', 'query', '--ids', '--from-url="{0}"'.format(query_url)]).splitlines()
query = bzapi.url_to_query(str(query_url))
query["include_fields"] = ["id"]

return bzapi.query(query)

return [Bug(id=i) for i in new_bugs]

def search_for_bug_transitions(bz_data, current_state, changed_from, changed_to):
query_url = SearchURL(bz_data)

query_url.addBugStatus(current_state)

query_url.addFilterOperator("AND_G")

query_url.addFilter("bug_status", "changedfrom", changed_from)
query_url.addFilter("bug_status", "changedto", changed_to)

for v in bz_data.get('version'):
query_url.addVersion(v)

changed_bugs = check_output(
['bugzilla', 'query', '--ids', '--from-url="{0}"'.format(query_url)]).splitlines()

return [Bug(id=i) for i in changed_bugs]

class Bug(object):
"""
Abstract interactions with bugzilla bugs
"""
def __init__(self, id):
""":param int id: A Bugzilla bug ID"""
self.id = id

def __str__(self):
return str(self.id)

def __repr__(self):
return str(self)

def add_comment(self, comment, is_private):
"""Add a comment to a bug"""
if is_private:
call(['bugzilla', 'modify', self.id, '--comment', comment, '--private'])
else:
call(['bugzilla', 'modify', self.id, '--comment', comment])

def add_flags(self, flags=[]): # pragma: no cover
"""Add flags to a bug"""
for flag in flags:
self.add_flag(flag)

def add_flag(self, flag):
"""Add the given flag to the bug"""
call(['bugzilla', 'modify', '--flag', '{0}+'.format(flag), self.id])

def add_whiteboard_value(self, value):
call(['bugzilla', 'modify', self.id, '--whiteboard', value])

def has_whiteboard_value(self, value):
"""Check if the value is in the Whiteboard for the bug"""
return check_output(['bugzilla', 'query', '--id', self.id, '--whiteboard', value])
def get_bzapi(bz_data):
return bugzilla.Bugzilla(bz_data['server'])


class SearchFilter(object):
Expand Down
4 changes: 2 additions & 2 deletions elliottlib/bugzilla_test.py → elliottlib/bzutil_test.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python

import unittest
import bugzilla
import bzutil

hostname = "bugzilla.redhat.com"

Expand All @@ -15,7 +15,7 @@ def test_search_filter(self):
value = "RFE"
expected = "&f1=component&o1=notequals&v1=RFE"

sf = bugzilla.SearchFilter(field_name, operator, value)
sf = bzutil.SearchFilter(field_name, operator, value)
self.assertEqual(sf.tostring(1), expected)

# class TestSearchURL(unittest.TestCase):
Expand Down
6 changes: 0 additions & 6 deletions elliottlib/constants.py
Expand Up @@ -64,10 +64,4 @@
errata_get_erratum_url = errata_url + "/api/v1/erratum/{id}"
errata_post_erratum_url = errata_url + "/api/v1/erratum"

bugzilla_invalid_transition_comment = """There is a potential issue with this bug that may prevent it from being processed by our automation.

For more information on proper bug management visit:
https://mojo.redhat.com/docs/DOC-1178565#jive_content_id_How_do_I_get_my_Bugzilla_Bug_to_VERIFIED
"""

DISTGIT_MAX_FILESIZE = 50000000
1 change: 1 addition & 0 deletions requirements.txt
Expand Up @@ -7,5 +7,6 @@ pydotconfig
pygitdata
pykwalify
pyyaml
python-bugzilla
requests
requests_kerberos