Bug#677792: [NEW] please consider including vcs-lint tool in devscripts
Jon Dowland
jmtd at debian.org
Sat Jun 16 19:16:00 UTC 2012
Package: devscripts
Version: 2.11.7
Severity: wishlist
Tags: patch
Hi,
I've written a tool 'vcs-lint' (formerly 'mr-lint'[1]) for which I am looking
for a home.
It's not intended to be a purely Debian tool, but it's certainly what I use
it for most, and it has some Debian-specific functionality.
'mr' and 'moreutils' are places I've considered which are not appropriate.
Is devscripts a good fit?
I don't feel it deserves it's own package, but I'd quite like to get it into
wheezy if possible.
Latest version attached.
Sample usage/output:
$ vcs-lint
/home/jon/wd/bup: local branches not present in origin: fix-pythonoptimize,debian-proposed,debian-dump-s390
/home/jon/wd/bup: commits to local branch debian have not been pushed to origin
/home/jon/wd/bup: 6 missing upstream tags: 0.14a, 0.17b, 0.20, 0.22a, 0.24b, 0.25~git2011.11.04
/home/jon/wd/bup: 8 missing debian tags: debian/0.17b-1, debian/0.20-2, debian/0.22a-1, debian/0.25~git2011.11.04-1, debian/0.25~git2011.11.04-2, debian/0.25~git2011.11.04-3, debian/0.25~git2011.11.04-4, debian/0.25~git2011.11.04-5
Please let me know what you think. Thanks!
[1] http://jmtd.net/log/mr-lint/
-------------- next part --------------
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright 2011 ? Jon Dowland <jmtd at debian.org>
# Licensed under the GNU GPL version 2 or higher.
import sys, os, subprocess
def usage():
print "usage: vcs-lint [ --verbose ]\n"+\
"vcs-lint will inspect the current working directory."
exit(0)
verbose = False
if "--verbose" in sys.argv:
verbose = True
if "--help" in sys.argv:
usage()
def debug(str):
if verbose:
print str
def run(cmd):
p = subprocess.Popen(cmd,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
output, errors = p.communicate()
return output
# how many debian package versions are there?
def get_package_versions():
output = run(['dpkg-parsechangelog', '--format', 'rfc822' , '--all'])
return set([ x[9:] for x in output.split("\n") if "Version: " == x[:9] ])
def get_git_tags():
tags = set(filter(lambda x: x, run(["git", "tag", "-l"]).split("\n")))
debug("\ttags: %s" % ", ".join(sorted(tags)))
return tags
# git tag checking
# there should be a tag 'upstream/$uv' and 'debian/$uv-$dv' for every version $v = "$uv-$dv"
def missing_tags(repo,ttype,missing):
if missing:
print "%s: %d missing %s tags: %s" % (repo, len(missing), ttype, ", ".join(sorted(missing)))
def check_package_versions_tagged(repo,git_tags,package_versions):
debug("\tcheck_package_versions_tagged")
if not filter(lambda x: x.find("-") >= 0, package_versions): # native package
missing_tags(repo, "package version", package_versions - git_tags)
else:
prefix = ""
if filter(lambda x: x.find("upstream") == 0, git_tags):
prefix = "upstream/"
missing_tags(repo, "upstream",
set( [ "%s%s"%(prefix,x[:x.find("-")]) for x in package_versions if x.find("-") >= 0 ]) - git_tags)
missing_tags(repo, "debian", set(["debian/%s"%x for x in package_versions]) - git_tags)
# git branch checking
def get_git_branches(prefix):
branches = run(["git", "for-each-ref", '--format=%(refname)', prefix]).split("\n")
return set([ x[len(prefix):] for x in branches if prefix == x[:len(prefix)] ])
def get_git_local_branches():
return get_git_branches("refs/heads/")
def get_git_origin_branches():
return get_git_branches("refs/remotes/origin/")
# are all local branches represented at origin?
def check_local_branches_at_origin(repo,origin_branches,local_branches):
debug("\tcheck_local_branches_at_origin")
debug("\t\tlocal branches: %s" % ",".join(local_branches))
debug("\t\torigin branches: %s" % ",".join(origin_branches))
missing = local_branches - origin_branches
if missing:
print "%s: local branches not present in origin: %s" % (repo, ",".join(missing))
# is branch x ahead of origin/x?
def local_branch_ahead_of_origin(branch):
debug("\tlocal_branch_ahead_of_origin")
return bool(run(["git", "rev-list", branch, "^remotes/origin/%s" % branch, "--"]))
# do all local branches match origin branches of the same name?
def check_branches_match_origin (repo,origin_branches,local_branches):
debug("\tcheck_branches_match_origin")
for b in local_branches & origin_branches:
debug("\t\t%s" % b)
l = run(["git", "for-each-ref",'--format="%(objectname)', "refs/remotes/origin/%s" % b])
r = run(["git", "for-each-ref",'--format="%(objectname)', "refs/heads/%s" % b])
if r != l:
if local_branch_ahead_of_origin(b):
print "%s: commits to local branch %s have not been pushed to origin" % (repo,b)
else:
print "%s: local branch %s does not match origin branch %s" % (repo,b,b)
def is_gitrepo():
return os.path.isdir(".git")
def repo_is_debian_package():
return os.path.isfile("debian/changelog")
repo = os.getcwd()
if not is_gitrepo:
sys.stderr.write("%s: not a git repository\n" % repo)
exit(1)
origin_branches = get_git_origin_branches()
local_branches = get_git_local_branches()
check_local_branches_at_origin(repo, origin_branches, local_branches)
check_branches_match_origin(repo, origin_branches, local_branches)
if repo_is_debian_package:
package_versions = get_package_versions()
git_tags = get_git_tags()
check_package_versions_tagged(repo, git_tags, package_versions)
More information about the devscripts-devel
mailing list