svn: rebase after push
[yap.git] / plugins / svn.py
blob3f4e25ea7f36c7e19ec3337a57a8f36c862af343
2 from yap import YapPlugin, YapError
3 from yap.util import get_output, takes_options, run_command, run_safely, short_help
4 import os
6 class SvnPlugin(YapPlugin):
7 def __init__(self, yap):
8 self.yap = yap
10 def _clone_svn(self, url, directory=None, **flags):
11 url = url.rstrip('/')
12 if directory is None:
13 directory = url.rsplit('/')[-1]
14 directory = directory.replace('.git', '')
16 try:
17 os.mkdir(directory)
18 except OSError:
19 raise YapError("Directory exists: %s" % directory)
20 os.chdir(directory)
21 self.yap.cmd_init()
22 os.system("git svn init %s" % url)
23 os.system("git svn fetch -r %s:HEAD" % flags.get('-r', '1'))
24 self.yap.cmd_repo("svn", url)
25 os.system("git config yap.svn.enabled 1")
27 def _enabled(self):
28 enabled = get_output("git config yap.svn.enabled")
29 return bool(enabled)
31 def _get_svn_ref(self):
32 fetch = get_output("git config svn-remote.svn.fetch")
33 if not fetch:
34 raise YapError("No svn remote configured")
35 ref = fetch[0].split(':')[1]
36 return ref
38 # Ensure users don't accidentally kill our "svn" repo
39 def pre_repo(self, *args, **flags):
40 if not self._enabled():
41 return
42 if '-d' in flags and args and args[0] == "svn":
43 raise YapError("Refusing to delete special svn repository")
45 @takes_options("r:")
46 def cmd_clone(self, *args, **flags):
47 if args and not run_command("svn info %s" % args[0]):
48 self._clone_svn(*args, **flags)
49 else:
50 self.yap._call_base("cmd_commit", *args, **flags)
52 def cmd_fetch(self, *args, **flags):
53 if self._enabled():
54 if args and args[0] == 'svn':
55 os.system("git svn fetch")
56 return
57 self.yap._call_base("cmd_fetch", *args, **flags)
59 def cmd_push(self, *args, **flags):
60 if self._enabled():
61 if args and args[0] == 'svn':
62 print "Verifying branch is up-to-date"
63 self.yap.cmd_fetch("svn")
64 ref = self._get_svn_ref()
65 rev = get_output("git rev-parse %s" % ref)
66 assert rev
67 base = get_output("git merge-base HEAD %s" % rev[0])
68 if base[0] != rev[0]:
69 raise YapError("Branch not up-to-date. Update first.")
70 current = get_output("git symbolic-ref HEAD")
71 if not current:
72 raise YapError("Not on a branch!")
73 current = current[0].replace('refs/heads/', '')
74 self.yap._confirm_push(current, "trunk", "svn")
75 if run_command("git update-index --refresh"):
76 raise YapError("Can't push with uncommitted changes")
77 os.system("git svn dcommit")
78 run_safely("git svn rebase")
79 return
80 self.yap._call_base("cmd_push", *args, **flags)
82 @short_help("change options for the svn plugin")
83 def cmd_svn(self, subcmd):
84 "enable"
86 if subcmd not in ["enable"]:
87 raise TypeError
89 if "svn" not in [x[0] for x in self.yap._list_remotes()]:
90 raise YapError("The svn plugin requires a remote named 'svn'")
92 os.system("git config yap.svn.enabled 1")