Exemple #1
0
    def checkoutBranch(self, CASE_NO, fromSpec,fbConnection):


        # get output from git branch command
        (branchStatus, branchOutput) = self.statusOutput("git branch")

        #fetch git repo information
        self.fetch()

        # check if a branch for CASE_NO exists
        # if it does, check it out
        if self.__checkoutExistingBranch(CASE_NO):
            if fromSpec:
                juche.warn("Ignoring your fromspec.  To override, re-try with after a git checkout master && git branch -D work-%d && git push origin :work-%d" %(CASE_NO,CASE_NO))
                juche.warn("THIS DESTRUCTIVE COMMAND DELETES ANY WORK ON work-%d, USE WITH CAUTION!" % CASE_NO)
            self.pull()
            return

        # if a branch does not exist, create one and check it out
        else:
            if not fromSpec:
                #try to fill automatically from FB
                fromSpec = fbConnection.getIntegrationBranch(CASE_NO)
            self.createNewWorkBranch(CASE_NO, fromSpec)
            return
Exemple #2
0
 def checkForUnsavedChanges(self):
     output = self.checkForRepository()
     #if "git status" returns an error..."
     if self.statusOutput("git status --porcelain")[1]:
         juche.warn("changes have been made to source code!")
         juche.warn("         use git stash or git commit to save changes")
         raise Exception("stacktraceplease")
     else:
         return
Exemple #3
0
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)
Exemple #4
0
def workConfig(settingString):
    ALLOWED_SETTINGS = ["viewOnStart"]
    if len(settingString.split("=")) < 2:
        printUsageString()
        raise Exception("stacktraceplease")

    setting = settingString.split("=")[0]
    value = settingString.split("=")[1]
    if setting and value:
        fbConnection = FogBugzConnect()
        settings = fbConnection.getCredentials()
        if(not setting in ALLOWED_SETTINGS):
            juche.warn("setting not known. Will be added anyway.")
        fbConnection.setSetting(setting, value)
    else:
        printUsageString()
        raise Exception("stacktraceplease")
Exemple #5
0
    def exec_tests(self,proj):
        import subprocess
        import shlex
        shortdesc = ""
        files = {}
        passed = True
        #WARNING:  YOU MUST PATCH $DEVELOPER/Platforms/iPhoneSimulator.platform/Developer/Tools/RunPlatformUnitTests for this to work.
        #See http://longweekendmobile.com/2011/04/17/xcode4-running-application-tests-from-the-command-line-in-ios/
        if proj["tests"]:
            juche.dictate(project=proj)

            for test in proj["tests"]:
                juche.dictate(running_test=test)

                juche.info("running test")
                r = subprocess.Popen(test["cmd"],shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE,cwd=WORK_DIR+proj["name"])
                (status,output) = self.wait_for(r)
                if status and test["type"]!="kif": #kif tests always return a status code of 1
                    shortdesc += "Failing in part because test %s returned a non-zero return code %d\n" % (test,status)
                    passed = False
                if test["type"]=="xcode":
                    (passed,shortdesc,files) = self.parse_xcodelike_response(passed,shortdesc,files,output,test["name"]+".log")
                elif test["type"]=="python":
                    (passed,shortdesc,files) = self.parse_python_response(passed,shortdesc,files,output,test["name"]+".log",status)
                elif test["type"]=="kif":
                    (passed,shortdesc,files) = self.parse_kif_response(passed,shortdesc,files,output,test["name"]+".log")
                else:
                    raise Exception("Unknown test type.")
                if passed:
                    if "commit-files" in test:
                        upload_files = test["commit-files"]
                        juche.dictate(upload_files=upload_files)

                        juche.info("commit-files")
                        git = GitConnect(wd=WORK_DIR+proj["name"])
                        git.add(upload_files)
                        try:
                            git.commit("If the subject survived the test, we let them purchase the pictures for $5.  If the subject died, we gave the photo to their next of kin free of charge")
                            git.pushChangesToOriginBranch()
                        except Exception as e:
                            juche.exception(e)
                            juche.warn("Was not able to upload the files successfully.  Perhaps they have not changed?")



        return (passed,shortdesc,files)
Exemple #6
0
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
Exemple #7
0
def _fixFors_test_quickly_dates(abbreviatedTest=False):
    juche.dictate(fixing_test_milestones=1)
    fbConnection = FogBugzConnect()
    fixfors_raw = fbConnection.listFixFors()
    fixfors = fbConnection.dependencyOrder(fixfors_raw)
    from dateutil.parser import parse
    import datetime
    if abbreviatedTest:
        fixfors = fixfors[:5]
    for testMilestone in fixfors:

        testMilestone_raw = fbConnection.fixForDetail(testMilestone)
        testName = fbConnection.nameForFixFor(testMilestone_raw)
        if testName.startswith("Never"): continue
        juche.dictate(testMilestone=testMilestone,testName=testName)
        if not testName.endswith("-test"): continue
        if testName=="Undecided-test": continue
        matched = False
        if testMilestone_raw.ixproject.contents==[]: continue
        for item in fbConnection.listFixFors(ixProject=int(testMilestone_raw.ixproject.contents[0])):
            #print testName[:-5],fbConnection.nameForFixFor(item)
            if item.sfixfor.contents[0]==testName[:-5]:
                #print "matching",testName,fbConnection.nameForFixFor(item)
                matched = True
                break
        if not matched:
            juche.info(testMilestone_raw)
            raise Exception("Cannot match "+testName)
        if item.dt.contents==[]:
            juche.info("Can't set %s because the non-test milestone has no completion date." % testName)
            continue
        date = item.dt.contents[0]
        newDate = parse(date)+datetime.timedelta(hours=6) #turns out that using 1 day produces weird results.  If the next implementation milestone is completed within 24 hours, lots of weird things can happen
        juche.info("setting %s to %s"% (testName,newDate))
        if not abbreviatedTest:
            fbConnection.editFixForShipDate(testMilestone,newDate)
        #It's bad to leave EBS in a partially-edited state.  Therefore we simply log the output and don't actually write any changes when in abbreviated test mode.
        else:
            juche.warn("Not editing the ship date in %s to %s because this is an abbreviated test." % (testMilestone,newDate))
Exemple #8
0
    def pull(self):
        self.checkForRepository()
        import ConfigParser
        c = ConfigParser.ConfigParser()
        if self.wd:
            path = self.wd + "/.git/config"
        else:
            path =".git/config"
        import os
        for i in range(0,30):
            if os.path.exists(path): break
            path = "../" + path
            if i==30:
                raise Exception("Not a git repository?")

        file = open(path)
        str = file.read()
        file.close()

        juche.dictate(pull=1)
        if self.getBranch() not in str:
            juche.warn( "%s is not a tracking branch. Attempting to fix..." % self.getBranch())
            try:
                self.setUpstream(self.getBranch(),"remotes/origin/{0}".format(self.getBranch()))
                juche.info("Success!")
            except:
                juche.error("DID NOT AUTOMATICALLY FIX BRANCH UPSTREAM / TRACKING.  PLEASE FILE A BUG.")

            (status,output) = self.statusOutput("git pull origin %s" % self.getBranch())
            if status:
                juche.error("Cannot pull! %s" % output)
        else:
            (status,output) = self.statusOutput("git pull")
            if status:
                juche.error("ERROR:  Cannot pull! %s" % output)
                raise Exception("stacktraceplease")
        self.submoduleUpdate()
        juche.info("Success!")
Exemple #9
0
 def setUp(self):
     juche.warn("Unit test begin")
     self.a = Atlas()
     self.a.fetch_all(deploy=False)
     pass