| #! /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() |