Beispiel #1
0
def _do_cmdline(args):
    original_dir = os.getcwd()
    dry_run = False

    # TODO: allow switches after args.
    while args:
        word = args[0]
        if word in ('-h', '--help', '-?'):
            print __doc__
            return
        elif word in ('--dry-run', '-n'):
            dry_run = True
        elif word[0] == '-':
            raise GiveUp, "Unexpected command line option %s"%word
        else:
            break
        args = args[1:]

    if len(args) != 1:
        raise GiveUp, "Incorrect non-option argument count (expected 1, the email destination)"

    email_dest = args[0]

    builder = find_and_load(original_dir, muddle_binary=None)
    # Don't bother determining muddle_binary: our invocation of find_and_load
    # doesn't make use of it. (Tibs writes: it's only needed for when
    # running makefiles, for when they use $(MUDDLE).)

    if not builder:
        raise GiveUp("Cannot find a build tree.")

    rootrepo = builder.db.RootRepository_pathfile.get()

    repo = parse_repo_url(rootrepo)

    rules = builder.all_checkout_rules()
    dirs = []
    for r in rules:
        key = r.target
        # Unfortunately, we do not currently support subdomains
        if key.domain:
            continue
        rel_dir = builder.db.get_checkout_location(key)
        if rel_dir.startswith("src/"):  # as it should
            rel_dir = rel_dir[4:]
        dirs.append(rel_dir)
    # in testing, use dirs[0:2] (or something similarly small) in place of dirs.
    repo.run_script(dirs, builder.build_name, email_dest, dry_run)
Beispiel #2
0
def _do_cmdline(args):
    original_dir = os.getcwd()
    dry_run = False

    # TODO: allow switches after args.
    while args:
        word = args[0]
        if word in ('-h', '--help', '-?'):
            print __doc__
            return
        elif word in ('--dry-run', '-n'):
            dry_run = True
        elif word[0] == '-':
            raise GiveUp, "Unexpected command line option %s" % word
        else:
            break
        args = args[1:]

    if len(args) != 1:
        raise GiveUp, "Incorrect non-option argument count (expected 1, the email destination)"

    email_dest = args[0]

    builder = find_and_load(original_dir, muddle_binary=None)
    # Don't bother determining muddle_binary: our invocation of find_and_load
    # doesn't make use of it. (Tibs writes: it's only needed for when
    # running makefiles, for when they use $(MUDDLE).)

    if not builder:
        raise GiveUp("Cannot find a build tree.")

    rootrepo = builder.db.RootRepository_pathfile.get()

    repo = parse_repo_url(rootrepo)

    rules = builder.all_checkout_rules()
    dirs = []
    for r in rules:
        key = r.target
        # Unfortunately, we do not currently support subdomains
        if key.domain:
            continue
        rel_dir = builder.db.get_checkout_location(key)
        if rel_dir.startswith("src/"):  # as it should
            rel_dir = rel_dir[4:]
        dirs.append(rel_dir)
    # in testing, use dirs[0:2] (or something similarly small) in place of dirs.
    repo.run_script(dirs, builder.build_name, email_dest, dry_run)
