def __main__(): parser = argparse.ArgumentParser( description=u"Check CoreJet report against PivotalTracker") parser.add_argument( "sections", nargs="?", help=(u"comma separated list of pivotal.cfg section names to " u"retrieve epics from")) parser.add_argument( "--token", help=u"default pivotal token to use to authenticate") parser.add_argument( "--project", help=u"default pivotal project id to retrieve stories from") parser.add_argument( metavar="corejet.xml", dest="filename", nargs="?", default="parts/test/corejet/corejet.xml", help=(u"path to CoreJet test report " u"(defaults to parts/test/corejet/corejet.xml)")) args = parser.parse_args() defaults = { "project": args.project, "token": args.token } defaults = config.read("defaults", defaults) sections = None if args.sections: sections = [name.strip() for name in args.sections.split(",")] if not sections and "epics" in defaults: sections = [name.strip() for name in defaults["epics"].split(",")] epics = {} if sections: for section in sections: epics[section] = config.read(section, defaults) if None in defaults.values(): parser = argparse.ArgumentParser( description=u"Check CoreJet report against PivotalTracker") parser.add_argument( "--token", required=True, help=u"pivotal token to use to authenticate") parser.add_argument( "--project", required=True, help=u"pivotal project id to retrieve stories from") parser.add_argument( metavar="parts/test/corejet/corejet.xml", dest="filename", help=u"path to CoreJet test report") args = parser.parse_args() corejet_etree = etree.fromstring(open(args.filename).read()) if not sections: for epic in corejet_etree.findall("epic"): doPivotal(defaults, epic) for epic in epics: doPivotal(epics[epic], corejet_etree.find("epic[@id='%s']" % epic))
def pivotalSource(details): """Produce a CoreJet XML file with stories for epics from Pivotal. The parameter should be a comma-separated string with the following parameters: <epic>,<epic>,... - optional cfg section names to retrieve options per epic token=<token> - default pivotal token to use in authentication project=<project> - default pivotal project id to retrieve stories from filter=<filter> - default pivotal filter string to retrieve stories title=<title> - optional title for the requirements catalog (defaults to the first found pivotal project title) """ sections = [] defaults = {} for option in details.split(","): try: key, value = option.split("=", 1) except ValueError: # values without keys are interpreted as cfg-sections value = option.strip() if value: sections.append(value) continue defaults[key.strip().lower()] = value.strip() defaults = config.read("defaults", defaults) if not sections and "epics" in defaults: sections = [name.strip() for name in defaults["epics"].split(",")] if not sections: sections = ["defaults"] epics = [] for section in sections: options = config.read(section, defaults) assert options.get("token", False),\ u"Pivotal token is a mandatory option." assert options.get("project", False),\ u"Pivotal project id is a mandatory option." assert options.get("filter", False),\ u"Pivotal filter string is a mandatory option." # append filter from command line (when found) if defaults.get("filter", "") not in options["filter"]: options["filter"] += " %s" % defaults["filter"] # set includedone:true if it's not explicitly set otherwise if not "includedone:" in options["filter"]: options["filter"] += " includedone:true" try: pv = pivotal.Pivotal(options["token"], use_https=True) except TypeError: # Support HTTPS on pivotal_py == 0.1.3 pivotal.BASE_URL = "https://www.pivotaltracker.com/services/v3/" pv = pivotal.Pivotal(options["token"]) project = pv.projects(options["project"]) project_etree = project.get_etree() project_title =\ options.get("title", project_etree.findtext("name")) if not type(project_title) == unicode: # ensure unicode project_title = unicode(project_title, "utf-8", "ignore") if not "title" in defaults: defaults["title"] = project_title epic_title = options.get("title", project_title) if not type(epic_title) == unicode: # ensure unicode epic_title = unicode(epic_title, "utf-8", "ignore") epic = Epic(name=section != "defaults" and section or str(sections.index(section) + 1), title=epic_title) stories = project.stories(filter=options["filter"]) stories_etree = stories.get_etree() for node in stories_etree: story = Story(node.findtext("id"), node.findtext("name")) story.status = node.findtext("current_state") if story.status in ["accepted", "rejected"]: story.resolution = story.status story.points = max(1, int(node.findtext("estimate", 0) or 0)) appendScenariosFromPivotalStory(story, node, options) if story.scenarios: epic.stories.append(story) epics.append(epic) catalogue = RequirementsCatalogue(project=defaults["title"], extractTime=datetime.now()) for epic in epics: catalogue.epics.append(epic) return catalogue