Add sample snf-common config file
[pithos] / fabfile.py
1 # Copyright 2011 GRNET S.A. All rights reserved.
2 #
3 # Redistribution and use in source and binary forms, with or
4 # without modification, are permitted provided that the following
5 # conditions are met:
6 #
7 #   1. Redistributions of source code must retain the above
8 #      copyright notice, this list of conditions and the following
9 #      disclaimer.
10 #
11 #   2. Redistributions in binary form must reproduce the above
12 #      copyright notice, this list of conditions and the following
13 #      disclaimer in the documentation and/or other materials
14 #      provided with the distribution.
15 #
16 # THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 # USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 # POSSIBILITY OF SUCH DAMAGE.
28 #
29 # The views and conclusions contained in the software and
30 # documentation are those of the authors and should not be
31 # interpreted as representing official policies, either expressed
32 # or implied, of GRNET S.A.
33 #
34
35 import os
36 import sys
37
38 from contextlib import contextmanager
39 from fabric.api import *
40 from fabric.colors import *
41
42 env.project_root = "./"
43 env.develop = False
44 env.autoremove = True
45 env.packages = ['snf-pithos-lib', 'snf-pithos-backend', 'snf-pithos-app',
46                         'snf-pithos-tools']
47 env.capture = False
48 env.colors = True
49 env.pypi_root = 'pypi'
50 env.roledefs = {
51     'docs': ['docs.dev.grnet.gr'],
52     'pypi': ['docs.dev.grnet.gr']
53 }
54
55
56 # colored logging
57 notice = lambda x: sys.stdout.write(yellow(x) + "\n")
58 info = lambda x: sys.stdout.write(green(x) + "\n")
59 error = lambda x: sys.stdout.write(red(x) + "\n")
60
61
62 def dev():
63     env.develop = True
64
65
66 # wrap local to respect global capturing setting from env.capture
67 oldlocal = local
68 def local(cmd, capture="default"):
69     if capture != "default":
70         capture = capture
71     else:
72         capture = env.capture
73     return oldlocal(cmd, capture=capture)
74
75
76 def package_root(p):
77     return os.path.join(env.project_root, p)
78
79
80 def remove_pkg(p):
81     notice("uninstalling package: %s" % p)
82     with lcd(package_root(p)):
83         with settings(warn_only=True):
84             local("pip uninstall %s -y" % p, env.capture)
85
86
87 def build_pkg(p):
88     info ("building package: %s" % p)
89     with lcd(package_root(p)):
90         try:
91             local("rm -r dist build")
92         except:
93             pass
94         local("python setup.py egg_info -d sdist")
95
96
97 def install_pkg(p):
98     info("installing package: %s" % p)
99     with lcd(package_root(p)):
100         if env.develop:
101             local("python setup.py develop")
102         else:
103             local("python setup.py install")
104
105
106 def install(*packages):
107     for p in packages:
108         install_pkg("snf-%s" % p)
109
110
111 def buildall():
112     for p in env.packages:
113         build_pkg(p)
114     collectdists()
115
116
117 def installall():
118     for p in env.packages:
119         install_pkg(p)
120
121
122 def collectdists():
123     if os.path.exists("./packages"):
124         notice("removing 'packages' directory")
125         local("rm -r packages");
126
127     local("mkdir packages");
128     for p in env.packages:
129         local("cp %s/dist/*.tar.gz ./packages/" % package_root(p));
130
131
132 def removeall():
133     for p in env.packages:
134         remove_pkg(p)
135
136
137 def remove(*packages):
138     for p in packages:
139         remove_pkg("snf-%s" % p)
140
141
142 #
143 # GIT helpers
144 #
145
146
147 def git(params, locl=True):
148     cmd = local if locl else run
149     return cmd("git %s" % params, capture=True)
150
151
152 def branch():
153     return git("symbolic-ref HEAD").split("/")[-1]
154
155
156 @contextmanager
157 def co(c):
158     current_branch = branch();
159     git("checkout %s" % c)
160     # Use a try block to make sure we checkout the original branch.
161     try:
162         yield
163     finally:
164         try:
165             git("checkout %s" % current_branch)
166         except Exception:
167             error("Could not checkout %s, you're still left at %s" % c)
168
169 #
170 # Debian packaging helpers
171 #
172
173 env.debian_branch = 'debian-0.8'
174 env.deb_packages = ['snf-pithos-lib', 'snf-pithos-backend',
175                     'snf-pithos-tools', 'snf-pithos-app']
176 env.signdebs = False
177 env.debrelease = False  # Increase release number in Debian changelogs
178 env.upstream = 'packaging'
179
180
181 def _last_commit(f):
182     return local("git rev-list --all --date-order --max-count=1 %s" % f,
183             capture=True).strip()
184
185
186 def _diff_from_master(c,f):
187     return local("git log --oneline %s..%s %s" \
188                  " | wc -l" % (c, env.upstream, f), capture=True)
189
190
191 def dch(p):
192     with co(env.debian_branch):
193         local("git merge %s" % env.upstream)
194         with lcd(package_root(p)):
195             local("if [ ! -d .git ]; then mkdir .git; fi")
196
197             # FIXME:
198             # Checking for new changes in packages
199             # has been removed temporarily.
200             # Always create a new Debian changelog entry.
201             ## Check for new changes in package dir
202             #diff = _diff_from_master(_last_commit("debian/changelog"), ".")
203             #vercmd  = "git describe --tags --abbrev=0"\
204             #          " | sed -rn '\''s/^v(.*)/\\1/p'\''"
205             #version = local(vercmd, capture=True)
206             #if int(diff) > 0:
207             if True:
208                 # Run git-dch in snapshot mode.
209                 # TODO: Support a --release mode in fabfile
210                 local(("git-dch --debian-branch=%s --auto %s" %
211                        (env.debian_branch,
212                         "--release" if env.debrelease else "--snapshot")))
213                 local(("git commit debian/changelog"
214                        " -m 'Updated %s changelog'" % p))
215                 notice(("Make sure to tag Debian release in %s" %
216                         env.debian_branch))
217
218             local("rmdir .git")
219
220
221 def debrelease():
222     env.debrelease = True
223
224
225 def signdebs():
226     env.signdebs = True
227
228
229 def builddeb(p, master="packaging", branch="debian-0.8"):
230     with co(branch):
231         info("Building debian package for %s" % p)
232         with lcd(package_root(p)):
233             local("git merge %s" % master)
234             local("if [ ! -d .git ]; then mkdir .git; fi")
235             local("python setup.py clean")
236             local("git add ./*/*/version.py -f")
237             local(("git-buildpackage --git-upstream-branch=%s --git-debian-branch=%s"
238                    " --git-export=INDEX --git-ignore-new %s") %
239                    (master, branch, "" if env.signdebs else "-us -uc"))
240             local("rm -rf .git")
241             local("git reset ./*/*/version.py")
242         info("Done building debian package for %s" % p)
243
244
245 def builddeball(b="debian-0.8"):
246     for p in env.deb_packages:
247         builddeb(p=p, branch=b)
248
249
250
251 @roles('pypi')
252 def uploadtars():
253     put("packages/*.tar.gz", 'www/pypi/')
254