def new(url): """Start a new Jira ticket""" repo = Repo('/Users/dominic.batten/projects/eigen') if repo.is_dirty(): return click.echo('You have unstaged changes. Aborting') issue = Issue(url) # branch_input = branchify( # click.prompt( # 'Please enter branch name', # default=issue.default_title(), # ), # ) # new_branch = f"{issue.type()}/{branch_input}/{issue.key()}" # click.echo(f"Creating new branch {new_branch}") # repo.git.checkout('master') # click.echo("Pulling latest master") # repo.remotes.origin.pull('master') # click.echo("Switching to new branch") # current = repo.create_head(new_branch) # current.checkout() # with open('/tmp/scratch.vim' , 'r') as file: # current_notes = file.read(100) # overwrite = click.confirm( # f"Overwrite current scratch window?\n{current_notes}...", # default=True, # ) # if overwrite: with open('/tmp/scratch.md', 'w') as file: file.write(issue.description()) # else: # with open('/tmp/scratch.vim' , 'a') as file: # file.write(issue.description()) click.echo("Done")
def _mock_jira(self, old_jira=False, user=None): mock.patch.stopall() mock_patch = mock.patch('waldur_jira.backend.JIRA') self.mock_jira = mock_patch.start() self.mock_jira().fields.return_value = json.loads( load_resource('jira_fields.json')) issue_raw = json.loads(load_resource('jira_issue_raw.json')) mock_backend_issue = Issue({'server': ''}, None, raw=issue_raw) mock_backend_issue.update = mock.MagicMock() self.mock_jira( ).create_customer_request.return_value = mock_backend_issue self.mock_jira().waldur_create_customer_request.return_value = ( mock_backend_issue) self.mock_jira().create_issue.return_value = mock_backend_issue mock_backend_users = [ User( {'server': ''}, None, raw={ 'key': 'user_1', 'active': True, 'name': user.email if user else '*****@*****.**', }, ) ] if old_jira: self.mock_jira().search_users.return_value = mock_backend_users else: self.mock_jira( ).waldur_search_users.return_value = mock_backend_users
def transition_jira_issue(issue: Issue, state=None): """ Note: if state is None, then this merely makes the labels self-consistent. :param issue: :param state: :return: """ current_fields = issue.fields labels = set(current_fields.labels) if state is not None: assert state in progression.values() labels.discard('NeedsValidation') labels.add(state) expand_triage_label(labels) if {progression[triage_state] for triage_state in triage_states} <= labels: labels.remove('Triage') new_fields = { "labels": list(labels), } issue.update(fields=new_fields)
def unflag_issue(conn: CustomJira, issue: Issue) -> None: """ Remove the "Impediment" flag from an issue. :param conn: Jira connection. :param issue: Jira issue. """ if getattr(issue.fields, conn.issue_fields[settings.JIRA_FIELDS_FLAGGED]): issue.update(fields={conn.issue_fields[settings.JIRA_FIELDS_FLAGGED]: None})
def flag_issue(conn: CustomJira, issue: Issue) -> None: """ Add the "Impediment" flag to an issue. :param conn: Jira connection. :param issue: Jira issue. """ if not getattr(issue.fields, conn.issue_fields[settings.JIRA_FIELDS_FLAGGED]): issue.update(fields={conn.issue_fields[settings.JIRA_FIELDS_FLAGGED]: [{"value": "Impediment"}]})
def search_issues() -> ResultList: result = ResultList() for x in range(0, 10, 1): temp_issue = Issue(None, None) temp_issue.key = 'Test-{}'.format(x) temp_issue.updated = '2014-01-01 00:00:01' result.append(temp_issue) return result
def _close_issue(self, issue: jira.Issue, fields: Dict[str, Any], ignore_reopened: bool) -> None: if issue.fields.status.name == 'Closed': issue.update(fields=fields) return if not ignore_reopened and JiraCloser._is_reopened(issue): self.jira_client.add_comment(issue, 'A change related to this issue was integrated. This issue was re-opened before, the bot will not close this issue, please close it manually when applicable.') return if issue.fields.status.name == 'In Progress': fields.update({'resolution': {'name': 'Done'}}) self.jira_client.transition_issue(issue.key, transition='Fixed', fields=fields) return fields.update({'resolution': {'name': 'Done'}}) self.jira_client.transition_issue(issue.key, transition='Close', fields=fields)
def _mock_jira(self): mock.patch.stopall() mock_patch = mock.patch('waldur_jira.backend.JIRA') self.mock_jira = mock_patch.start() self.mock_jira().fields.return_value = json.loads(load_resource('jira_fields.json')) issue_raw = json.loads(load_resource('jira_issue_raw.json')) mock_backend_issue = Issue({'server': ''}, None, raw=issue_raw) mock_backend_issue.update = mock.MagicMock() self.mock_jira().create_customer_request.return_value = mock_backend_issue self.mock_jira().create_issue.return_value = mock_backend_issue mock_backend_users = [User({'server': ''}, None, raw={'key': 'user_1', 'active': True})] self.mock_jira().search_users.return_value = mock_backend_users
def non_cached_issue(issue_key: str) -> 'JiraIssue': """ Used to represent a non-cached JiraIssue for use during dependency resolution storage / visualization :return: a JiraIssue w/out an active connection or any fields outside the issue key """ new_issue = Issue(None, None) new_issue.key = issue_key result = JiraIssue(None, new_issue) result['relationship'] = 'MISSING CHAIN' result['summary'] = 'BREAK IN CHAIN. Cache offline to see deps.' result.is_cached_offline = False # hard-code it to being open since we don't know result['resolution'] = None return result
def transform(self): with open(self.pickle_filepath, 'rb') as f: self.issues = [ parse_jira_issue(Issue(options=None, session=None, raw=i)) for i in pickle.load(f) ] print('Jiras transform completed')
def print_issue(issue: jira.Issue) -> None: grid = Table.grid(expand=True) grid.add_column() grid.add_column() grid.add_row("", "") # probably better way to add padding than this grid.add_row("[bold magenta]Key", issue.key) grid.add_row("[bold magenta]Summary", issue.fields.summary) grid.add_row("[bold magenta]URL", issue.permalink()) grid.add_row("[bold magenta]Issue type", issue.fields.issuetype.name) grid.add_row("[bold magenta]Status", issue.fields.status.name) # import pdb # pdb.set_trace() # if issue.fields.issuetype.subtask is False: time_remaining = format_time(issue.fields.aggregatetimeestimate or 0) row_title = "Total time remaining" if issue.fields.issuetype.subtask is False: row_title += " (including subtasks)" grid.add_row( f"[bold magenta]{row_title}", time_remaining, ) time_spent = format_time(issue.fields.aggregatetimespent or 0) row_title = "Total time spent" if issue.fields.issuetype.subtask is False: row_title += " (including subtasks)" grid.add_row( f"[bold magenta]{row_title}", time_spent, ) grid.add_row("", "") # probably better way to add padding than this print(grid)
def index(): payload = app.current_request.json_body issue = Issue(payload) employee = Employee(payload) if issue.type == "New Hire": print("New Hire ticket processing.") try: fn.onboard_user(issue, employee) print("New Hire ticket processed.") return {'status': "Onboarding success."} except: print("New Hire ticket failed to process.") return {'status': "An error ocurred with onboarding."} elif issue.type == "Termination": print("Termination ticket processing.") try: fn.terminate_user(issue, employee) return {'status': "Termination success."} except: return {'status': "An error ocurred with termination."} elif issue.type == "Change": print("Change ticket processing.") try: fn.change_user(issue, employee) return {'status': "Information change success."} except: return {'status': "An error ocurred with information change."} else: print("All conditions failed. No ticket processing.") return {'status': "Unknown issue type."}
def getIssues(jira, board_id, sprint_id): """Return the issues for the sprint.""" r_json = jira._get_json('board/%s/sprint/%s/issue?maxResults=1000' % (board_id, sprint_id), base=jira.AGILE_BASE_URL) issues = [Issue(jira._options, jira._session, raw_issues_json) for raw_issues_json in r_json['issues']] return issues
def getBacklogIssues(jira, board, max): r_json = jira._get_json('board/%s/backlog?maxResults=%s' % (board.id, max), base=jira.AGILE_BASE_URL) issues = [ Issue(jira._options, jira._session, raw_issues_json) for raw_issues_json in r_json['issues'] ] return issues
def _get_issue_properties(issue: Issue) -> DataIssue: """ Maps the jira issue object to properties we want in the UI :param issue: Jira issue to map :return: JiraIssue """ return DataIssue(issue_key=issue.key, title=issue.fields.summary, url=issue.permalink())
def test__jira_issue_to_package(self, jira_board_provider, config): """ Test whether exceptions are handled/raised correctly. """ issue = Issue(None, None) issue.fields = Mock() for attribute in config.ISSUE_FIELDS: issue.fields.__setattr__(attribute, str(random())) try: jira_board_provider._jira_issue_to_package(issue) except AttributeError: assert True issue.fields = object try: jira_board_provider._jira_issue_to_package(issue) except JiraIssueMissingFields: assert True
def search_issues(self, *args, **kwargs): _ = args, self if kwargs["startAt"] > 0: return [] with open("./test_data/sample_issue.json", mode="r", encoding="utf-8") as file: raw_issue = json.loads(file.read()) test_issue = Issue(options=None, session=None, raw=raw_issue) return [test_issue]
def _get_issue_properties(issue: Issue) -> DataIssue: """ Maps the jira issue object to properties we want in the UI :param issue: Jira issue to map :return: JiraIssue """ return DataIssue(issue_key=issue.key, title=issue.fields.summary, url=issue.permalink(), status=issue.fields.status.name, priority=Priority.from_jira_severity( issue.fields.priority.name))
def jira_issue(): raw = { "id": "1001", "self": "https://bebit-sw.atlassian.net/rest/api/2/issue/1001", "key": "KEY-1", "fields": { "summary": "This is the summary", "worklog": { "worklogs": [raw_worklog()] } }, } return Issue(None, None, raw=raw)
def get_issue(self, key, refresh=True): """ Get a potentially cached issue. Keep Jira module API. TODO: Refresh before returning, unless offline mode or explicit off. This returns a wrapped issue for detailed work on a single issue. """ assert not key.startswith("_") cached = self.cache.shelve.get(key, None) if cached is None and (refresh is False or self.jira.is_connected is False): return None issue = Issue(options={}, session=self.link, raw=cached) return issue
def __init__(self, m): self.issue_url = 'https://acme.atlassian.net/browse/ID-123' m.register_uri( 'GET', f"{self.base_url}/ID-123", json={ 'fields': { 'summary': 'The summary', 'description': 'The description', 'issuetype': { 'name': 'Task' } } }, ) self.issue = Issue()
def _get_cached(self, source: BaseSource) -> Iterator[Result]: cache_key = ":".join( [ str(self.jira.client_info()), str(self.query.from_), str(self.query.where), str(self.query.order_by), str(self.query.limit), str(self.query.expand), ] ) if self.query.cache: try: min_recency, _ = self.query.cache if min_recency is None: raise KeyError(cache_key) cached_results = self.cache.get(cache_key, min_recency=min_recency) if not cached_results: raise KeyError(cache_key) source.update_count(len(cached_results)) source.remove_progress() for result in cached_results: yield SingleResult(Issue({}, None, result)) return except KeyError: pass cache = [] for result in source: cache.append(result) yield SingleResult(source.rehydrate(result)) if self.query.cache: _, max_store = self.query.cache if max_store is not None: self.cache.set(cache_key, cache, expire=max_store)
def setUp(self): super().setUp() self.JIRA_ISSUES = [ { "key": "ALPHA-1", "fields": { "issuetype": "Issue", "summary": "My Ticket", "project": "ALPHA", "story_points": 1, "customfield10010": 50, "customfield10011": "Ivanovna", "customfield10012": MyResource({"ok": "yes"}), "customfield10013": NonResource(), "worklogs": DotMap({ "total": 1, "worklogs": [{ "timespentSeconds": 60 }] }), "transactions": DotMap( {"byCurrency": { "usd": 100, "cad": 105, "cop": 200 }}), }, }, { "key": "ALPHA-3", "fields": { "issuetype": "Bug", "summary": "Another Ticket", "project": "ALPHA", "story_points": 10, "customfield10010": 55, "customfield10011": "Jackson", "customfield10012": MyResource({"ok": "no"}), "customfield10013": NonResource(), "worklogs": DotMap({ "total": 2, "worklogs": [ { "timespentSeconds": 30 }, { "timespentSeconds": 15 }, ], }), "transactions": DotMap({"byCurrency": { "cad": 124, "cop": 843 }}), }, }, { "key": "ALPHA-2", "fields": { "issuetype": "Issue", "summary": "My Ticket #2", "project": "ALPHA", "story_points": 1, "customfield10010": 56, "customfield10011": "Chartreuse", "customfield10012": MyResource({"ok": "maybe"}), "customfield10013": NonResource(), "transactions": DotMap({"byCurrency": { "usd": 10, "rur": 33 }}), }, }, ] issues = JiraList( [Issue(None, None, issue) for issue in self.JIRA_ISSUES]) issues.total = len(self.JIRA_ISSUES) self.mock_jira = Mock(search_issues=Mock(return_value=issues), fields=Mock(return_value=[]))
def index(): payload = app.current_request.json_body issue = Issue(payload)