awful hg repo, taghilight include
[stack/conf/vim.git] / addons / TagHighlight / dist / make_taghighlight_release.py
1 #!/usr/bin/python
2 from __future__ import print_function
3
4 import os
5 import sys
6 import zipfile
7 import fnmatch
8 import subprocess
9
10 vimfiles_dir = os.path.abspath(os.path.join(os.path.dirname(__file__),'..'))
11
12 import socket
13 hostname = socket.gethostname()
14
15 HG=["hg"]
16
17 # Recursive glob function, from
18 # http://stackoverflow.com/questions/2186525/use-a-glob-to-find-files-recursively-in-python#2186565
19 def Rglob(path, match):
20     matches = []
21     for root, dirnames, filenames in os.walk(path):
22         for filename in fnmatch.filter(filenames, match):
23             matches.append(os.path.join(root, filename))
24     return matches
25
26 def UpdateReleaseVersion():
27     release_file = os.path.join(vimfiles_dir,'plugin/TagHighlight/data/release.txt')
28     fh = open(release_file,'r')
29     lines = [i for i in fh]
30     fh.close()
31     release = 'INVALID'
32     fh = open(release_file, 'wb')
33     for line in lines:
34         if line.startswith('release:'):
35             parts = line.strip().split(':')
36             numbers = [int(i) for i in parts[1].split('.')]
37             release = '{0}.{1}.{2}'.format(numbers[0],numbers[1],numbers[2]+1)
38             fh.write('release:'+release+'\n')
39         else:
40             fh.write(line.strip() + '\n')
41     fh.close()
42     return release
43
44 version_info_initial = ['log','-1','--template=release_revid:{node}\nrelease_date:{date|isodate}']
45 clean_info = ['status']
46
47 def GenerateVersionInfo():
48     version_file = os.path.join(vimfiles_dir,'plugin/TagHighlight/data/version_info.txt')
49
50     args = HG + clean_info
51     p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
52     (stdout,stderr) = p.communicate()
53     if p.returncode > 0:
54         sys.exit(p.returncode)
55
56     status_lines = stdout
57     if len(status_lines) > 0:
58         clean = False
59         clean_line = "release_clean:0"
60     else:
61         clean = True
62         clean_line = "release_clean:1"
63
64     args = HG + version_info_initial
65     p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
66     (stdout,stderr) = p.communicate()
67
68     # Write as binary for consistent line endings
69     fh = open(version_file, 'wb')
70     fh.write(clean_line + "\n")
71
72     for line in stdout.split('\n'):
73         if line.startswith('release_'):
74             fh.write(line + '\n')
75     fh.close()
76
77     return version_file, clean
78
79 def MakeMainRelease(r):
80     # List of paths to include (either explicit files or paths to search)
81     paths = {
82             '.py': ['plugin/TagHighlight',__file__],
83             '.vim': ['plugin/TagHighlight.vim','autoload/TagHighlight'],
84             '.txt': ['plugin/TagHighlight/data','plugin/TagHighlight/instructions.txt', 'doc/TagHighlight.txt'],
85             '.spec': ['plugin/TagHighlight/TagHighlight.spec'],
86             }
87     filename = 'taghighlight_r{0}.zip'.format(r)
88     MakeZipFile(filename, paths)
89
90 def MakeZipFile(filename, paths):
91     # Create the zipfile
92     zipf = zipfile.ZipFile(os.path.join(vimfiles_dir, 'dist', filename), 'w')
93
94     # Collect the specified paths into a zip file
95     for ext, pathlist in paths.items():
96         for path in pathlist:
97             # Get the full path (specified relative to vimfiles directory)
98             full_path = os.path.join(vimfiles_dir, path)
99             if os.path.exists(full_path):
100                 if os.path.isfile(full_path):
101                     files = [full_path]
102                 elif os.path.isdir(full_path):
103                     files = Rglob(full_path, '*' + ext)
104                 else:
105                     print("Unrecognised path: " + full_path)
106
107                 if len(files) > 0:
108                     for f in files:
109                         dirname = os.path.dirname(os.path.relpath(f,vimfiles_dir))
110                         zipf.write(f,os.path.join(dirname, os.path.basename(f)), zipfile.ZIP_DEFLATED)
111                 else:
112                     print("No files found for path: " + full_path)
113             else:
114                 print("Path does not exist: " + full_path)
115     # Close the zipfile
116     zipf.close()
117
118 def MakeLibraryPackage(r):
119     paths = {
120             '.txt': ['plugin/TagHighlight/standard_libraries'],
121             '.taghl': ['plugin/TagHighlight/standard_libraries'],
122             }
123     filename = 'taghighlight_standard_libraries_r{0}.zip'.format(r)
124     MakeZipFile(filename, paths)
125
126 def MakeCompiled(pyexe, pyinstaller_path, zipfilename, platform_dir):
127     initial_dir = os.getcwd()
128     os.chdir(os.path.join(vimfiles_dir, 'plugin/TagHighlight'))
129     args = pyexe + [os.path.join(pyinstaller_path, 'Build.py'), '-y', 'TagHighlight.spec']
130     p = subprocess.Popen(args)#, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
131     (stdout,stderr) = p.communicate()
132     if p.returncode > 0:
133         sys.exit(p.returncode)
134     zipf = zipfile.ZipFile(os.path.join(vimfiles_dir,'dist',zipfilename), 'w')
135     for f in Rglob(os.path.join(vimfiles_dir,'plugin/TagHighlight/Compiled/'+platform_dir),'*'):
136         dirname = os.path.dirname(os.path.relpath(f,vimfiles_dir))
137         zipf.write(f,os.path.join(dirname, os.path.basename(f)), zipfile.ZIP_DEFLATED)
138     zipf.close()
139     os.chdir(initial_dir)
140
141 def MakeWin32Compiled(r):
142     if 'WINPYTHON' in os.environ:
143         # Doesn't work with spaces in the path
144         # (doing the split to allow for running python
145         # with wine).
146         pyexe = os.environ['WINPYTHON'].split(' ')
147     else:
148         pyexe = ['python.exe']
149     pyinstaller_path = os.environ['WINPYINSTALLERDIR']
150     MakeCompiled(pyexe, pyinstaller_path, 'taghighlight_r{0}_win32.zip'.format(r), 'Win32')
151
152 def MakeLinuxCompiled(r):
153     if 'PYTHON' in os.environ:
154         # Doesn't work with spaces in the path
155         # (doing the split to allow for running python
156         # with wine).
157         pyexe = os.environ['PYTHON']
158     else:
159         pyexe = ['python']
160     pyinstaller_path = os.environ['PYINSTALLERDIR']
161     MakeCompiled(pyexe, pyinstaller_path, 'taghighlight_r{0}_linux.zip'.format(r), 'Linux')
162
163 def CheckInChanges(r):
164     args = HG+['commit','-m','Release build {0}'.format(r)]
165     p = subprocess.Popen(args)
166     (stdout,stderr) = p.communicate()
167     if p.returncode > 0:
168         sys.exit(p.returncode)
169     args = HG+['tag','taghighlight-release-{0}'.format(r)]
170     p = subprocess.Popen(args)
171     (stdout,stderr) = p.communicate()
172     if p.returncode > 0:
173         sys.exit(p.returncode)
174     args = HG+['push']
175     p = subprocess.Popen(args)
176     (stdout,stderr) = p.communicate()
177     if p.returncode > 0:
178         sys.exit(p.returncode)
179
180 def PublishReleaseVersion():
181     # TODO
182     # This function will be used to push generated files to a remote location
183     # to make them available on the web
184     pass
185
186 def main():
187     version_file, clean = GenerateVersionInfo()
188
189     if clean:
190         new_release = UpdateReleaseVersion()
191         MakeMainRelease(new_release)
192         os.remove(version_file)
193         MakeWin32Compiled(new_release)
194         MakeLinuxCompiled(new_release)
195         MakeLibraryPackage(new_release)
196         CheckInChanges(new_release)
197         PublishReleaseVersion()
198     else:
199         print("Distribution not clean: check into Mercurial before making release.")
200         os.remove(version_file)
201
202
203 if __name__ == "__main__":
204     main()