def process(goals):

	if goals and goals[0] in ('-h', '-help', '--help'):
		print __doc__
		sys.exit(0)

	## ... find a build tree
	original_dir = os.getcwd()
	gbuilder = find_and_load(original_dir, muddle_binary=None)
	# Don't bother determining muddle_binary: our invocation of find_and_load
	# doesn't make use of it. (Tibs writes: it's only needed for when
	# running makefiles, for when they use $(MUDDLE).)
	if not gbuilder:
		raise GiveUp('Not in a muddle build tree')

	if not goals:
		print '# No goals given: assuming default deployments'
		default_deployment_labels = gbuilder.default_deployment_labels
		goals = map(str, default_deployment_labels)
		print '#  %s'%', '.join(goals)

	if not goals:
		raise GiveUp('No goals given, and no default deployments. Giving up.')

	# Do we care about labelling the edges?
	hideEdgeLabels = True
	# Do we care about nodes touching an AptGetBuilder?
	omitAptGetNodes = True

	full_goals = []
	for g in goals:
		labels = gbuilder.label_from_fragment(g, default_type=LabelType.Package)
		for label in labels:
			if gbuilder.target_label_exists(label):
				full_goals.append(str(label))

	if not full_goals:
		raise GiveUp("None of the given goals %s is a target"%(map(str, goals)))

	for g in full_goals:
		Node(g, isGoal=True, extras="shape=parallelogram")
		# color=green fillcolor=green style=filled...?

	for g in full_goals:
		do_deps(gbuilder, g)

	# Nodes created by AptGetBuilders aren't very interesting.
	if omitAptGetNodes:
		for k,e in Edge.all_edges.items():
			if e.nodeFrom.isAptGet:
				del Edge.all_edges[k]
		for k,n in Node.all_nodes.items():
			if n.isAptGet:
				del Node.all_nodes[k]

	# If we have A/preconfig -> A/configured -> A/built -> A/installed
	# [ -> A/preinstalled], we can condense them into one.
	reductio = {
			'preconfig' : 'configured',
			'configured' : 'built',
			'built' : 'installed',
			'installed' : 'postinstalled',
	}
	while True:
		madeChange = False
		for k,e in Edge.all_edges.items():
			if e.nodeTo.isGoal:
				continue # Don't conflate explicit goal nodes

			nFrom = e.nodeFrom.rawname.rsplit('/',1)
			nTo = e.nodeTo.rawname.rsplit('/',1)
			if not nFrom[0] == nTo[0]:
				continue # labels are not the same, no chance of reduction

			# TODO: This logic is horrible!
			reducable = False
			try:
				if reductio[nFrom[1]] == nTo[1]:
					reducable = True
			except KeyError: pass
			for aux in e.nodeFrom.auxNames:
				try:
					auxFrom = aux.rsplit('/',1)
					assert auxFrom[0] == nFrom[0]
					if reductio[auxFrom[1]] == nTo[1]:
						reducable = True
						break
				except KeyError: pass

			if not reducable: continue

			# Are there any other edges to nodeTo? If so, we can't reduce.
			count = 0
			for ee in Edge.all_edges.values():
				if ee.nodeTo.rawname == e.nodeTo.rawname:
					count=count+1
			if count > 1:
				# NOTE: This code path is untested...
				continue

			# OK, it's safe to conflate the two.
			#print "WOULD REDUCE: %s -> %s" %(e.nodeFrom.rawname,e.nodeTo.rawname)
			oldname = e.nodeFrom.displayname
			if e.nodeTo.displayname.find('+') != -1:
				substr = e.nodeTo.displayname.rsplit('/')[1]
				e.nodeFrom.displayname = "%s+%s" %(e.nodeFrom.displayname, substr)
			else:
				e.nodeFrom.displayname = "%s+%s" %(e.nodeFrom.displayname, nTo[1])
			#print "RENAME: %s => %s"%(oldname, e.nodeFrom.displayname)

			e.nodeFrom.auxNames.add(e.nodeTo.rawname)
			e.nodeFrom.auxNames |= e.nodeTo.auxNames

			# Now kill all nodes B->C, replace with A'->C:
			for kk,ee in Edge.all_edges.items():
				if ee.nodeFrom == e.nodeTo:
					Edge(e.nodeFrom, ee.nodeTo, e.label)
					del Edge.all_edges[kk]
			# Finally, kill off edge A->B and node B themselves:
			del Edge.all_edges[k]
			del Node.all_nodes[e.nodeTo.rawname]

			madeChange = True
			break

		if not madeChange:
			break
		# else loop forever

	# Now tidy up the conflated display names:
	for n in Node.all_nodes.values():
		if len(n.auxNames)>0:
			tmp = n.displayname.rsplit('/',1)
			n.displayname = '%s/\\n%s'%(tmp[0],tmp[1])

	print 'digraph muddle {'

	print "\n# Nodes"
	print "node [shape=box];"
	for n in Node.all_nodes.values():
		print n.todot()

	print "\n# Edges"
	print "edge [fontsize=9, labelangle=90, decorate=true];"
	for e in Edge.all_edges.values():
		print e.todot(hideEdgeLabels)

	print '}'
def process(args):
    goals = []
    omitCheckouts = False
    shortLabels = False

    while args:
        word = args.pop(0)
        if word in ('-h', '-help', '--help'):
            print __doc__
            return
        elif word in ('--hide-checkouts'):
            omitCheckouts = True
        elif word in ('--short-labels'):
            shortLabels = True
        elif word[0] == '-':
            print 'Unrecognised switch', word
            return
        else:
            goals.append(word)

## ... find a build tree
    original_dir = os.getcwd()
    gbuilder = find_and_load(original_dir, muddle_binary=None)
    # Don't bother determining muddle_binary: our invocation of find_and_load
    # doesn't make use of it. (Tibs writes: it's only needed for when
    # running makefiles, for when they use $(MUDDLE).)
    if not gbuilder:
        raise GiveUp('Not in a muddle build tree')

    if not goals:
        print '# No goals given: assuming default deployments'
        default_deployment_labels = gbuilder.default_deployment_labels
        goals = map(str, default_deployment_labels)
        print '#  %s' % ', '.join(goals)

    if not goals:
        raise GiveUp('No goals given, and no default deployments. Giving up.')

