def projectFailTest(): gitConnection = GitConnect() gitConnection.checkForUnsavedChanges() reasons = {"0":"Failed a unit test.","1":"Failed a UI test"} for reason in reasons.keys(): print reason," ",reasons[reason] print "Or just type why it failed." reason = raw_input() if reason in reasons.keys(): reason = reasons[reason] purgatory = False else: purgatory = True caseno = gitConnection.extractCaseFromBranch() gitConnection.pushChangesToOriginBranch(gitConnection.getBranch()) gitConnection.checkoutMaster() fbConnection = FogBugzConnect() (parent,test) = fbConnection.getCaseTuple(caseno) if purgatory: fbConnection.commentOn(parent,PURGATORY_STMT) #this signals buildbot to fail the case back to the implementer after PURGATORY expires #buildbot special-cases Inspect passes to be in PURGATORY, so no signaling is required for the pass case fbConnection.fbConnection.assign(ixBug=parent,ixPersonAssignedTo=magic.BUILDBOT_IXPERSON,sEvent="Terribly sorry but your case FAILED a test: %s" % reason) fbConnection.stopWork(test) # play sounds! getstatusoutput ("afplay -v 7 %s/media/dundundun.aiff" % sys.prefix)
def recharge(fr,to): import dateutil.parser fbConnection = FogBugzConnect() fbConnection.setParentIfUnset(fr,to) #cannot create a time record for a closed case... mustOpen = not fbConnection.isOpen(to) if mustOpen: fbConnection.reopen(to,"work.py recharge") results = fbConnection.listTimeRecords(fr) time_interval = 0 my_records = [] for record in results: #print record if record.fdeleted.contents[0]!="false": juche.warn("Skipping deleted record %s" % record) continue if len(record.dtend)==0: juche.warn("Skipping open time record %s" % record) continue my_records.append(record) r = 0 for record in my_records: juche.info("%d: %s-%s" % (r,record.dtstart.contents[0],record.dtend.contents[0])) r += 1 def parse_range(astr): # http://stackoverflow.com/questions/4726168/parsing-command-line-input-for-numbers result=set() for part in astr.split(','): x=part.split('-') result.update(range(int(x[0]),int(x[-1])+1)) return sorted(result) strl = raw_input("records (syntax like 22-27,51-64): ") results = parse_range(strl) for result in results: record = my_records[result] record_desc = "From %s to %s ixPerson %s ixBug %s" % (record.dtstart.contents[0],record.dtend.contents[0],record.ixperson.contents[0],record.ixbug.contents[0]) from_time = dateutil.parser.parse(record.dtstart.contents[0]) to_time = dateutil.parser.parse(record.dtend.contents[0]) time_interval += (to_time-from_time).total_seconds() juche.info("from_time %s to_time %s time_interval %s" % (from_time,to_time,time_interval)) fbConnection.commentOn(fr,"recharge: A record was removed from this ticket: %s, see case %d" % (record_desc,to)) fbConnection.commentOn(to,"recharge: A record was added to this ticket: %s, see case %d" % (record_desc, fr)) fbConnection.createTimeRecord(to,str(record.dtstart.contents[0]),str(record.dtend.contents[0])) oldEst = fbConnection.getEstimate(fr) * 60.0 * 60.0 newEst = (oldEst - time_interval) / 60.0 / 60.0 if newEst <= 0: newEst = 1/60.0 juche.info("Setting estimate to",newEst) fbConnection.setEstimate(fr,timespan="%f hours" % newEst) #fbConnection.deleteTimeRecord(record.ixinterval.contents[0]) if mustOpen: fbConnection.closeCase(to)
def projectIntegrate(CASE_NO,defaultgitConnection=GitConnect()): if not defaultgitConnection: interactive = True else: interactive = False gitConnection = defaultgitConnection gitConnection.checkForUnsavedChanges() #see referencing note on line 369 fbConnection = FogBugzConnect() #still open here # make sure integration is even worth it... fbConnection.ensureReadyForTest(CASE_NO) gitConnection.checkoutExistingBranch(CASE_NO) integrate_to = fbConnection.getIntegrationBranch(CASE_NO) gitConnection.checkoutExistingBranchRaw(integrate_to) gitConnection.resetHard_INCREDIBLY_DESTRUCTIVE_COMMAND() #this is safe because we check for unsafe changes on line 357. gitHubConnection = GitHubConnect(gitConnect=gitConnection) gitHubConnection.closePullRequestbyName("work-%d" % CASE_NO) #check for test case try: (parent, test) = fbConnection.getCaseTuple(CASE_NO,oldTestCasesOK=True) except: if interactive: juche.warn("no test case! Press enter to continue") raw_input() if not interactive: if not gitConnection.mergeIn("work-%d" % CASE_NO,pretend=True): return False gitConnection.mergeIn("work-%d" % CASE_NO) fbConnection.commentOn(CASE_NO,"Merged into %s" % integrate_to) fbConnection.closeCase(CASE_NO) if not interactive: gitConnection.pushChangesToOriginBranch(branch=integrate_to) return True
def complain(ixComplainAboutPerson,sComplainAboutProject): fbConnection = FogBugzConnect() response = fbConnection.fbConnection.search(q="status:active assignedto:=%d project:%s" % (ixComplainAboutPerson,sComplainAboutProject),cols="hrsCurrEst,hrsElapsed,sPersonAssignedTo,sFixFor,sCategory") for case in response.cases: #print case if case.hrscurrest.contents[0]=="0": juche.info("%s's case %s has no estimate" % (case.spersonassignedto.contents[0], case["ixbug"])) fbConnection.commentOn(case["ixbug"],"This next test could take a very, VERY long time.") if case.sfixfor.contents[0]=="Undecided" and (case.scategory.contents[0] == "bug" or case.scategory.contents[0] == "feature"): juche.info("%s needs a milestone" % case["ixbug"]) fbConnection.commentOn(case["ixbug"],"If you choose not to decide, you still have made a choice. (Don't think about it, don't think about it...) It's a paradox! There IS no answer.") est = float(case.hrscurrest.contents[0]) act = float(case.hrselapsed.contents[0]) if est - act < 0: juche.info("%s's case %s requires updated estimate" % (case.spersonassignedto.contents[0], case["ixbug"])) fbConnection.commentOn(case["ixbug"],"I'll give you credit: I guess you ARE listening to me. But for the record: You don't have to go THAT slowly.")
def projectShip(): if lint_loaded: try: result = lint.Lint.analyze() except Exception as e: juche.exception(e) print "Lint sunk the ship, but we still have a liferaft!" else: if not result: while True: cont = raw_input("Your code failed lint analyses. Continue anyway? (Y/n)") if cont == "n": exit() if cont == "Y": break #create new gitConnect object to talk to git gitConnection = GitConnect() gitConnection.checkForUnsavedChanges(); #create new FogBugzConnect object to talk to FBAPI fbConnection = FogBugzConnect() #check if we're in a git repo branch = gitConnection.getBranch(); # check if branch is the right branch caseno = gitConnection.extractCaseFromBranch() gitConnection.pushChangesToOriginBranch(branch) gitConnection.checkoutMaster() #create the pull request gitHubConnect = GitHubConnect() if not gitHubConnect.pullRequestAlreadyExists("work-%d" % caseno): body = "Ticket at %s/default.asp?%d\n%s" % (fbConnection.getFBURL(),caseno,raw_input("Type a note: ")) list = gitConnection.getUserRepo() integrationBranch = fbConnection.getIntegrationBranch(caseno) if integrationBranch=="Undecided": raise Exception("Come on now, you've implemented the ticket before you decided what mielstone it was? You have to decide!") pullURL = gitHubConnect.createPullRequest("work-%d" % caseno,body,integrationBranch,"work-%d" % caseno) fbConnection.commentOn(caseno,"Pull request at %s\n%s" %(pullURL,body)) #is there a test case? try: (parent,child) = fbConnection.getCaseTuple(caseno) fbConnection.resolveCase(caseno,isTestCase_CASENO=child) except: fbConnection.resolveCase(caseno) pass print """There's about an 80% chance that whatever you just did was work that rightfully belongs to some other (possibly closed) case. Recharging is a way to signify to EBS that your work should be counted against a different case. Ex 1: You're fixing a somewhat-forseeable bug in a feature that was implemented and estimated in another case, but for some reason a new bug has been filed instead of the old feature reactivated. Recharge to the original feature, as whoever estimated that should have accounted for a relatively bug-free implementation. Ex 2: You're implementing a feature that was originally estimated in some other case. Maybe it was a parent case that was broken down into child cases, or maybe somebody carved out a feature of a larger something for you to implement. When there are multiple candidates for a recharge, use your judgment. Pick the newer case where reasonable. DO NOT RECHARGE 1) Things that are legitimately and substantially new features 2) Test cases, inquiries, or fake tickets 3) Build feedback / ship tickets """ print "recharge to: (case#)", TO_CASE = raw_input() if TO_CASE: to = int(TO_CASE) recharge(caseno,to)