Status: | Merged |
---|---|
Approved by: | David Britton |
Approved revision: | 178 |
Merged at revision: | 146 |
Proposed branch: | lp:~dpb/lp2kanban/lint-1 |
Merge into: | lp:lp2kanban |
Prerequisite: | lp:~dpb/lp2kanban/feature-hoover-just-the-facts |
Diff against target: |
1106 lines (+194/-165) 8 files modified
Makefile (+4/-1) src/lp2kanban/bugs2cards.py (+23/-20) src/lp2kanban/cards2workitems.py (+6/-6) src/lp2kanban/kanban.py (+38/-41) src/lp2kanban/tests/test_bugs2cards.py (+94/-72) src/lp2kanban/tests/test_cards2workitems.py (+13/-10) src/lp2kanban/tests/test_description_annotations.py (+6/-5) src/lp2kanban/workitems2cards.py (+10/-10) |
To merge this branch: | bzr merge lp:~dpb/lp2kanban/lint-1 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Alberto Donato (community) | Approve | ||
🤖 Landscape Builder | test results | Approve | |
Review via email: mp+305280@code.launchpad.net |
Commit message
Add lint target (flake8), remove lint.
Description of the change
Add lint target (flake8), remove lint.
make lint should pass
make ci-test includes lint check
To post a comment you must log in.
Revision history for this message
🤖 Landscape Builder (landscape-builder) : | # |
review:
Abstain
(executing tests)
Revision history for this message
🤖 Landscape Builder (landscape-builder) wrote : | # |
review:
Approve
(test results)
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'Makefile' |
2 | --- Makefile 2016-08-29 20:19:31 +0000 |
3 | +++ Makefile 2016-09-08 22:02:56 +0000 |
4 | @@ -61,4 +61,7 @@ |
5 | . venv/bin/activate; \ |
6 | $(MAKE) check |
7 | |
8 | -.PHONY: check default configs needs-xdg-utils clean ci-test |
9 | +lint: |
10 | + flake8 src/lp2kanban |
11 | + |
12 | +.PHONY: check default configs needs-xdg-utils clean ci-test lint |
13 | |
14 | === modified file 'src/lp2kanban/bugs2cards.py' |
15 | --- src/lp2kanban/bugs2cards.py 2016-09-08 22:02:56 +0000 |
16 | +++ src/lp2kanban/bugs2cards.py 2016-09-08 22:02:56 +0000 |
17 | @@ -141,7 +141,7 @@ |
18 | self.lp_to_group.update(parse_groups_config(groups_config)) |
19 | |
20 | self.feature_lanes = {} |
21 | - new_lane = config.get("new_lanes") |
22 | + new_lane = config.get("new_lanes") |
23 | if not new_lane: |
24 | return |
25 | if "${group}" in new_lane: |
26 | @@ -149,7 +149,7 @@ |
27 | for group in set(self.lp_to_group.values()): |
28 | lane_path = new_lane.replace("${group}", group) |
29 | lane = board.getLaneByPath(lane_path) |
30 | - group_tag = "squad-%s" % group.lower().replace(" ","-") |
31 | + group_tag = "squad-%s" % group.lower().replace(" ", "-") |
32 | self.feature_lanes[group_tag] = lane |
33 | for card in board.getFeatureCards(): |
34 | if not card.tags: |
35 | @@ -192,6 +192,7 @@ |
36 | IGNORE_STATUSES = ('Superseded',) |
37 | FINAL_STATUSES = ('Approved', 'Merged') |
38 | |
39 | + |
40 | def get_lp_bug(card, launchpad): |
41 | """Return the launchpad bug resource for a card if that bug exists. |
42 | |
43 | @@ -273,7 +274,7 @@ |
44 | |
45 | for card in feature_card.lane.board.cards: |
46 | if card_type and card.type.name != card_type: |
47 | - continue |
48 | + continue |
49 | if card.tags: |
50 | card_tags = set(card.tags.split(",")) |
51 | if feature_tags.intersection(card_tags): |
52 | @@ -304,7 +305,7 @@ |
53 | mps = [] |
54 | has_inprogress_branches = False |
55 | for branch in branches: |
56 | - if hasattr(branch, 'branch') : |
57 | + if hasattr(branch, 'branch'): |
58 | branch = branch.branch |
59 | for mp in branch.landing_targets: |
60 | mp_info = Record(rank=None, status=None, mp=None) |
61 | @@ -319,7 +320,7 @@ |
62 | mps.append(mp_info) |
63 | if len(mps) == 0: |
64 | return None |
65 | - mps.sort(key=lambda x:(x.rank, x.mp.date_created), reverse=True) |
66 | + mps.sort(key=lambda x: (x.rank, x.mp.date_created), reverse=True) |
67 | if not has_inprogress_branches: |
68 | return mps[0] # Return highest-ranked and most-recent MP |
69 | for mp in mps: |
70 | @@ -395,7 +396,7 @@ |
71 | return False |
72 | if card.tags and "no-sync" in set(card.tags.split(",")): |
73 | return False |
74 | - |
75 | + |
76 | enabled = conf.get('move_cards', 'off') == 'on' |
77 | active = not card.lane.board.is_archived |
78 | return enabled and active |
79 | @@ -498,7 +499,7 @@ |
80 | status = CardStatus.LANDING |
81 | elif branch_card_status: |
82 | return branch_card_status |
83 | - |
84 | + |
85 | elif bug_status in DONE_FIX_BUG_STATUSES: |
86 | status = CardStatus.DONE_FIX |
87 | elif bug_status in DONE_NOFIX_BUG_STATUSES: |
88 | @@ -512,7 +513,7 @@ |
89 | if task.target in all_projects: |
90 | return True |
91 | if (hasattr(task.target, "project") and |
92 | - task.target.project in all_projects): |
93 | + task.target.project in all_projects): |
94 | return True |
95 | return False |
96 | |
97 | @@ -525,13 +526,13 @@ |
98 | for task in tasks: |
99 | # Ignore bug task status for series targets |
100 | if (task.target.resource_type_link == RESOURCE_TYPE_LINK_SERIES and |
101 | - task.target.project in all_projects): |
102 | + task.target.project in all_projects): |
103 | continue # Skip series task status for our projects |
104 | if (task.assignee is not None and |
105 | - task.assignee.name not in all_users): |
106 | + task.assignee.name not in all_users): |
107 | continue # Skip non-users tasks |
108 | if (task.target in all_projects or |
109 | - task.assignee is not None): |
110 | + task.assignee is not None): |
111 | matches = True |
112 | if (lowest_status is None or |
113 | (ORDERED_BUG_STATUSES.index(task.status) < |
114 | @@ -555,7 +556,6 @@ |
115 | return possible_target_lane |
116 | |
117 | |
118 | - |
119 | def find_card_target_lane_next(lane, path): |
120 | """Find the target lane for the path using the "next" algorithm. |
121 | |
122 | @@ -723,7 +723,7 @@ |
123 | assignee = Record(name=owner_name) |
124 | try: |
125 | move_card(card, card_status, bconf, [assignee], lp_users) |
126 | - except IOError as e: |
127 | + except IOError: |
128 | log.exception("Error moving card: %s (in %s)" % ( |
129 | card.title, card_path)) |
130 | continue |
131 | @@ -751,7 +751,8 @@ |
132 | continue |
133 | ignore_external_projects = ( |
134 | bconf.get("autosync") == "active-projects") |
135 | - if ignore_external_projects and not is_bug_in_projects(lp_bug, lp_projects): |
136 | + if ignore_external_projects and not is_bug_in_projects( |
137 | + lp_bug, lp_projects): |
138 | continue # Skip bugs in external projects |
139 | synced, card_status, assignees, mp_url, mp_type = get_bug_status( |
140 | lp_bug, lp_projects, lp_users.lp_to_kanban.keys()) |
141 | @@ -766,7 +767,7 @@ |
142 | if card_status is not None and should_move_card(card, bconf): |
143 | try: |
144 | move_card(card, card_status, bconf, assignees, lp_users) |
145 | - except IOError as e: |
146 | + except IOError: |
147 | log.exception("Error Moving: lp:%s: %s (in %s)" % ( |
148 | lp_bug.id, card.title, card_path)) |
149 | continue |
150 | @@ -878,7 +879,8 @@ |
151 | return |
152 | |
153 | log.info( |
154 | - u" * Moving card#{}: {} -> {}".format(card.id, card.lane.path, target_lane_path)) |
155 | + u" * Moving card#{}: {} -> {}".format( |
156 | + card.id, card.lane.path, target_lane_path)) |
157 | card.move(target_lane) |
158 | |
159 | |
160 | @@ -896,8 +898,8 @@ |
161 | # happens. |
162 | try: |
163 | card.save() |
164 | - except IOError as e: |
165 | - log.exception(u"Exception caught. Skipping board.\n" |
166 | + except IOError: |
167 | + log.exception("Exception caught. Skipping board.\n" |
168 | " desc:{}\n" |
169 | " kanban id:{}\n" |
170 | " LP bug id:{}\n".format( |
171 | @@ -937,7 +939,8 @@ |
172 | |
173 | if args.debug: |
174 | logging.basicConfig( |
175 | - level=logging.DEBUG, format='%(asctime)s %(levelname)s %(message)s') |
176 | + level=logging.DEBUG, |
177 | + format='%(asctime)s %(levelname)s %(message)s') |
178 | import httplib |
179 | httplib.HTTPConnection.debuglevel = 1 |
180 | else: |
181 | @@ -975,7 +978,7 @@ |
182 | continue |
183 | bconf = boards_config[board_name] |
184 | process_board(board, bconf, args.bug, args.card) |
185 | - except (KeyError, AssertionError) as e: |
186 | + except (KeyError, AssertionError): |
187 | log.exception("Exception caught. Skipping board.") |
188 | continue |
189 | |
190 | |
191 | === modified file 'src/lp2kanban/cards2workitems.py' |
192 | --- src/lp2kanban/cards2workitems.py 2013-06-19 19:44:20 +0000 |
193 | +++ src/lp2kanban/cards2workitems.py 2016-09-08 22:02:56 +0000 |
194 | @@ -13,9 +13,9 @@ |
195 | # support POSTPONED work items in this mapping, since the Kanban board |
196 | # has no such concept. |
197 | LANE_TYPE_TO_WORK_ITEM_STATUS_MAP = { |
198 | - 1: u"TODO", # Kanban type "Ready" |
199 | - 2: u"INPROGRESS", # Kanban type "In process" |
200 | - 3: u"DONE", # Kanban type "Complete" |
201 | + 1: u"TODO", # Kanban type "Ready" |
202 | + 2: u"INPROGRESS", # Kanban type "In process" |
203 | + 3: u"DONE", # Kanban type "Complete" |
204 | } |
205 | |
206 | |
207 | @@ -34,7 +34,7 @@ |
208 | card.description_annotations.get('blueprint_url') or |
209 | card.external_system_url) |
210 | if (blueprint_url is None or not |
211 | - blueprint_url_pattern.match(blueprint_url)): |
212 | + blueprint_url_pattern.match(blueprint_url)): |
213 | # Return early if the card isn't linked to a blueprint, since |
214 | # there's no point doing the conversion if we're not going to |
215 | # sync it. |
216 | @@ -118,8 +118,8 @@ |
217 | work_items_text = "\n".join(work_items) |
218 | blueprint = fetch_blueprint(lp, blueprint_url) |
219 | if blueprint is not None: |
220 | - print "Adding %s work items to %s" % ( |
221 | - len(work_items), blueprint.name) |
222 | + print("Adding %s work items to %s" % ( |
223 | + len(work_items), blueprint.name)) |
224 | blueprint.workitems_text = work_items_text |
225 | blueprint.lp_save() |
226 | |
227 | |
228 | === modified file 'src/lp2kanban/kanban.py' |
229 | --- src/lp2kanban/kanban.py 2016-09-08 22:02:56 +0000 |
230 | +++ src/lp2kanban/kanban.py 2016-09-08 22:02:56 +0000 |
231 | @@ -3,7 +3,6 @@ |
232 | |
233 | import requests |
234 | import json |
235 | -import logging |
236 | import operator |
237 | from pprint import pprint |
238 | import re |
239 | @@ -112,14 +111,14 @@ |
240 | |
241 | resp = request.response |
242 | if (not sent or |
243 | - resp.status_code not in LeankitResponseCodes.SUCCESS_CODES): |
244 | - print "Error from kanban" |
245 | + resp.status_code not in LeankitResponseCodes.SUCCESS_CODES): |
246 | + print("Error from kanban") |
247 | pprint(resp) |
248 | raise IOError('kanban error %d' % (resp.status_code)) |
249 | response = Record(json.loads(resp.content)) |
250 | |
251 | if (handle_errors and |
252 | - response.ReplyCode not in LeankitResponseCodes.SUCCESS_CODES): |
253 | + response.ReplyCode not in LeankitResponseCodes.SUCCESS_CODES): |
254 | raise IOError('kanban error %d: %s' % ( |
255 | response.ReplyCode, response.ReplyText)) |
256 | return response |
257 | @@ -166,7 +165,7 @@ |
258 | def _prettifyName(self, camelcase): |
259 | camelcase = camelcase.replace('ID', '_id') |
260 | if len(camelcase) > 1: |
261 | - repl_func = lambda match: '_' + match.group(1).lower() |
262 | + def repl_func(match): return '_' + match.group(1).lower() |
263 | camelcase = camelcase[0].lower() + camelcase[1:] |
264 | return re.sub('([A-Z])', repl_func, camelcase) |
265 | else: |
266 | @@ -174,7 +173,7 @@ |
267 | |
268 | def _toCamelCase(self, name): |
269 | if len(name) > 1: |
270 | - repl_func = lambda match: match.group(1)[1:].upper() |
271 | + def repl_func(match): return match.group(1)[1:].upper() |
272 | name = name[0].upper() + name[1:] |
273 | return re.sub('(_[a-z])', repl_func, name) |
274 | else: |
275 | @@ -236,9 +235,9 @@ |
276 | # no-op. |
277 | return |
278 | data = self._raw_data |
279 | - data["UserWipOverrideComment"] = None; |
280 | + data["UserWipOverrideComment"] = None |
281 | if ("AssignedUsers" in data and |
282 | - "assigned_user_id" not in self.dirty_attrs): |
283 | + "assigned_user_id" not in self.dirty_attrs): |
284 | if 'AssignedUserId' in data.keys(): |
285 | del data['AssignedUserId'] |
286 | if 'AssignedUserName' in data.keys(): |
287 | @@ -247,7 +246,6 @@ |
288 | lambda X: X['AssignedUserId'], data['AssignedUsers']) |
289 | |
290 | for attr in self.dirty_attrs: |
291 | - #print "Storing %s in %s..." % (attr, self._toCamelCase(attr)) |
292 | data[self._toCamelCase(attr)] = getattr(self, attr) |
293 | |
294 | board_id = str(self.lane.board.id) |
295 | @@ -380,7 +378,6 @@ |
296 | self.external_card_id = src.external_card_id |
297 | self.assigned_user_id = src.assigned_user_id |
298 | |
299 | - |
300 | @property |
301 | def parsed_description(self): |
302 | """Parse the card description to find key=value pairs. |
303 | @@ -397,8 +394,8 @@ |
304 | end = match.end() |
305 | try: |
306 | annotations = Record(json.loads(self.description[start:end])) |
307 | - except ValueError, ex: |
308 | - print "Unable to parse card %s: %s" % (self.id, ex.message) |
309 | + except ValueError as ex: |
310 | + print("Unable to parse card %s: %s" % (self.id, ex.message)) |
311 | annotations = Record() |
312 | return ( |
313 | annotations, |
314 | @@ -580,7 +577,7 @@ |
315 | archive_lanes = [lane_dict['Lane'] for lane_dict in self._archive] |
316 | archive_lanes.extend( |
317 | [lane_dict['Lane'] for |
318 | - lane_dict in self._archive[0]['ChildLanes']]) |
319 | + lane_dict in self._archive[0]['ChildLanes']]) |
320 | lanes += archive_lanes |
321 | lanes += self.connector.get( |
322 | "/Kanban/Api/Board/" + str(self.id) + "/Backlog").ReplyData[0] |
323 | @@ -594,7 +591,7 @@ |
324 | |
325 | def _classifyCards(self): |
326 | """Classify the cards into buckets for lookups later.""" |
327 | - print " Classifying cards %s cards." % len(self.cards) |
328 | + print(" Classifying cards %s cards." % len(self.cards)) |
329 | for card in self.cards: |
330 | if card.type.name == "Feature": |
331 | self._feature_cards.add(card) |
332 | @@ -608,18 +605,18 @@ |
333 | if BRANCH_MP_REGEX.match(card.external_system_url): |
334 | self._cards_with_branches.add(card) |
335 | else: |
336 | - print ("WARNING: Card won't sync. Non-branch link ({}) " |
337 | - "for {}.".format(url, card.title)) |
338 | - print " - %s feature cards" % len( |
339 | - self._feature_cards) |
340 | - print " - %s cards with external ids" % len( |
341 | - self._cards_with_external_ids) |
342 | - print " - %s cards with external links" % len( |
343 | - self._cards_with_external_links) |
344 | - print " - %s cards with description annotations" % len( |
345 | - self._cards_with_description_annotations) |
346 | - print " - %s cards with branches" % len( |
347 | - self._cards_with_branches) |
348 | + print("WARNING: Card won't sync. Non-branch link ({}) " |
349 | + "for {}.".format(url, card.title)) |
350 | + print(" - %s feature cards" % len( |
351 | + self._feature_cards)) |
352 | + print(" - %s cards with external ids" % len( |
353 | + self._cards_with_external_ids)) |
354 | + print(" - %s cards with external links" % len( |
355 | + self._cards_with_external_links)) |
356 | + print(" - %s cards with description annotations" % len( |
357 | + self._cards_with_description_annotations)) |
358 | + print(" - %s cards with branches" % len( |
359 | + self._cards_with_branches)) |
360 | |
361 | def _populateFeatureTagPaths(self): |
362 | """Create a map from feature tag to the group owning the feature.""" |
363 | @@ -672,12 +669,13 @@ |
364 | |
365 | def getLane(self, lane_id): |
366 | flat_lanes = {} |
367 | + |
368 | def flatten_lane(lane): |
369 | flat_lanes[lane.id] = lane |
370 | for child in lane.child_lanes: |
371 | flatten_lane(child) |
372 | map(flatten_lane, self.root_lane.child_lanes) |
373 | - return flat_lanes[lane_id]; |
374 | + return flat_lanes[lane_id] |
375 | |
376 | def getLaneByTitle(self, title): |
377 | if len(self.root_lane.child_lanes) > 0: |
378 | @@ -689,7 +687,7 @@ |
379 | else: |
380 | for child in lane.child_lanes: |
381 | result = self._getLaneByTitle(child, title) |
382 | - if result != None: |
383 | + if result is not None: |
384 | return result |
385 | return None |
386 | |
387 | @@ -698,7 +696,7 @@ |
388 | return self._getLaneByPath(self.root_lane, path, ignorecase) |
389 | |
390 | def _getLaneByPath(self, lane, path, ignorecase): |
391 | - if ignorecase == True: |
392 | + if ignorecase is True: |
393 | if lane.path.lower() == path.lower(): |
394 | return lane |
395 | else: |
396 | @@ -707,24 +705,23 @@ |
397 | |
398 | for child in lane.child_lanes: |
399 | result = self._getLaneByPath(child, path, ignorecase) |
400 | - if result != None: |
401 | + if result is not None: |
402 | return result |
403 | return None |
404 | |
405 | - |
406 | def _printLanes(self, lane, indent, include_cards=False): |
407 | next_lane = lane.getNextLanes() |
408 | if next_lane is None: |
409 | next_lane = '' |
410 | else: |
411 | next_lane = (' (next: any of [' + |
412 | - ', '.join([my_lane.path for my_lane in next_lane]) |
413 | - + '])') |
414 | + ', '.join([my_lane.path for my_lane in next_lane]) + |
415 | + '])') |
416 | next_lane += ' - %d cards' % len(lane.cards) |
417 | - print " " * indent + "* " + lane.title + next_lane |
418 | + print(" " * indent + "* " + lane.title + next_lane) |
419 | for card in lane.cards: |
420 | - print (" " * (indent + 1) + "- #" + card.external_card_id + |
421 | - ': ' + card.title) |
422 | + print(" " * (indent + 1) + "- #" + card.external_card_id + |
423 | + ': ' + card.title) |
424 | for child in lane.child_lanes: |
425 | self._printLanes(child, indent + 1) |
426 | |
427 | @@ -732,7 +729,7 @@ |
428 | """Recursively prints all the lanes in the board with indentation.""" |
429 | if len(self.root_lane.child_lanes) == 0: |
430 | return |
431 | - print "Board lanes:" |
432 | + print("Board lanes:") |
433 | indent = 1 |
434 | for lane in self.root_lane.child_lanes: |
435 | self._printLanes(lane, indent, include_cards) |
436 | @@ -818,16 +815,16 @@ |
437 | kanban = LeankitKanban('launchpad.leankitkanban.com', |
438 | 'user@email', 'password') |
439 | |
440 | - print "Active boards:" |
441 | + print("Active boards:") |
442 | boards = kanban.getBoards() |
443 | for board in boards: |
444 | - print " * %s (%d)" % (board.title, board.id) |
445 | + print(" * %s (%d)" % (board.title, board.id)) |
446 | |
447 | # Get a board by the title. |
448 | board_name = 'Landscape 2016' |
449 | - print "Getting board '%s'..." % board_name |
450 | + print("Getting board '%s'..." % board_name) |
451 | board = kanban.getBoard(title=board_name) |
452 | board.printLanes() |
453 | |
454 | # Print all users. |
455 | - print board.users |
456 | + print(board.users) |
457 | |
458 | === modified file 'src/lp2kanban/tests/test_bugs2cards.py' |
459 | --- src/lp2kanban/tests/test_bugs2cards.py 2016-09-08 22:02:56 +0000 |
460 | +++ src/lp2kanban/tests/test_bugs2cards.py 2016-09-08 22:02:56 +0000 |
461 | @@ -1,8 +1,6 @@ |
462 | # Copyright 2011-2012 Canonical Ltd |
463 | """Tests for the bugs2cards.py script.""" |
464 | |
465 | -__metaclass__ = type |
466 | - |
467 | from ConfigParser import ( |
468 | ConfigParser, |
469 | NoSectionError, |
470 | @@ -38,12 +36,9 @@ |
471 | ) |
472 | from lp2kanban.kanban import ( |
473 | RESOURCE_TYPE_LINK_SERIES, |
474 | - LeankitCard, |
475 | Record, |
476 | ) |
477 | from lp2kanban.tests.common import ( |
478 | - FauxLeankitUser, |
479 | - FauxLaunchpadUser, |
480 | FauxLaunchpadUsersForBoard, |
481 | FauxBoard, |
482 | FauxCard, |
483 | @@ -51,6 +46,8 @@ |
484 | FauxLane, |
485 | ) |
486 | |
487 | +__metaclass__ = type |
488 | + |
489 | |
490 | def parse_config_text(text): |
491 | config = ConfigParser() |
492 | @@ -90,8 +87,7 @@ |
493 | globals, boards = parse_config(config) |
494 | |
495 | self.assertEqual({'var1': 'value1', |
496 | - 'var2': 'value2', |
497 | - }, globals) |
498 | + 'var2': 'value2'}, globals) |
499 | self.assertEqual({'Board 1': {'var1': 'board value 1'}}, boards) |
500 | |
501 | def test_parse_config_defaults(self): |
502 | @@ -131,7 +127,9 @@ |
503 | |
504 | |
505 | class FauxMP: |
506 | - def __init__(self, queue_status, target_name, link=None, description=None, date_created=None): |
507 | + def __init__( |
508 | + self, queue_status, target_name, link=None, description=None, |
509 | + date_created=None): |
510 | self.queue_status = queue_status |
511 | self.target_branch = Record(name=target_name) |
512 | self.web_link = link |
513 | @@ -145,7 +143,7 @@ |
514 | self.projects = data.get("projects", {}) |
515 | self.project_group = data.get("project_groups", {}) |
516 | self.bugs = data.get("bugs", {}) |
517 | - |
518 | + |
519 | |
520 | class BranchInfoTests(unittest.TestCase): |
521 | |
522 | @@ -296,7 +294,7 @@ |
523 | def __init__(self, resource_type_link="http://api/project", project=None): |
524 | self.resource_type_link = resource_type_link |
525 | self.project = project |
526 | - |
527 | + |
528 | |
529 | class FauxBugTask: |
530 | |
531 | @@ -312,23 +310,25 @@ |
532 | class IsBugInProjectsTest(unittest.TestCase): |
533 | |
534 | def test_false_when_part_of_external_project(self): |
535 | - # Return False when the bug is part of an unconfigured (external) project |
536 | + # Return False when the bug is part of an unconfigured (external) |
537 | + # project |
538 | bug = FauxBug() |
539 | - project = FauxTarget(resource_type_link="project", project="otherproject") |
540 | + project = FauxTarget( |
541 | + resource_type_link="project", project="otherproject") |
542 | bug.addTask(project) |
543 | self.assertFalse(is_bug_in_projects(bug, ["myproject1", "myproject2"])) |
544 | |
545 | def test_true_when_part_of_configured_projects(self): |
546 | # Return True when the bug is one of the configured (internal) projects |
547 | bug = FauxBug() |
548 | - project = FauxTarget(resource_type_link="project", project="myproject2") |
549 | + project = FauxTarget( |
550 | + resource_type_link="project", project="myproject2") |
551 | bug.addTask(project) |
552 | self.assertTrue(is_bug_in_projects(bug, ["myproject1", "myproject2"])) |
553 | |
554 | - |
555 | def test_true_when_series_within_a_configured_project(self): |
556 | - # Return True when the bug has a series task that is related to one of the |
557 | - # configured projects. |
558 | + # Return True when the bug has a series task that is related to one |
559 | + # of the configured projects. |
560 | bug = FauxBug() |
561 | series = FauxTarget( |
562 | resource_type_link=RESOURCE_TYPE_LINK_SERIES, project="myproject1") |
563 | @@ -407,7 +407,8 @@ |
564 | # than 'Fix Committed'). |
565 | bug = FauxBug() |
566 | project1 = FauxTarget(resource_type_link="project", project="lazr") |
567 | - project2 = FauxTarget(resource_type_link="project", project="launchpad") |
568 | + project2 = FauxTarget( |
569 | + resource_type_link="project", project="launchpad") |
570 | bug.addTask(project1, status='Fix Released') |
571 | bug.addTask(project2, status='In Progress') |
572 | matches, status, assignees, mp_url, mp_type = get_bug_status( |
573 | @@ -583,8 +584,9 @@ |
574 | self.assertTrue(should_sync_card(card, {'autosync': 'on', |
575 | 'sync_cards': 'on'})) |
576 | |
577 | - def test_should_sync_card_autosync_synced_with_external_card_id(self): |
578 | - # When autosync is 'active-projects', cards with external card IDs are synced. |
579 | + def test_should_sync_card_autosync_active_projects_external_card_id(self): |
580 | + # When autosync is 'active-projects', cards with external card |
581 | + # IDs are synced. |
582 | card = Record(title=u'no sync', description=u'', |
583 | external_card_id=u'11', external_system_url=u'') |
584 | self.assertTrue(should_sync_card(card, {'autosync': 'active-projects', |
585 | @@ -663,8 +665,8 @@ |
586 | self.assertFalse(should_sync_card(card2, conf)) |
587 | |
588 | def test_get_card_status_new_no_branch(self): |
589 | - # For a bug in 'New', 'Triaged' or 'Confirmed' or 'Incomplete' statuses, |
590 | - # the branch status is new state. |
591 | + # For a bug in 'New', 'Triaged' or 'Confirmed' or |
592 | + # 'Incomplete' statuses the branch status is new state. |
593 | no_branch_info = Record(status=None) |
594 | self.assertEqual( |
595 | CardStatus.NEW, |
596 | @@ -681,29 +683,29 @@ |
597 | |
598 | def test_get_card_status_coding_no_bug(self): |
599 | # For a card with no associated bug, an 'In Progress' branch status |
600 | - # will be in the coding state. |
601 | + # will be in the coding state. |
602 | branch_info = Record(status='In Progress', target=None) |
603 | self.assertEqual( |
604 | - CardStatus.CODING, |
605 | + CardStatus.CODING, |
606 | get_card_status(None, [], branch_info)) |
607 | |
608 | def test_get_card_status_review_no_bug(self): |
609 | # For a card with no associated bug, an 'Approved' or 'In Review' |
610 | - # branch status will be in the review state. |
611 | + # branch status will be in the review state. |
612 | branch_infos = [ |
613 | Record(status='In Review', target=None), |
614 | Record(status='Approved', target=None)] |
615 | for branch_info in branch_infos: |
616 | self.assertEqual( |
617 | - CardStatus.REVIEW, |
618 | + CardStatus.REVIEW, |
619 | get_card_status(None, [], branch_info)) |
620 | |
621 | def test_get_card_status_landing_no_bug(self): |
622 | # For a card with no associated bug, a merged branch status will be in |
623 | - # the landing state. |
624 | + # the landing state. |
625 | branch_info = Record(status='Merged', target=None) |
626 | self.assertEqual( |
627 | - CardStatus.LANDING, |
628 | + CardStatus.LANDING, |
629 | get_card_status(None, [], branch_info)) |
630 | |
631 | def test_get_card_status_coding_in_progress_no_branch(self): |
632 | @@ -888,7 +890,7 @@ |
633 | cards = get_cards_for_feature( |
634 | self.feature_card, self.feature_bug, card_type='Branch') |
635 | self.assertItemsEqual([branch_card], cards) |
636 | - |
637 | + |
638 | |
639 | class FindLaneNextTest(unittest.TestCase): |
640 | |
641 | @@ -980,7 +982,7 @@ |
642 | def test_no_bugs(self): |
643 | # If no bugs are found, no cards are created. |
644 | board = FauxBoard() |
645 | - bug_lane = board.addLane('bugs') |
646 | + board.addLane('bugs') |
647 | project = FauxLaunchpadProject(bug_tasks=[]) |
648 | create_cards_in_project(board, project, 'kanban') |
649 | self.assertEqual([], board.cards) |
650 | @@ -989,7 +991,7 @@ |
651 | # If a new bug is found, a card is created for it, having the |
652 | # bug id, title and description saved. |
653 | board = FauxBoard() |
654 | - bug_lane = board.addLane('bugs') |
655 | + board.addLane('bugs') |
656 | project = FauxLaunchpadProject( |
657 | bug_tasks=[FauxBugTask( |
658 | bug_id=42, title='Test bug', |
659 | @@ -1007,7 +1009,7 @@ |
660 | # After a card is created from a bug, the bug tag is removed, so |
661 | # that having a lot of open bugs won't slow down the process. |
662 | board = FauxBoard() |
663 | - bug_lane = board.addLane('bugs') |
664 | + board.addLane('bugs') |
665 | project = FauxLaunchpadProject( |
666 | bug_tasks=[FauxBugTask( |
667 | bug_id=42, title='Test bug', |
668 | @@ -1038,7 +1040,7 @@ |
669 | # Cards are created only for bugs having the bug tag that is |
670 | # passed in to create_cards_in_project(). |
671 | board = FauxBoard() |
672 | - bug_lane = board.addLane('bugs') |
673 | + board.addLane('bugs') |
674 | project = FauxLaunchpadProject( |
675 | bug_tasks=[FauxBugTask( |
676 | bug_id=21, title='Tagged with other tag', |
677 | @@ -1058,7 +1060,7 @@ |
678 | # It's possible to specify which card type that the created card |
679 | # should have, instead of the default one. |
680 | board = FauxBoard() |
681 | - bug_lane = board.addLane('bugs') |
682 | + board.addLane('bugs') |
683 | project = FauxLaunchpadProject( |
684 | bug_tasks=[FauxBugTask( |
685 | bug_id=42, title='Test bug', |
686 | @@ -1066,7 +1068,8 @@ |
687 | tags=['kanban'])]) |
688 | feature_type = FauxCardType(id=2, name='Feature', is_default=False) |
689 | board.cardtypes[feature_type.id] = feature_type |
690 | - create_cards_in_project(board, project, 'kanban', cardtype_name='Feature') |
691 | + create_cards_in_project( |
692 | + board, project, 'kanban', cardtype_name='Feature') |
693 | [card] = board.cards |
694 | self.assertEqual(feature_type.id, card.type_id) |
695 | self.assertTrue(card.saved) |
696 | @@ -1075,8 +1078,8 @@ |
697 | # It's possible to specify to which lane the card should be |
698 | # added. |
699 | board = FauxBoard() |
700 | - bug_lane = board.addLane('bugs') |
701 | - bug_lane = board.addLane('incoming') |
702 | + board.addLane('bugs') |
703 | + board.addLane('incoming') |
704 | project = FauxLaunchpadProject( |
705 | bug_tasks=[FauxBugTask( |
706 | bug_id=42, title='Test bug', |
707 | @@ -1094,7 +1097,7 @@ |
708 | # Bug descriptions that exceed the 19997 character limit of a |
709 | # kanban card are truncated to 19500 bytes. |
710 | board = FauxBoard() |
711 | - bug_lane = board.addLane('bugs') |
712 | + board.addLane('bugs') |
713 | project = FauxLaunchpadProject( |
714 | bug_tasks=[FauxBugTask( |
715 | bug_id=42, title='Test bug', |
716 | @@ -1185,7 +1188,6 @@ |
717 | parse_groups_config(config)) |
718 | |
719 | |
720 | - |
721 | class LaunchpadUsersForBoardTest(unittest.TestCase): |
722 | |
723 | def setUp(self): |
724 | @@ -1266,12 +1268,12 @@ |
725 | lp_users = LaunchpadUsersForBoard() |
726 | lp_users.set_up_users(lp, board, config) |
727 | self.assertEqual( |
728 | - {"sometag": coding_lane, "anothertag": coding_lane}, |
729 | + {"sometag": coding_lane, "anothertag": coding_lane}, |
730 | lp_users.feature_lanes) |
731 | |
732 | def test_feature_lanes_unset_with_group_new_lanes_and_no_assignee(self): |
733 | # When a feature card is present and tagged and the new_lanes |
734 | - # in the config specifies the ${group} variable, |
735 | + # in the config specifies the ${group} variable, |
736 | # feature_lanes will be unset when there are no assigned users on the |
737 | # card. |
738 | feature_card = FauxCard(tags="sometag") |
739 | @@ -1305,7 +1307,8 @@ |
740 | lp = None |
741 | config = {"groups_config_file": groups_file.name, |
742 | "new_lanes": "dev::${group}::coding"} |
743 | - lp_users = LaunchpadUsersForBoard(kanban_to_lp={1:FauxPerson("User1")}) |
744 | + lp_users = LaunchpadUsersForBoard( |
745 | + kanban_to_lp={1: FauxPerson("User1")}) |
746 | lp_users.set_up_users(lp, board, config) |
747 | self.assertEqual( |
748 | {"squad-group-1": coding_lane, "squad-group-2": coding_lane2}, |
749 | @@ -1313,7 +1316,7 @@ |
750 | |
751 | def test_feature_lanes_set_with_group_new_lanes_and_assignee(self): |
752 | # When a feature card is present and tagged and the new_lanes |
753 | - # in the config specifies the ${group} variable, |
754 | + # in the config specifies the ${group} variable, |
755 | # feature_lanes will be set when there are is an assigned user on the |
756 | # card. |
757 | feature_card = FauxCard(tags="sometag,anothertag") |
758 | @@ -1336,17 +1339,17 @@ |
759 | lp = None |
760 | config = {"groups_config_file": groups_file.name, |
761 | "new_lanes": "dev::${group}::coding"} |
762 | - lp_users = LaunchpadUsersForBoard(kanban_to_lp={1:FauxPerson("User1")}) |
763 | + lp_users = LaunchpadUsersForBoard( |
764 | + kanban_to_lp={1: FauxPerson("User1")}) |
765 | lp_users.set_up_users(lp, board, config) |
766 | self.assertEqual( |
767 | - {"sometag": coding_lane, "anothertag": coding_lane, |
768 | - "squad-group-1": coding_lane, "squad-group-2": coding_lane2}, |
769 | + {"sometag": coding_lane, "anothertag": coding_lane, |
770 | + "squad-group-1": coding_lane, "squad-group-2": coding_lane2}, |
771 | lp_users.feature_lanes) |
772 | |
773 | |
774 | class FauxPerson: |
775 | |
776 | - |
777 | def __init__(self, name): |
778 | self.name = name |
779 | |
780 | @@ -1654,7 +1657,7 @@ |
781 | self.lp_users = FauxLaunchpadUsersForBoard() |
782 | |
783 | def test_sync_cards_moves_landing_cards_to_taskboard_in_landing_lane(self): |
784 | - """ |
785 | + """ |
786 | Feature-linked cards in landing lanes will move to taskboard when the |
787 | feature card is in landing_lanes. |
788 | """ |
789 | @@ -1735,16 +1738,20 @@ |
790 | self.assertEqual((self.feature_card, 'Done'), landed_card2.moved_to) |
791 | |
792 | def test_sync_cards_external_ids_filter_card(self): |
793 | - """filter_card skips and selects correctly.""" |
794 | - # Configure bugs2cards to sync only active-projects myproject1 and myproject2 |
795 | + """filter_card skips and selects correctly.""" |
796 | + # Configure bugs2cards to sync only active-projects myproject1 |
797 | + # and myproject2 |
798 | self.bconf.update({ |
799 | "autosync": "active-projects", |
800 | "projects": "myproject", |
801 | "sync_cards": "on", "move_cards": "on", |
802 | "new_lanes": "new"}) |
803 | - # Setup bug1 and bug2 in separate projects which both need to move coding -> new |
804 | - project1 = FauxTarget(resource_type_link="project", project="myproject") |
805 | - lp_users = FauxLaunchpadUsersForBoard(lp_to_kanban={"person1": "Person One"}) |
806 | + # Setup bug1 and bug2 in separate projects which both need to |
807 | + # move coding -> new |
808 | + project1 = FauxTarget( |
809 | + resource_type_link="project", project="myproject") |
810 | + lp_users = FauxLaunchpadUsersForBoard( |
811 | + lp_to_kanban={"person1": "Person One"}) |
812 | lp_projects = [project1] |
813 | bug_task1 = FauxBugTask( |
814 | bug_id=123, target=project1, title='Test bug in myproject', |
815 | @@ -1766,25 +1773,31 @@ |
816 | bug_card1.type = bug_type |
817 | bug_card2.type = bug_type |
818 | self.board.cards.extend([bug_card1, bug_card2]) |
819 | - lp = FauxLP({"projects": {"myproject": project1}, |
820 | - "bugs": {123: bug_task1.bug, 456: bug_task2.bug}}) |
821 | + lp = FauxLP({ |
822 | + "projects": {"myproject": project1}, |
823 | + "bugs": {123: bug_task1.bug, 456: bug_task2.bug}}) |
824 | sync_cards_external_ids( |
825 | - board, self.bconf, lp, lp_users, lp_projects, filter_card=bug_card2.id) |
826 | + board, self.bconf, lp, lp_users, |
827 | + lp_projects, filter_card=bug_card2.id) |
828 | coding_lane = FauxLane(board=board, path='coding') |
829 | self.assertEqual(new_lane, bug_card2.moved_to) |
830 | self.assertIsNone(bug_card1.moved_to) |
831 | |
832 | def test_sync_cards_skips_bugs_not_in_filter_bug(self): |
833 | - """filter_bug skips and selects bugs in sync_cards_external_ids.""" |
834 | - # Configure bugs2cards to sync only active-projects myproject1 and myproject2 |
835 | + """filter_bug skips and selects bugs in sync_cards_external_ids.""" |
836 | + # Configure bugs2cards to sync only active-projects myproject1 |
837 | + # and myproject2 |
838 | self.bconf.update({ |
839 | "autosync": "active-projects", |
840 | "projects": "myproject", |
841 | "sync_cards": "on", "move_cards": "on", |
842 | "new_lanes": "new"}) |
843 | - # Setup bug1 and bug2 in separate projects which both need to move coding -> new |
844 | - project1 = FauxTarget(resource_type_link="project", project="myproject") |
845 | - lp_users = FauxLaunchpadUsersForBoard(lp_to_kanban={"person1": "Person One"}) |
846 | + # Setup bug1 and bug2 in separate projects which both need |
847 | + # to move coding -> new |
848 | + project1 = FauxTarget( |
849 | + resource_type_link="project", project="myproject") |
850 | + lp_users = FauxLaunchpadUsersForBoard( |
851 | + lp_to_kanban={"person1": "Person One"}) |
852 | lp_projects = [project1] |
853 | bug_task1 = FauxBugTask( |
854 | bug_id=123, target=project1, title='Test bug in myproject', |
855 | @@ -1806,26 +1819,34 @@ |
856 | bug_card1.type = bug_type |
857 | bug_card2.type = bug_type |
858 | self.board.cards.extend([bug_card1, bug_card2]) |
859 | - lp = FauxLP({"projects": {"myproject": project1}, |
860 | - "bugs": {123: bug_task1.bug, 456: bug_task2.bug}}) |
861 | + lp = FauxLP({ |
862 | + "projects": {"myproject": project1}, |
863 | + "bugs": {123: bug_task1.bug, 456: bug_task2.bug}}) |
864 | sync_cards_external_ids( |
865 | board, self.bconf, lp, lp_users, lp_projects, filter_bug=u"456") |
866 | coding_lane = FauxLane(board=board, path='coding') |
867 | self.assertEqual(new_lane, bug_card2.moved_to) |
868 | self.assertIsNone(bug_card1.moved_to) |
869 | |
870 | - def test_sync_cards_skips_bugs_of_external_projects_when_active_projects_set(self): |
871 | - """Bugs of external projects are skipped when autosync set to active-projects.""" |
872 | - # Configure bugs2cards to sync only active-projects myproject1 and myproject2 |
873 | + def test_sync_cards_skips_bugs_of_external_projects_active_projects(self): |
874 | + """Bugs of external projects are skipped when autosync set to |
875 | + active-projects.""" |
876 | + # Configure bugs2cards to sync only active-projects myproject1 |
877 | + # and myproject2 |
878 | self.bconf.update({"autosync": "active-projects", |
879 | "projects": "myproject,myproject2", |
880 | "sync_cards": "on", "move_cards": "on", |
881 | "new_lanes": "new"}) |
882 | - # Setup bug1 and bug2 in separate projects which both need to move coding -> new |
883 | - project1 = FauxTarget(resource_type_link="project", project="myproject") |
884 | - project2 = FauxTarget(resource_type_link="project2", project="myproject2") |
885 | - otherproject = FauxTarget(resource_type_link="project", project="otherproject") |
886 | - lp_users = FauxLaunchpadUsersForBoard(lp_to_kanban={"person1": "Person One"}) |
887 | + # Setup bug1 and bug2 in separate projects which both need to move |
888 | + # coding -> new |
889 | + project1 = FauxTarget( |
890 | + resource_type_link="project", project="myproject") |
891 | + project2 = FauxTarget( |
892 | + resource_type_link="project2", project="myproject2") |
893 | + otherproject = FauxTarget( |
894 | + resource_type_link="project", project="otherproject") |
895 | + lp_users = FauxLaunchpadUsersForBoard( |
896 | + lp_to_kanban={"person1": "Person One"}) |
897 | lp_projects = [project1, project2] |
898 | bug_task1 = FauxBugTask( |
899 | bug_id=123, target=project1, title='Test bug in myproject', |
900 | @@ -1848,8 +1869,9 @@ |
901 | bug_card2.type = bug_type |
902 | self.board.cards.extend([bug_card1, bug_card2]) |
903 | # Include project1 and project2 in our active 'projects' fake LP data |
904 | - lp = FauxLP({"projects": {"myproject": project1, "myproject2": project2}, |
905 | - "bugs": {123: bug_task1.bug, 456: bug_task2.bug}}) |
906 | + lp = FauxLP({ |
907 | + "projects": {"myproject": project1, "myproject2": project2}, |
908 | + "bugs": {123: bug_task1.bug, 456: bug_task2.bug}}) |
909 | sync_cards_external_ids(board, self.bconf, lp, lp_users, lp_projects) |
910 | coding_lane = FauxLane(board=board, path='coding') |
911 | self.assertEqual(new_lane, bug_card1.moved_to) |
912 | |
913 | === modified file 'src/lp2kanban/tests/test_cards2workitems.py' |
914 | --- src/lp2kanban/tests/test_cards2workitems.py 2013-03-19 16:06:09 +0000 |
915 | +++ src/lp2kanban/tests/test_cards2workitems.py 2016-09-08 22:02:56 +0000 |
916 | @@ -1,5 +1,4 @@ |
917 | # Copyright 2012 Canonical Ltd. |
918 | -__metaclass__ = type |
919 | |
920 | import re |
921 | import testtools |
922 | @@ -27,6 +26,8 @@ |
923 | from testtools.monkey import patch |
924 | from textwrap import dedent |
925 | |
926 | +__metaclass__ = type |
927 | + |
928 | |
929 | class CardsToWorkItemsBase(testtools.TestCase): |
930 | |
931 | @@ -56,9 +57,9 @@ |
932 | "String \"{string}\" did not match pattern \"{pattern}\"".format( |
933 | string=string, pattern=pattern)) |
934 | |
935 | - def _generateCard(self, board=None, lane=None, |
936 | - description_annotations=None, assigned_user_id=0, |
937 | - title=None, external_system_url=None): |
938 | + def _generateCard( |
939 | + self, board=None, lane=None, description_annotations=None, |
940 | + assigned_user_id=0, title=None, external_system_url=None): |
941 | if board is None: |
942 | board = self.board |
943 | if lane is None: |
944 | @@ -220,7 +221,8 @@ |
945 | work_item = convert_card_to_work_item( |
946 | card, self.board, self.lp_users_for_board) |
947 | self.assertEqual( |
948 | - card.description_annotations.blueprint_url, work_item.blueprint_url) |
949 | + card.description_annotations.blueprint_url, |
950 | + work_item.blueprint_url) |
951 | |
952 | def test_blueprint_extracted_from_card_external_link(self): |
953 | # Cards can also be linked to blueprints by putting the |
954 | @@ -233,7 +235,7 @@ |
955 | external_system_url=self.blueprint_url, |
956 | description_annotations=Record(), |
957 | ) |
958 | - work_item = convert_card_to_work_item( |
959 | + convert_card_to_work_item( |
960 | card, self.board, self.lp_users_for_board) |
961 | self.assertEqual( |
962 | self.blueprint_url, card.description_annotations.blueprint_url) |
963 | @@ -243,8 +245,8 @@ |
964 | # isn't a blueprint, convert_card_to_work_item() will return |
965 | # None. |
966 | card = self._generateCard( |
967 | - description_annotations=Record |
968 | - (blueprint_url= 'https://nyancat.com')) |
969 | + description_annotations=Record( |
970 | + blueprint_url='https://nyancat.com')) |
971 | work_item = convert_card_to_work_item( |
972 | card, self.board, self.lp_users_for_board) |
973 | self.assertIsNone(work_item) |
974 | @@ -268,8 +270,8 @@ |
975 | self._generateCard( |
976 | title="Card %i" % id, |
977 | description_annotations=Record( |
978 | - blueprint_url=blueprint_url_tpl % id)) |
979 | - for id in range(3)] |
980 | + blueprint_url=blueprint_url_tpl % id |
981 | + )) for id in range(3)] |
982 | self.work_items = convert_cards_to_work_items( |
983 | self.cards, self.board, self.lp_users_for_board) |
984 | self.blueprints = {} |
985 | @@ -283,6 +285,7 @@ |
986 | # We stub out the Launchpad interaction using a fake version of |
987 | # fetch_blueprint() |
988 | called_with_urls = [] |
989 | + |
990 | def fake_fetch_blueprint(lp, url): |
991 | called_with_urls.append(url) |
992 | return FauxBlueprint(name="somename") |
993 | |
994 | === modified file 'src/lp2kanban/tests/test_description_annotations.py' |
995 | --- src/lp2kanban/tests/test_description_annotations.py 2013-03-18 13:25:36 +0000 |
996 | +++ src/lp2kanban/tests/test_description_annotations.py 2016-09-08 22:02:56 +0000 |
997 | @@ -9,6 +9,7 @@ |
998 | from textwrap import dedent |
999 | import unittest |
1000 | |
1001 | + |
1002 | class DescriptionAnnotationsTest(unittest.TestCase): |
1003 | """Tests for kanban.LeankitCard description annotations.""" |
1004 | |
1005 | @@ -16,7 +17,7 @@ |
1006 | # parse_card_description() parses key:value pairs out of a |
1007 | # card's description and returns them as a dict. |
1008 | card = LeankitCard.create(FauxLane("Test")) |
1009 | - card.title=u"some card" |
1010 | + card.title = u"some card" |
1011 | card.description = dedent(""" |
1012 | {"key2": "value2", "key1": "value 1"} |
1013 | """) |
1014 | @@ -28,7 +29,7 @@ |
1015 | # Any text not in the key=value form is returned unparsed by |
1016 | # card.parsed_description(). |
1017 | card = LeankitCard.create(FauxLane("Test")) |
1018 | - card.title=u"some card" |
1019 | + card.title = u"some card" |
1020 | card.description = dedent(""" |
1021 | Some other text, |
1022 | {"key2": "value2", "key1": "value 1"} |
1023 | @@ -44,7 +45,7 @@ |
1024 | # LeankitCard.description_annotations returns only the key=value |
1025 | # pairs from the description field. |
1026 | card = LeankitCard.create(FauxLane("Test")) |
1027 | - card.title=u"some card" |
1028 | + card.title = u"some card" |
1029 | card.description = dedent(""" |
1030 | {"key2": "value2", "key1": "value 1"} |
1031 | Here's a URL: http://test.com?a=b |
1032 | @@ -57,7 +58,7 @@ |
1033 | # LeankitCard._setDescriptionAnnotations() can be used to write |
1034 | # new annotations to the description field. |
1035 | card = LeankitCard.create(FauxLane("Test")) |
1036 | - card.title=u"some card" |
1037 | + card.title = u"some card" |
1038 | card.description = dedent(""" |
1039 | Some text |
1040 | {"key2": "value2", "key1": "value 1"} |
1041 | @@ -73,7 +74,7 @@ |
1042 | # LeankitCard.description_annotations is a Record, so it hass |
1043 | # attribute access for its values. |
1044 | card = LeankitCard.create(FauxLane("Test")) |
1045 | - card.title=u"some card" |
1046 | + card.title = u"some card" |
1047 | card.description = '{"key1": "value 1"}' |
1048 | self.assertIsInstance(card.description_annotations, Record) |
1049 | self.assertEqual("value 1", card.description_annotations.key1) |
1050 | |
1051 | === modified file 'src/lp2kanban/workitems2cards.py' |
1052 | --- src/lp2kanban/workitems2cards.py 2013-03-18 13:42:24 +0000 |
1053 | +++ src/lp2kanban/workitems2cards.py 2016-09-08 22:02:56 +0000 |
1054 | @@ -66,8 +66,8 @@ |
1055 | assigned_user_id = assigned_user.id |
1056 | else: |
1057 | assigned_user_id = 0 |
1058 | - print "Creating card {title} [{assignee}]".format( |
1059 | - title=work_item.text, assignee=assigned_user_id) |
1060 | + print(u"Creating card {title} [{assignee}]".format( |
1061 | + title=work_item.text, assignee=assigned_user_id)) |
1062 | card = lane.addCard() |
1063 | card.title = work_item.text |
1064 | card.description_annotations.blueprint_url = work_item.blueprint |
1065 | @@ -90,15 +90,15 @@ |
1066 | |
1067 | match = re.match(BLUEPRINT_URL_PATTERN, args.spec_url) |
1068 | if match is None: |
1069 | - print "Spec URL is not a Launchpad blueprint." |
1070 | + print("Spec URL is not a Launchpad blueprint.") |
1071 | sys.exit(1) |
1072 | |
1073 | if not args.dry_run: |
1074 | - should_continue = raw_input( |
1075 | + should_continue = raw_input( # noqa |
1076 | "WARNING: This script is not well-tested and will mess with " |
1077 | "your Kanban board; use it at your own risk. Continue? [y/N] ") |
1078 | if should_continue.lower() != "y": |
1079 | - print "Exiting." |
1080 | + print("Exiting.") |
1081 | sys.exit(0) |
1082 | |
1083 | match_dict = match.groupdict() |
1084 | @@ -115,17 +115,17 @@ |
1085 | sys.exit(1) |
1086 | work_items = parse_work_items(lp, **match_dict) |
1087 | if not args.dry_run: |
1088 | - should_continue = raw_input( |
1089 | + should_continue = raw_input( # noqa |
1090 | "{count} cards will be created, whether or not you want them all. " |
1091 | "Continue [y/N]?".format(count=len(work_items))) |
1092 | if args.dry_run or should_continue.lower() == "y": |
1093 | - print "Creating cards from work items in lane {lane}.".format( |
1094 | - lane=args.target_lane) |
1095 | + print(u"Creating cards from work items in lane {lane}.".format( |
1096 | + lane=args.target_lane)) |
1097 | cards = work_items_to_cards( |
1098 | work_items, board, lane, lp_users, dry_run=args.dry_run) |
1099 | - print "{count} cards created".format(count=len(cards)) |
1100 | + print(u"{count} cards created").format(count=len(cards)) |
1101 | else: |
1102 | - print "Aborting." |
1103 | + print(u"Aborting.") |
1104 | |
1105 | if __name__ == '__main__': |
1106 | main(sys.argv) |
Command: http_proxy= $CI_PROXY https_proxy= $CI_PROXY make ci-test /ci.lscape. net/job/ latch-test/ 10190/
Result: Success
Revno: 178
Branch: lp:~davidpbritton/lp2kanban/lint-1
Jenkins: https:/