RIP subversion
[freebsd-maintainer-scripts/.git] / up.py
1 #!/usr/bin/env python3
2
3 """
4 One updater script to pull them all
5 """
6
7 import configparser
8 import io
9 import os
10 import shlex
11 import subprocess
12 import sys
13
14 user = os.environ['USER']
15 pwd = os.path.expanduser('~{0}'.format(user) or '/home/{0}'.format(user))
16
17 config = """
18 [default]
19 scm=git
20 git_update_cmd=git pull
21 git_clone_cmd=git clone
22 svn_update_cmd=svn update
23 svn_clone_cmd=svn checkout
24
25 [freebsd-src]
26 remote=https://git.freebsd.org/src.git
27 local={0}/freebsd/src
28
29 [freebsd-ports]
30 remote=https://git.freebsd.org/ports.git
31 local={0}/freebsd/ports
32
33 [freebsd-doc]
34 remote=https://git.freebsd.org/doc.git
35 local={0}/freebsd/doc
36
37 [openbsd-src]
38 remote=https://github.com/openbsd/src.git
39 local={0}/openbsd/src
40 """.format(pwd, user)
41
42 cfg = configparser.ConfigParser()
43 cfg.read_string(config)
44
45 def call(cmd):
46     subprocess.call(shlex.split(cmd))
47
48 class UpdaterFactory(object):
49
50     class BaseUpdater(object):
51         def __init__(self):
52             self.scm = "none"
53             self.already_cloned = False
54
55         def setCloned(self):
56             self.already_clone = True
57
58         def isCloned(self):
59             return self.already_cloned
60
61         def up(self): raise NotImplemented("up() method to implement")
62
63         def clone(self): raise NotImplemented("clone() method to implement")
64
65     class SVNUpdater(BaseUpdater):
66         def __init__(self, p):
67             super().__init__()
68             self.p = p
69             self.scm = 'svn'
70
71         def up(self):
72             os.chdir(self.p.get('local'))
73             cmd = cfg.get('default', 'svn_update_cmd')
74             call(cmd)
75
76         def clone(self):
77             cmd = cfg.get('default', 'svn_clone_cmd')
78             rc = call('svn checkout {0} {1}'.format(self.p.get('remote'), self.p.get('local')))
79             if rc == 0:
80                 self.setCloned()
81
82     class GitUpdater(BaseUpdater):
83         def __init__(self, p):
84             super().__init__()
85             self.p = p
86             self.scm = 'git'
87
88         def up(self):
89             os.chdir(self.p.get('local'))
90             cmd = cfg.get('default', 'git_update_cmd')
91             call(cmd)
92
93         def clone(self):
94             cmd = cfg.get('default', 'git_clone_cmd')
95             rc = call('{0} {1} {2}'.format(cmd , self.p.get('remote'), self.p.get('local')))
96             if rc == 0:
97                 self.setCloned()
98
99     @classmethod
100     def fromdict(cls, p):
101         scm_type = p.get('scm')
102         if scm_type == 'git':
103             return cls.GitUpdater(p)
104         elif scm_type == 'svn':
105             return cls.SVNUpdater(p)
106         else:
107             raise Exception("scm_type '{0}' unknown".format(scm_type))
108
109 class Config(object):
110     def __init__(self, cp):
111         self.cp = cp
112
113     def getSection(self, s, k):
114         if self.cp is None:
115             return ""
116         return self.cp._sections[s].get(k)
117
118     def getProjects(self):
119         projects = []
120         for s in self.cp._sections:
121             if s == 'default':
122                 continue
123             remote = self.getSection(s, 'remote')
124             local = self.getSection(s, 'local')
125             scm = self.getSection(s, 'scm') or self.getSection('default', 'scm')
126             projects.append(
127                 {'name': s, 'remote': remote, 'local': local, 'scm': scm}
128             )
129
130         return projects
131
132 if __name__ == '__main__':
133
134     for p in Config(cfg).getProjects():
135         u = UpdaterFactory.fromdict(p)
136         if not u.isCloned():
137             u.clone()
138         else:
139             u.up()