diff options
Diffstat (limited to 'scripts/selinux-maint')
-rwxr-xr-x | scripts/selinux-maint | 232 |
1 files changed, 232 insertions, 0 deletions
diff --git a/scripts/selinux-maint b/scripts/selinux-maint new file mode 100755 index 00000000..06fec4e0 --- /dev/null +++ b/scripts/selinux-maint @@ -0,0 +1,232 @@ +#! /usr/bin/python + +# Basic instructions +# +# 1. Save patch email to file [patch.email] +# +# 2. Go to the svn directory to which you want to apply the patch. +# +# 3. Run "selinux-maint split patch.email". This will run vi on the +# logmsg (pulled out of the email) to allow you to add anything (ack +# messages). When you quit vi the current directory will have files +# called "patch" and "logmsg". +# +# 4. Run "selinux-maint apply" (optionally with a strip level as +# the last argument). This will do a dry run of applying the patch +# showing the results and ask if you want to apply the patch. If you +# say yes it will apply the patch and attempt to detect file adds (by +# comparing svn status and the output of patch). If it finds adds it +# will ask if you want to add each file. +# +# 5. Run "selinux-maint commit" to commit that patch with the log +# message. +# +# 6. Repeat 4 and 5 as often as necessary for a set of patch emails. +# +# 7. Run "selinux-maint rev packagename" where packagename is +# something like "libsepol". This will prompt for the new version +# number (showing the current), update VERSION, add a Changelog entry +# with the version and date, and vi the changelog for you to add +# entries. +# +# 8. Run "selinux-maint commit" again to commit the revision change +# (rev adds a simple log message - I just fixed this as my last +# checkin had the wrong log message). + +import sys +import subprocess +import shutil +import os +import os.path +import datetime + +dir = "/tmp/selinux-maint/" + +def usage(): + print "selinux-maint [command] [options]" + print "" + print "commands:" + print "\tsplit patch-email: split patch-email into a patch and log message" + print "\tapply [patch-level]: apply the patch and logmsg with optional level" + print "\tcommit username: commit the changes" + print "\trev package: update the version number and changelog of package" + print "\tmerge reva:revb source-branch: merge changes to the current branch" + +def create_tmpdir(): + try: + os.mkdir(dir) + except OSError: + if not os.path.isdir(dir): + print "path %s exists and is not a directory" % dir + sys.exit(1) + +def split_email(args): + # Get an absolute path for the patch email since we are going to + # change the working directory + patch_path = os.path.abspath(args[0]) + + create_tmpdir() + prevdir = os.getcwd() + os.chdir(dir) + + infd = open(patch_path) + outfd = open("info", "w") + retcode = subprocess.call(["git-mailinfo", "msg", "patch"], stdin=infd, + stdout=outfd) + if retcode != 0: + sys.exit(1) + + msgfd = open("logmsg", "w") + retcode = subprocess.call(["cat", "info", "msg"], stdout=msgfd) + + msgfd.close() + + retcode = subprocess.call(["vi", "logmsg"]) + + shutil.copyfile("logmsg", prevdir + "/logmsg") + shutil.copyfile("patch", prevdir + "/patch") + +def apply(args): + if len(args) >= 1: + patch_level = "-p%d" % int(args[0]) + else: + patch_level = "-p1" + + if len(args) == 2: + patch_name = "../patch" + patch_dir = args[1] + else: + patch_name = "patch" + patch_dir = None + + print "Test applying patch:" + if patch_dir: + os.chdir(patch_dir) + + patchfd = open(patch_name) + retcode = subprocess.call(["patch", patch_level, "--dry-run", "-l"], stdin=patchfd) + resp = raw_input("apply [y/n]: ") + if resp != "y": + sys.exit(0) + + patchfd = open(patch_name) + patch_output = subprocess.Popen(["patch", patch_level, "-l"], stdin=patchfd, + stdout=subprocess.PIPE).communicate()[0] + + status_output = subprocess.Popen(["svn", "status"], stdout=subprocess.PIPE).communicate()[0] + + + # Detect adds + unknown_files = [] + for status_line in status_output.split("\n"): + try: + status, fname = status_line.split() + except ValueError: + continue + if status == "?": + unknown_files.append(fname) + + added_files = [] + for patch_line in patch_output.split("\n"): + try: + patched_fname = patch_line.split(" ")[2] + except: + continue + if patched_fname in unknown_files: + added_files.append(patched_fname) + + for fname in added_files: + input = raw_input("add file %s [y/n]: " % fname) + if input == "y": + subprocess.call(["svn", "add", fname]) + +def commit(args): + if len(args) == 1: + retcode = subprocess.call(["svn", "commit", "--username", args[0], "-F", "logmsg"]) + else: + retcode = subprocess.call(["svn", "commit", "-F", "logmsg"]) + + +def rev(args): + if len(args) != 1: + print "you must provide a package name" + usage() + sys.exit(1) + package = args[0] + + ver_fd = open("%s/VERSION" % package, "r") + cur = ver_fd.read() + cur = cur.split("\n")[0] + ver_fd.close() + input = raw_input("new version [current is %s]: " % cur) + new_fd = open("%s/VERSION.new" % package, "w") + new_fd.write(input + "\n") + new_fd.close() + shutil.copyfile("%s/VERSION.new" % package, "%s/VERSION" % package) + + old_changelog = "%s/ChangeLog" % package + new_changelog = "%s/ChangeLog.new" % package + + n = open(new_changelog, "w") + + entry = "%s %s\n" % (input, str(datetime.date.today())) + n.write(entry) + n.write("\t*\n\n") + o = open(old_changelog) + n.write(o.read()) + n.close() + o.close() + + subprocess.call(["vi", new_changelog]) + shutil.copyfile(new_changelog, old_changelog) + + logmsg = open("logmsg", "w") + logmsg.write("updated %s to version %s\n" % (package, input)) + +def merge(args): + if len(args) != 2: + print "you must provide a revision pair and source branch" + usage() + sys.exit(1) + + rev = args[0] + branch = args[1] + + if branch == "trunk": + url = "https://selinux.svn.sourceforge.net/svnroot/selinux/trunk" + elif branch == "stable": + url = "https://selinux.svn.sourceforge.net/svnroot/selinux/branches/stable/1_0" + else: + url = "https://selinux.svn.sourceforge.net/svnroot/selinux/branches/%s" % branch + + subprocess.call(["svn", "diff", "-r%s" % rev, url]) + input = raw_input("apply these changes [y/n]? ") + if input != "y": + sys.exit(0) + + subprocess.call(["svn", "merge", "-r%s" % rev, url]) + + logmsg = open("logmsg", "w") + logmsg.write("applied r%s from %s\n" % (rev, branch)) + + +def main(): + if len(sys.argv) < 2: + usage() + sys.exit(1) + + command = sys.argv[1] + if command == "split": + split_email(sys.argv[2:]) + elif command == "apply": + apply(sys.argv[2:]) + elif command == "commit": + commit(sys.argv[2:]) + elif command == "rev": + rev(sys.argv[2:]) + elif command == "merge": + merge(sys.argv[2:]) + else: + usage() + +main() |