# Do we care about labelling the edges?
    hideEdgeLabels = True
    # Do we care about nodes touching an AptGetBuilder?
    omitAptGetNodes = True

    full_goals = []
    for g in goals:
        labels = gbuilder.label_from_fragment(g,
                                              default_type=LabelType.Package)
        for label in labels:
            if gbuilder.target_label_exists(label):
                full_goals.append(str(label))

    if not full_goals:
        raise GiveUp("None of the given goals %s is a target" %
                     (map(str, goals)))

    for g in full_goals:
        Node(g, isGoal=True, extras="shape=parallelogram, fillcolor=gold")
        # color=green fillcolor=green style=filled...?

    for g in full_goals:
        do_deps(gbuilder, g)

# Nodes created by AptGetBuilders aren't very interesting.
    if omitAptGetNodes:
        for k, e in Edge.all_edges.items():
            if e.nodeFrom.isAptGet:
                del Edge.all_edges[k]
        for k, n in Node.all_nodes.items():
            if n.isAptGet:
                del Node.all_nodes[k]

    # Maybe don't bother with checkouts either
    if omitCheckouts:
        for k, e in Edge.all_edges.items():
            if e.nodeFrom.isCheckout:
                del Edge.all_edges[k]
        for k, n in Node.all_nodes.items():
            if n.isCheckout:
                del Node.all_nodes[k]

# If we have A/preconfig -> A/configured -> A/built -> A/installed
# [ -> A/preinstalled], we can condense them into one.
    reductio = {
        'preconfig': 'configured',
        'configured': 'built',
        'built': 'installed',
        'installed': 'postinstalled',
    }
    while True:
        madeChange = False
        for k, e in Edge.all_edges.items():
            if e.nodeTo.isGoal:
                continue  # Don't conflate explicit goal nodes

            nFrom = e.nodeFrom.rawname.rsplit('/', 1)
            nTo = e.nodeTo.rawname.rsplit('/', 1)
            if not nFrom[0] == nTo[0]:
                continue  # labels are not the same, no chance of reduction

            # TODO: This logic is horrible!
            reducable = False
            try:
                if reductio[nFrom[1]] == nTo[1]:
                    reducable = True
            except KeyError:
                pass
            for aux in e.nodeFrom.auxNames:
                try:
                    auxFrom = aux.rsplit('/', 1)
                    assert auxFrom[0] == nFrom[0]
                    if reductio[auxFrom[1]] == nTo[1]:
                        reducable = True
                        break
                except KeyError:
                    pass

            if not reducable: continue

            # Are there any other edges to nodeTo? If so, we can't reduce.
            count = 0
            for ee in Edge.all_edges.values():
                if ee.nodeTo.rawname == e.nodeTo.rawname:
                    count = count + 1
            if count > 1:
                # NOTE: This code path is untested...
                continue

            # OK, it's safe to conflate the two.
            #print "WOULD REDUCE: %s -> %s" %(e.nodeFrom.rawname,e.nodeTo.rawname)
            oldname = e.nodeFrom.displayname
            if e.nodeTo.displayname.find('+') != -1:
                substr = e.nodeTo.displayname.rsplit('/')[1]
                e.nodeFrom.displayname = "%s+%s" % (e.nodeFrom.displayname,
                                                    substr)
            else:
                e.nodeFrom.displayname = "%s+%s" % (e.nodeFrom.displayname,
                                                    nTo[1])
            #print "RENAME: %s => %s"%(oldname, e.nodeFrom.displayname)

            e.nodeFrom.auxNames.add(e.nodeTo.rawname)
            e.nodeFrom.auxNames |= e.nodeTo.auxNames

            # Now kill all nodes B->C, replace with A'->C:
            for kk, ee in Edge.all_edges.items():
                if ee.nodeFrom == e.nodeTo:
                    Edge(e.nodeFrom, ee.nodeTo, e.label)
                    del Edge.all_edges[kk]
            # Finally, kill off edge A->B and node B themselves:
            del Edge.all_edges[k]
            del Node.all_nodes[e.nodeTo.rawname]

            madeChange = True
            break

        if not madeChange:
            break
        # else loop forever

# Now tidy up the conflated display names:
    if shortLabels:
        for n in Node.all_nodes.values():
            n.displayname = n.displayname.rsplit('/', 1)[0]
            if n.displayname.startswith('package:'):
                n.displayname = n.displayname[8:]
    else:
        for n in Node.all_nodes.values():
            if len(n.auxNames) > 0:
                tmp = n.displayname.rsplit('/', 1)
                n.displayname = '%s/\\n%s' % (tmp[0], tmp[1])

    print 'digraph muddle {'

    print "\n# Nodes"
    print "node [shape=box];"
    for n in Node.all_nodes.values():
        print n.todot()

    print "\n# Edges"
    print "edge [fontsize=9, labelangle=90, decorate=true];"
    for e in Edge.all_edges.values():
        print e.todot(hideEdgeLabels)

    print '}'
