def test_repr(self): url_canon = "git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git" url_non_canon = "git://linuxtv.org/media_tree.git" self.assertEqual( repr(git_sort.RepoURL(url_canon)), url_canon ) self.assertEqual( str(git_sort.RepoURL(url_canon)), "torvalds/linux" ) self.assertEqual( repr(git_sort.RepoURL(url_non_canon)), url_non_canon ) self.assertEqual( str(git_sort.RepoURL(url_non_canon)), url_non_canon ) self.assertEqual( str(git_sort.RepoURL(None)), "" )
def test_heads(self): self.assertEqual( git_sort.get_heads(self.repo), collections.OrderedDict([ (git_sort.Head(git_sort.RepoURL("torvalds/linux.git")), self.heads["mainline"]), (git_sort.Head(git_sort.RepoURL("davem/net.git")), self.heads["net"]), ]))
def test_heads(self): self.assertEqual( git_sort.get_heads(self.repo), collections.OrderedDict([( git_sort.Head(git_sort.RepoURL(None), "HEAD"), str(self.commits[-1][0]), )]))
def parse_section_header(line): """ Parse a series.conf line to identify if it's a comment denoting the beginning of a subsystem section. In that case, return the Head object it corresponds to. """ oot_text = git_sort.oot.rev line = line.strip() if not line.startswith("# "): raise exc.KSNotFound() line = line[2:] if line == oot_text: return git_sort.oot elif line.lower() == series_conf.start_text: raise exc.KSNotFound() words = line.split(None, 3) if len(words) > 2: raise exc.KSError( "Section comment \"%s\" in series.conf could not be parsed. " "series.conf is invalid." % (line, )) args = [git_sort.RepoURL(words[0])] if len(words) == 2: args.append(words[1]) head = git_sort.Head(*args) if head not in git_sort.remotes: raise exc.KSError( "Section comment \"%s\" in series.conf does not match any Head in " "variable \"remotes\". series.conf is invalid." % (line, )) return head
def test_sort(self): mapping = {commit: subject for commit, subject in self.commits} r = self.index.sort(mapping) self.assertEqual(len(mapping), 0) self.assertEqual(len(r), 1) r2 = list(r.items())[0] self.assertEqual(r2[0], git_sort.Head(git_sort.RepoURL(None), "HEAD")) self.assertEqual(r2[1], [subject for commit, subject in self.commits])
def sync_remote_list(directory): quoted_directory = shlex.quote(directory) commands = [] try: repo = pygit2.Repository(directory) except pygit2.GitError: commands.append("git init %s\n" % (quoted_directory, )) current_remotes = {} else: current_remotes = { remote.name: git_sort.RepoURL(remote.url) for remote in repo.remotes } commands.append("cd %s\n" % (quoted_directory, )) new_remotes = collections.OrderedDict((( transform(str(head.repo_url)), head.repo_url, ) for head in git_sort.remotes)) # modify existing remotes whose url has changed commands.extend([ "git remote set-url %s %s\n" % ( shlex.quote(name), shlex.quote(repr(repo_url)), ) for name, repo_url in new_remotes.items() if name in current_remotes and repo_url != current_remotes[name] ]) # add missing remotes current = set(current_remotes) new = set(new_remotes) mainline = str(git_sort.remotes[0].repo_url) def option(name): if name == mainline: return "" else: return " --no-tags" commands.extend([ "git remote add%s %s %s\n" % ( option(name), shlex.quote(name), shlex.quote(repr(new_remotes[name])), ) for name in new_remotes if name in new - current ]) # remove superfluous remotes commands.extend([ "git remote remove %s\n" % (shlex.quote(name), ) for name in sorted(current - new) ]) return commands
def test_sort(self): mapping = {str(commit.id): commit.message for commit in self.commits} r = self.index.sort(mapping) self.assertEqual(len(mapping), 0) self.assertEqual(len(r), 2) r2 = list(r.items())[0] self.assertEqual(r2[0], git_sort.Head(git_sort.RepoURL("torvalds/linux.git"))) self.assertEqual(r2[1], [commit.message for commit in self.commits])
def test_eq(self): self.assertEqual( git_sort.Head(git_sort.RepoURL("torvalds/linux.git")), git_sort.Head(git_sort.RepoURL("torvalds/linux.git")), ) self.assertEqual( git_sort.Head(git_sort.RepoURL("torvalds/linux.git")), git_sort.Head(git_sort.RepoURL("torvalds/linux.git"), "master"), ) self.assertNotEqual( git_sort.Head(git_sort.RepoURL("torvalds/linux.git")), git_sort.Head(git_sort.RepoURL("davem/net.git")), ) self.assertTrue( git_sort.Head(git_sort.RepoURL("torvalds/linux.git")) < git_sort.Head(git_sort.RepoURL("davem/net.git")))
def test_eq(self): self.assertEqual( git_sort.RepoURL( "git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git" ), git_sort.RepoURL( "git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git" )) self.assertEqual( git_sort.RepoURL( "git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git" ), git_sort.RepoURL( "git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git" )) self.assertEqual( git_sort.RepoURL( "git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git" ), git_sort.RepoURL( "http://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git" )) self.assertNotEqual( git_sort.RepoURL( "git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git" ), git_sort.RepoURL( "git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git")) self.assertEqual( git_sort.RepoURL( "git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git" ), git_sort.RepoURL( "git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux") ) self.assertEqual( git_sort.RepoURL( "git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git" ), git_sort.RepoURL("torvalds/linux.git")) self.assertEqual(git_sort.RepoURL("torvalds/linux.git"), git_sort.RepoURL("torvalds/linux")) self.assertNotEqual(git_sort.RepoURL("torvalds/linux.git"), git_sort.RepoURL("davem/net.git"))
def from_patch(self, index, name, current_head, move_upstream): """ This is where we decide a patch line's fate in the sorted series.conf The following factors determine how a patch is sorted: * commit found in index * patch's series.conf current_head is indexed (ie. the local repo fetches from that remote) * patch appears to have moved downstream/didn't move/upstream * patch's tag is good ("Git-repo:" == current_head.url) * patches may be moved upstream between subsystem sections """ self.name = name if not os.path.exists(name): raise exc.KSError("Could not find patch \"%s\"" % (name, )) with Patch(open(name, mode="rb")) as patch: commit_tags = patch.get("Git-commit") repo_tags = patch.get("Git-repo") if not commit_tags: self.dest_head = git_sort.oot return class BadTag(Exception): pass def get_commit(value): if not value: raise BadTag(value) tag = series_conf.firstword(value) if not self.commit_match.match(tag): raise BadTag(tag) return tag try: self.revs = [get_commit(value) for value in commit_tags] except BadTag as e: raise exc.KSError("Git-commit tag \"%s\" in patch \"%s\" is not a " "valid revision." % ( e.args[0], name, )) rev = self.revs[0] if len(repo_tags) > 1: raise exc.KSError("Multiple Git-repo tags found. Patch \"%s\" is " "tagged improperly." % (name, )) elif repo_tags: repo = git_sort.RepoURL(repo_tags[0]) elif commit_tags: repo = git_sort.remotes[0].repo_url self.new_url = None try: ic = index.lookup(rev) except git_sort.GSKeyError: # commit not found if current_head not in index.repo_heads: # repo not indexed if repo == current_head.repo_url: # good tag self.dest_head = current_head else: # bad tag raise exc.KSError( "There is a problem with patch \"%s\". " "The Git-repo tag is incorrect or the patch is in the " "wrong section of series.conf and (the Git-commit tag " "is incorrect or the relevant remote is outdated or " "not available locally) or an entry for this " "repository is missing from \"remotes\". In the last " "case, please edit \"remotes\" in " "\"scripts/git_sort/git_sort.py\" and commit the " "result. Manual intervention is required." % (name, )) else: # repo is indexed if repo == current_head.repo_url: # good tag raise exc.KSError( "There is a problem with patch \"%s\". " "Commit \"%s\" not found in git-sort index. " "The remote fetching from \"%s\" needs to be fetched " "or the Git-commit tag is incorrect or the patch is " "in the wrong section of series.conf. Manual " "intervention is required." % ( name, rev, current_head.repo_url, )) else: # bad tag raise exc.KSError( "There is a problem with patch \"%s\". " "The Git-repo tag is incorrect or the patch is in the " "wrong section of series.conf. Manual intervention is " "required." % (name, )) else: # commit found msg_bad_tag = "There is a problem with patch \"%s\". " \ "The Git-repo tag is incorrect or the patch is in " \ "the wrong section of series.conf. Manual " \ "intervention is required." % (name,) if current_head not in index.repo_heads: # repo not indexed if ic.head > current_head: # patch moved downstream if repo == current_head.repo_url: # good tag self.dest_head = current_head else: # bad tag raise exc.KSError(msg_bad_tag) elif ic.head == current_head: # patch didn't move raise exc.KSException( "Head \"%s\" is not available locally but commit " "\"%s\" found in patch \"%s\" was found in that head." % ( ic.head, rev, name, )) elif ic.head < current_head: # patch moved upstream if move_upstream: # move patches between subsystem sections self.dest_head = ic.head self.dest = ic if repo != ic.head.repo_url: # bad tag self.new_url = ic.head.repo_url else: # do not move patches between subsystem sections if repo == current_head.repo_url: # good tag self.dest_head = current_head else: # bad tag raise exc.KSError(msg_bad_tag) else: # repo is indexed if ic.head > current_head: # patch moved downstream if repo == current_head.repo_url: # good tag raise exc.KSError( "There is a problem with patch \"%s\". " "The patch is in the wrong section of series.conf " "or the remote fetching from \"%s\" needs to be " "fetched or the relative order of \"%s\" and " "\"%s\" in \"remotes\" is incorrect. Manual " "intervention is required." % ( name, current_head.repo_url, ic.head, current_head, )) else: # bad tag raise exc.KSError( "There is a problem with patch \"%s\". " "The patch is in the wrong section of series.conf " "or the remote fetching from \"%s\" needs to be " "fetched. Manual intervention is required." % ( name, current_head.repo_url, )) elif ic.head == current_head: # patch didn't move self.dest_head = ic.head self.dest = ic if repo != ic.head.repo_url: # bad tag self.new_url = ic.head.repo_url elif ic.head < current_head: # patch moved upstream if move_upstream: # move patches between subsystem sections self.dest_head = ic.head self.dest = ic if repo != ic.head.repo_url: # bad tag self.new_url = ic.head.repo_url else: # do not move patches between subsystem sections if repo == current_head.repo_url: # good tag self.dest_head = current_head self.dest = ic else: # bad tag raise exc.KSError(msg_bad_tag)