def _do_cmdline(args):
    original_dir = os.getcwd()
    original_env = os.environ.copy()
    dry_run = False
    verbose = False

    # TODO: allow switches after args.
    while args:
        word = args[0]
        if word in ("-h", "--help", "-?"):
            print __doc__
            return
        elif word in ("--dry-run", "-n"):
            dry_run = True
        elif word in ("-v", "--verbose"):
            verbose = True
        elif word[0] == "-":
            raise GiveUp, "Unexpected command line option %s" % word
        else:
            break
        args = args[1:]

    if len(args) != 0:
        raise GiveUp, "Unexpected non-option arguments given"

    builder = find_and_load(original_dir, muddle_binary=None)
    # Don't bother determining muddle_binary: our invocation of find_and_load
    # doesn't make use of it. (Tibs writes: it's only needed for when
    # running makefiles, for when they use $(MUDDLE).)

    if not builder:
        raise GiveUp("Cannot find a build tree.")

    rootrepo = builder.db.RootRepository_pathfile.get()

    rules = builder.all_checkout_rules()
    rr = []
    for r in rules:
        co_dir = builder.db.get_checkout_path(r.target)
        if isinstance(r.action.vcs, muddled.vcs.git.Git):
            if verbose:
                print "In %s:" % co_dir
            os.chdir(co_dir)
            raw = get_cmd_data("git show-ref --heads", verbose=verbose)
            raw_heads = raw[1].rstrip("\n").split("\n")
            pat = re.compile("[0-9a-f]+ refs/heads/(.+)")
            heads = set()
            for h in raw_heads:
                m = pat.match(h)
                if m is None:
                    raise GiveUp("Unparseable output from git: %s" % h)
                heads.add(m.group(1))

            g = r.action.vcs
            # print "heads is %s"%heads.__str__()
            if g.branch is not None:
                if g.branch in heads:
                    if verbose:
                        print "%s: ok (has %s)" % (co_dir, g.branch)
                else:
                    bfrom = "master"
                    # desired branch not found; if we have a master then try to fixup:
                    if bfrom in heads:
                        # if verbose:
                        print "===\nFixing %s: %s --> %s" % (co_dir, bfrom, g.branch)
                        (rc, lines, igno) = get_cmd_data("git status --porcelain -uall", verbose=verbose)
                        lines = lines.rstrip("\n")
                        if lines != "":
                            if not verbose:
                                print "> git status --porcelain -uall"
                            print ">>%s<<" % lines
                            print (
                                "Uncommitted changes or untracked files found in %s, deal with these before continuing"
                                % co_dir
                            )
                            raise GiveUp
                        maybe_run_cmd("git fetch origin %s" % (g.branch), dry_run, verbose)
                        maybe_run_cmd("git fetch origin %s:%s" % (g.branch, g.branch), dry_run, verbose)
                        maybe_run_cmd("git checkout %s" % g.branch, dry_run, verbose)
                        maybe_run_cmd("git config branch.%s.remote origin" % g.branch, dry_run, verbose)
                        maybe_run_cmd("git config branch.%s.merge %s" % (g.branch, g.branch), dry_run, verbose)
                        try:
                            maybe_run_cmd("git branch -d %s" % bfrom, dry_run, verbose)
                        except GiveUp:
                            print "\n* * * HEALTH WARNING * * *"
                            print "Unmerged changes were found committed to the '%s' branch in %s" % (bfrom, co_dir)
                            print "YOU MUST MERGE THESE INTO '%s' YOURSELF OR LOSE THEM!" % g.branch
                            # print "This script will not revisit this checkout."
                            print "The relevant changes are:"
                            run0("git log --oneline --topo-order --graph --decorate=short %s..%s" % (g.branch, bfrom))
                            raise
                    else:
                        raise GiveUp(
                            "Error: %s wants a branch named '%s', does not have one, and does not have a '%s' either - I don't know how to fix this"
                            % (co_dir, g.branch, bfrom)
                        )
            else:
                # want master, don't care about others
                if verbose:
                    print "%s heads are: %s" % (co_dir, heads)
                if not "master" in heads:
                    raise GiveUp(
                        "Error: %s wants a 'master' branch but does not have one, I don't know how to fix this" % co_dir
                    )
        else:
            if verbose:
                print "Ignoring %s (not powered by git)" % co_dir