OSDN Git Service

Buildscript: Adopt to new translation folder for PO files.
[winmerge-jp/winmerge-jp.git] / Tools / Scripts / create_release.py
1 #
2 # The MIT License
3 # Copyright (c) 2007-2009 Kimmo Varis
4 # Copyright (c) 2008 Matthias Mayer
5 #
6 # Permission is hereby granted, free of charge, to any person obtaining
7 # a copy of this software and associated documentation files
8 # (the "Software"), to deal in the Software without restriction, including
9 # without limitation the rights to use, copy, modify, merge, publish,
10 # distribute, sublicense, and/or sell copies of the Software, and to
11 # permit persons to whom the Software is furnished to do so, subject to
12 # the following conditions:
13 # The above copyright notice and this permission notice shall be included
14 # in all copies or substantial portions of the Software.
15 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17 # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
23 # $Id$
24
25 # This is a script for creating a WinMerge release.
26 # Tasks it does:
27 # - cleans previous build files from folders
28 # - sets version number for resources
29 # - updates POT and PO files
30 # - builds libraries (expat, scew, pcre)
31 # - builds WinMerge.exe and WinMergeU.exe
32 # - builds 32-bit ShellExtension targets
33 # - builds user manual
34 # - builds the InnoSetup installer
35 # - creates per-version distribution folder
36 # - exports SVN sources to distribution folder
37 # - creates binary distribution folder
38
39 #Tasks not done (TODO?):
40 # - building 64-bit ShellExtension
41 # - creating packages from source and binary folders
42 # - running virus check
43 # - creating SHA-1 hashes for distributed files
44 # - create installer to correct folder
45 # - make installer compile less verbose
46 # - make building exes and dlls also less verbose
47 # - builds libraries twice: as independent project and from executable project (by prelink.bat)
48 # - check Python version
49 # - check JRE is installed
50 # - check InnoSetup is installed
51
52 # Tools needed:
53 # - Visual Studio 2003 or later
54 # - Python 2.5 or 2.6 :)
55 # - Subversion command line binaries from http://subversion.tigris.org/
56 # - InnoSetup 5
57 # - Manual build tools (in Developer tools at downloads)
58 # - Java runtime environment (JRE) (Manual build tools need it)
59 # There are lots of other dependencies, they are documented in /Docs/Developers documents. Especially be sure to read:
60 # - Compiling.html for compiling executables and dlls
61 # - readme-manual.html for building the manual
62 # - readme-InnoSetup.html for creating the installer
63
64 # Please note that this script is only tested in kimmov's environment. It simply may not work in other environments and
65 # configurations. If you find problems, please report them so we can improve the script.
66
67 # CONFIGURATION:
68 # Set these variables to match your environment and folders you want to use
69
70 # Subversion binary - set this to absolute path to svn.exe
71 #svn_binary = r'C:\Program Files\Subversion\bin\svn.exe'
72 # Visual Studio path
73 #vs_path = r'C:\Program Files\Microsoft Visual Studio .NET 2003'
74 # InnoSetup installation path
75 #innosetup_path = 'C:\\Program Files\\Inno Setup 5'
76 # Relative path where to create a release folder
77 dist_root_folder = 'distrib'
78 # Source location
79 # Give URL to SVN repository to export source from SVN or 'workspace' to export
80 # from workspace
81 #source_location = 'https://winmerge.svn.sourceforge.net/svnroot/winmerge/trunk'
82 #source_location ='workspace'
83
84 # END CONFIGURATION - you don't need to edit anything below...
85
86 from subprocess import *
87 import os
88 import os.path
89 import sys
90 import getopt
91 import shutil
92 import SetVersions
93 import ConfigParser
94
95 class settings:
96     def __init__(self):
97         self.rootpath = ''
98         self.svn_binary = r'C:\Program Files\Subversion\bin\svn.exe'
99         self.vs_path = ''
100         self.vs_path7 = r'C:\Program Files\Microsoft Visual Studio .NET 2003'
101         self.vs_path8 = r'C:\Program Files\Microsoft Visual Studio 8.0'
102         self.vs_path9 = r'C:\Program Files\Microsoft Visual Studio 9.0'
103         self.innosetup_path = r'C:\Program Files\Inno Setup 5'
104         self.winmerge_iss = 'WinMerge.iss' #filename only
105         self.winmerge_iss_path = 'WinMerge.iss' #including path
106         self.source = 'workspace'
107         self.version = ''
108         self.vs_version = 2003
109
110     def create_ini(self, filename):
111         config = ConfigParser.RawConfigParser()
112         sect = 'RUNTIME'
113         if os.path.exists('Tools.ini'):
114             config.readfp(open(filename))
115         if not config.has_section(sect):
116             config.add_section(sect)
117         if not config.has_option(sect, 'type'):
118             config.set(sect, 'type', 'VSXXXX')
119         if not config.has_option(sect, 'VSStudio'):
120             config.set(sect, 'VSStudio', self.vs_version)
121         if not config.has_option(sect, 'Source'):
122             config.set(sect, 'Source', self.source)
123         if not config.has_option(sect, 'svn_binary'):
124             config.set(sect, 'svn_binary', self.svn_binary)
125         if not config.has_option(sect, 'vs_path7'):
126             config.set(sect, 'vs_path7', self.vs_path7)
127         if not config.has_option(sect, 'vs_path8'):
128             config.set(sect, 'vs_path8', self.vs_path8)
129         if not config.has_option(sect, 'vs_path9'):
130             config.set(sect, 'vs_path9', self.vs_path9)
131         if not config.has_option(sect, 'innosetup_path'):
132             config.set(sect, 'innosetup_path', self.innosetup_path)
133
134         # Writing our configuration file to 'Tools.ini'
135         with open(filename, 'w') as configfile:
136             config.write(configfile)
137
138     def read_ini(self, filename):
139         config = ConfigParser.RawConfigParser()
140         if not os.path.exists(filename):
141             # If the config file didn't exist, we create a new file and ask
142             # user to edit the config and re-run the script. This is because
143             # our defaults probably don't match user's environment.
144             self.create_ini(filename)
145             print 'New configuration file created: ' + filename
146             print 'Please edit the file to match your configuration and re-run the script.'
147             sys.exit()
148
149         config.readfp(open(filename))
150         self.svn_binary = config.get('RUNTIME', 'svn_binary')
151         self.vs_path7 = config.get('RUNTIME', 'vs_path7')
152         self.vs_path8 = config.get('RUNTIME', 'vs_path8')
153         self.vs_path9 = config.get('RUNTIME', 'vs_path9')
154         self.innosetup_path = config.get('RUNTIME', 'innosetup_path')
155         self.source = config.get('RUNTIME', 'Source') 
156         self.vs_version = config.getint('RUNTIME', 'VSStudio')
157
158         if self.vs_version ==2003:
159             self.vs_path =self.vs_path7
160         elif self.vs_version ==2005:
161             self.vs_path =self.vs_path8
162         elif self.vs_version ==2008:
163             self.vs_path =self.vs_path9
164
165 # global settings class instance
166 prog = settings()
167
168 def get_vs_ide_bin():
169     """Gets a full path to the Visual Studio IDE executable to run."""
170
171     # These are identical for VS2003.Net, VS2005 and VS2008
172     rel_path = 'Common7/IDE'
173     vs_bin = 'devenv.com'
174
175     vs_ide_path = os.path.join(prog.vs_path, rel_path)
176     vs_cmd_path = os.path.join(vs_ide_path, vs_bin)
177     return vs_cmd_path
178
179 def cleanup_build():
180     """Deletes all build files around folder structure"""
181
182     print 'Delete old build files...'
183     winmerge_temp = 'BuildTmp'
184     if os.path.exists(winmerge_temp):
185         print 'Remove folder %s' % winmerge_temp
186         shutil.rmtree(winmerge_temp, True)
187     else:
188         print 'Skipping folder %s' % winmerge_temp
189     
190     try:
191         print 'Remove ANSI files'
192         if os.path.exists('build/mergerelease/WinMerge.exe'):
193             os.remove('build/mergerelease/WinMerge.exe')
194         if os.path.exists('build/mergerelease/ShellExtension.dll'):
195             os.remove('build/mergerelease/ShellExtension.dll')
196         if os.path.exists('build/mergerelease/MergeLang.dll'):
197             os.remove('build/mergerelease/MergeLang.dll')
198
199         print 'Remove Unicode files'
200         if os.path.exists('build/mergeunicoderelease/WinMergeU.exe'):
201             os.remove('build/mergeunicoderelease/WinMergeU.exe')
202         if os.path.exists('build/mergeunicoderelease/ShellExtensionU.dll'):
203             os.remove('build/mergeunicoderelease/ShellExtensionU.dll')
204         if os.path.exists('build/mergeunicoderelease/MergeLang.dll'):
205             os.remove('build/mergeunicoderelease/MergeLang.dll')
206
207         print 'Remove expat files'
208         if os.path.exists('build/expat'):
209             shutil.rmtree('build/expat', True)
210         if os.path.exists('build/mergerelease/libexpat.dll'):
211             os.remove('build/mergerelease/libexpat.dll')
212         if os.path.exists('build/mergeunicoderelease/libexpat.dll'):
213             os.remove('build/mergeunicoderelease/libexpat.dll')
214
215         print 'Remove pcre files'
216         if os.path.exists('build/pcre'):
217             shutil.rmtree('build/pcre', True)
218         if os.path.exists('build/mergerelease/pcre.dll'):
219             os.remove('build/mergerelease/pcre.dll')
220         if os.path.exists('build/mergeunicoderelease/pcre.dll'):
221             os.remove('build/mergeunicoderelease/pcre.dll')
222
223         if os.path.exists('build/scew'):
224             shutil.rmtree('build/scew', True)
225
226         if os.path.exists('build/Manual'):
227             shutil.rmtree('build/Manual',True)
228
229     except EnvironmentError, einst:
230         print 'Error deleting files: '
231         print einst
232         return False;
233     except:
234         print 'Error deleting files: '
235         print sys.exc_info()[0]
236         return False
237     return True
238
239 def get_product_version(file):
240     """Get the product version number from config file."""
241
242     version = SetVersions.get_product_version(file)
243     return version
244
245 def set_resource_version(file):
246     """Sets the version number to the resource."""
247
248     print 'Update version number to resource(s)...'
249     SetVersions.process_versions(file)
250
251 def setup_translations():
252     """Updates translation files by running scripts in Src/Languages."""
253
254     # Scripts must be run from the directory where they reside
255     curdir = os.getcwd()
256     os.chdir('Translations/WinMerge')
257     call(['cscript', '/nologo', 'CreateMasterPotFile.vbs'])
258     call(['cscript', '/nologo', 'UpdatePoFilesFromPotFile.vbs'])
259     os.chdir(curdir)
260
261 def get_and_create_dist_folder(folder):
262     """Formats a folder name for version-specific distribution folder
263     and creates the folder."""
264
265     abs_folder = os.path.realpath(dist_root_folder)
266     dist_folder = os.path.join(abs_folder, folder)
267     if os.path.exists(dist_folder):
268         print 'Folder: ' + dist_folder + ' already exists!'
269         print 'If you want to re-create this version, remove folder first!'
270         return ''
271     else:
272         print 'Create distribution folder: ' + dist_folder
273         os.mkdir(dist_folder)
274         return dist_folder
275
276 def get_src_dist_folder(dist_folder, folder):
277     """Format a source distribution folder path."""
278
279     dist_src = os.path.join(dist_folder, folder + '-src')
280     return dist_src
281
282 def svn_export(dist_src_folder):
283     """Exports sources to distribution folder."""
284
285     print 'Exporting sources to ' + dist_src_folder
286     print 'Exporting from: ' + prog.source
287     if prog.source == 'workspace':
288         call([prog.svn_binary, 'export', '--non-interactive', '.', dist_src_folder])
289     else:
290         call([prog.svn_binary, 'export', '--non-interactive', source_location, dist_src_folder]) 
291
292 def cleanup_dlls_from_plugins(dist_src_folder):
293     """Remove compiled plugin dll files from source distribution folders."""
294
295     dll_folder = os.path.join(dist_src_folder, 'Plugins/dlls')
296     files = os.listdir(dll_folder)
297
298     print 'Removing dll files from plugin folder...'
299     for cur_file in files:
300         fullpath = os.path.join(dll_folder, cur_file)
301         if os.path.isfile(fullpath):
302             file_name, file_ext = os.path.splitext(cur_file)
303             if (file_ext == '.dll'):
304                 os.remove(fullpath)
305
306 def build_libraries():
307     """Builds library targets: expat, scew and pcre."""
308
309     vs_cmd = get_vs_ide_bin()
310     cur_path = os.getcwd()
311
312     print 'Build expat library...'
313     solution_path = os.path.join(cur_path, 'Externals/expat/lib/expat.vcproj')
314     #print solution_path
315     call([vs_cmd, solution_path, '/rebuild', 'Release'], shell=True)
316
317     print 'Build scew library...'
318     solution_path = os.path.join(cur_path, 'Externals/scew/win32/scew.vcproj')
319     #print solution_path
320     call([vs_cmd, solution_path, '/rebuild', 'Release'], shell=True)
321
322     print 'Build pcre library...'
323     solution_path = os.path.join(cur_path, 'Externals/pcre/Win32/pcre.vcproj')
324     #print solution_path
325     call([vs_cmd, solution_path, '/rebuild', 'MinSizeRel'], shell=True)
326
327 def build_targets():
328     """Builds all WinMerge targets."""
329
330     build_libraries()
331
332     vs_cmd = get_vs_ide_bin()
333
334     build_winmerge(vs_cmd)
335     build_shellext(vs_cmd)
336
337 def build_winmerge(vs_cmd):
338     """Builds WinMerge executable targets."""
339
340     cur_path = os.getcwd()
341     solution_path = os.path.join(cur_path, 'Src\\Merge.vcproj')
342     #print sol_path
343
344     # devenv Src\Merge.dsp /rebuild Release
345     print 'Build WinMerge executables...'
346     call([vs_cmd, solution_path, '/rebuild', 'Release'], shell=True)
347     call([vs_cmd, solution_path, '/rebuild', 'UnicodeRelease'], shell=True)
348
349 def build_shellext(vs_cmd):
350     """Builds 32-bit ShellExtension."""
351
352     cur_path = os.getcwd()
353     solution_path = os.path.join(cur_path, 'ShellExtension\\ShellExtension.vcproj')
354
355     # devenv Src\Merge.dsp /rebuild Release
356     print 'Build ShellExtension dlls...'
357     call([vs_cmd, solution_path, '/rebuild', 'Release MinDependency'])
358     call([vs_cmd, solution_path, '/rebuild', 'Unicode Release MinDependency'])
359
360 def build_manual():
361     """Builds manual's HTML Help (CHM) version for user install and
362     HTML version for the Web. HTML version is created with ads."""
363
364     curdir = os.getcwd()
365     os.chdir('Docs/Users/Manual/build')
366     print 'Build HTML Help (CHM) manual...' 
367     call(['build_htmlhelp.bat'])
368     
369     # HTML manual not build in trunk.
370     #print 'Build HTML manual for Web with ads...'
371     #call(['build_html.bat', 'withads'])
372     print 'Manual build finished.'
373     os.chdir(curdir)
374
375 def build_innosetup_installer(target_folder):
376     """Builds the InnoSetup installer for the WinMerge."""
377
378     innosetup_exe = os.path.join(prog.innosetup_path, 'iscc.exe')
379     cur_path = os.getcwd()
380
381     prog.winmerge_iss_path = os.path.join(cur_path, 'Installer\\InnoSetup\\' + prog.winmerge_iss)
382
383     #output_switch = '/O"' + target_folder + '"'
384
385     print 'Build Innosetup installer...'
386     # Should be able to give folder for created file and Q switch to make build quiet
387     #call([innosetup_exe, '/Q', output_switch, winmerge_iss])
388     call([innosetup_exe, prog.winmerge_iss_path])
389
390 def get_and_create_bin_folder(dist_folder, folder):
391     """Formats and creates binary distribution folder."""
392
393     bin_folder = os.path.join(dist_folder, folder + '-exe')
394     print 'Create binary distribution folder: ' + bin_folder
395     os.mkdir(bin_folder)
396     return bin_folder
397
398 def create_bin_folders(bin_folder, dist_src_folder):
399     """Creates binary distribution folders."""
400
401     cur_path = os.getcwd()
402     os.chdir(bin_folder)
403     print 'Create binary distribution folder structure...'
404     lang_folder = os.path.join(bin_folder, 'Languages')
405     os.mkdir(lang_folder)
406     doc_folder = os.path.join(bin_folder, 'Docs')
407     os.mkdir(doc_folder)
408     filters_folder = os.path.join(bin_folder, 'Filters')
409     plugins_folder = os.path.join(bin_folder, 'MergePlugins')
410     os.chdir(cur_path)
411
412     print 'Copying files to binary distribution folder...'
413     shutil.copy('build/mergerelease/WinMerge.exe', bin_folder)
414     shutil.copy('build/mergeunicoderelease/WinMergeU.exe', bin_folder)
415
416     shutil.copy('build/mergerelease/ShellExtension.dll', bin_folder)
417     shutil.copy('build/mergeunicoderelease/ShellExtensionU.dll', bin_folder)
418     shutil.copy('build/mergeunicoderelease/MergeLang.dll', bin_folder)
419     shutil.copy('build/shellextensionx64/ShellExtensionX64.dll', bin_folder)
420     shutil.copy('ShellExtension/Register.bat', bin_folder)
421     shutil.copy('ShellExtension/UnRegister.bat', bin_folder)
422
423     shutil.copy('build/pcre/pcre.dll', bin_folder)
424     shutil.copy('build/expat/libexpat.dll', bin_folder)
425
426     copy_po_files(lang_folder)
427     filter_orig = os.path.join(dist_src_folder, 'Filters')
428     shutil.copytree(filter_orig, filters_folder, False)
429
430     # Copy compiled plugins dir and rename it
431     plugin_dir = os.path.join(bin_folder, 'dlls')
432     plugin_orig = os.path.join(dist_src_folder, 'Plugins/dlls')
433     shutil.copytree(plugin_orig, plugin_dir, False)
434     os.rename(plugin_dir, plugins_folder)
435
436     shutil.copy('build/Manual/htmlhelp/WinMerge.chm', doc_folder)
437
438     shutil.copy('Docs/Users/ReleaseNotes.html', doc_folder)
439     shutil.copy('Docs/Users/ReadMe.txt', bin_folder)
440     shutil.copy('Docs/Users/ChangeLog.txt', doc_folder)
441     shutil.copy('Docs/Users/Contributors.txt', bin_folder)
442     shutil.copy('Docs/Users/Files.txt', bin_folder)
443
444 def copy_po_files(dest_folder):
445     """Copies all PO files to destination folder."""
446
447     lang_folder = 'Translations/WinMerge'
448     files = os.listdir(lang_folder)
449
450     print 'Copying PO files to binary folder...'
451     for cur_file in files:
452         fullpath = os.path.join(lang_folder, cur_file)
453         if os.path.isfile(fullpath):
454             file_name, file_ext = os.path.splitext(cur_file)
455             if (file_ext == '.po'):
456                 shutil.copy(fullpath, dest_folder)
457
458 def find_winmerge_root():
459     """Find WinMerge tree root folder from where to run rest of the script.
460
461     This function checks if we are in WinMerge root folder. If we are in some
462     other folder then we must try to find the WinMerge root folder. Because all
463     other code assumes we are in WinMerge root folder. If the root folder is
464     found current folder is changed into it."""
465
466     # If we find Src and Filters -subfolders we are in root 
467     if os.path.exists('Src') and os.path.exists('Filters'):
468         return True
469     
470     # Check if we are in /Tools/Scripts
471     if os.path.exists('../../Src') and os.path.exists('../../Filters'):
472         os.chdir('../../')
473         return True
474     
475     return False
476
477 def check_tools():
478     """Check that needed external tools can be found."""
479
480     global prog
481     if not os.path.exists(prog.svn_binary):
482         print 'Subversion binary could not be found from:'
483         print prog.svn_binary
484         print 'Please check script configuration and/or make sure Subversion is installed.'
485         return False
486
487     vs_cmd = get_vs_ide_bin()
488     if not os.path.exists(vs_cmd):
489         print 'Cannot find Visual Studio IDE binary from:'
490         print vs_cmd
491         print 'Please check script configuration.'
492         return False
493
494     pathhhc = os.path.join(prog.rootpath, 'Docs/Users/Manual/build/hhc/hhc.exe')
495     folderdtd = os.path.join(prog.rootpath, 'Docs/Users/Manual/build/dtd')
496     foldersaxon = os.path.join(prog.rootpath, 'Docs/Users/Manual/build/saxon')
497     folderxerc = os.path.join(prog.rootpath, 'Docs/Users/Manual/build/xerces')
498     folderxsl = os.path.join(prog.rootpath, 'Docs/Users/Manual/build/xsl')
499
500     if not os.path.exists(pathhhc) or not os.path.exists(folderdtd) or \
501             not os.path.exists(foldersaxon) or not os.path.exists(folderxerc) or \
502             not os.path.exists(folderxsl):
503         print 'Cannot find manual build tools'
504         print 'Please download and install manual build tools from:'
505         print 'https://sourceforge.net/project/showfiles.php?group_id=13216'
506         print 'See also Docs/Developers/readme-manual.html'
507         return False
508     return True
509
510 def check_x64shellext():
511     """Checks that 64-bit ShellExtension is compiled prior to running this
512     script.
513
514     This is due to the fact we can't compile 64-bit ShellExtension without some
515     environment tweaks, so it won't work (currently) from this script. And the
516     ShellExtension must be compiled separately.
517     """
518     if not os.path.exists('build/shellextensionx64/ShellExtensionX64.dll'):
519         print 'ERROR: cannot create a release:'
520         print 'You must compile 64-bit ShellExtension (ShellExtensionX64.dll)'
521         print 'before running this script!'
522         return False
523     else:
524         return True
525
526 def usage():
527     """Print script usage information."""
528
529     print 'WinMerge release script.'
530     print 'Usage: create_release [-h] [-f file] [-v n] [-c] [-l]'
531     print '  where:'
532     print '    -h, --help print this help'
533     print '    -v n, --version=n set release version'
534     print '    -c, --cleanup clean up build files (temp files, libraries, executables)'
535     print '    -l, --libraries build libraries (expat, scew, pcre) only'
536     print '    -f file, --file=filename set the version number ini file'
537     print '  For example: create_release -f versions.ini'
538     print '  If no version number (-v) or INI file (-f) given, 0.0.0.0 will be'
539     print '    used as version number.'
540
541 def main(argv):
542     global prog
543     ver_file = ''
544     if len(argv) > 0:
545         opts, args = getopt.getopt(argv, "hclv:f:", [ "help", "cleanup", "libraries",
546                                                     "version=", "file="])
547         
548         for opt, arg in opts:
549             if opt in ("-h", "--help"):
550                 usage()
551                 sys.exit()
552             if opt in ("-v", "--version"):
553                 prog.version = arg
554                 print "Start building WinMerge release version " + prog.version
555             if opt in ("-c", "--cleanup"):
556                 if cleanup_build() == True:
557                     print 'Cleanup done.'
558                 sys.exit()
559             if opt in ("-l", "--libraries"):
560                 build_libraries()
561                 sys.exit()
562             if opt in ("-f", "--file"):
563                 ver_file = arg
564         
565     if ver_file == '' and prog.version == '':
566         print 'WARNING: No version number or INI file given, using default'
567         print '    version number of 0.0.0.0 where applicable in this script.'
568         prog.version = '0.0.0.0'
569
570     # Check we are running from correct folder (and go to root if found)
571     if find_winmerge_root() == False:
572         print 'ERROR: Cannot find WinMerge root folder!'
573         print 'The script must be run from WinMerge tree\'s root folder'
574         print '(which has Src- and Filter -folders as subfolders) or from'
575         print 'Tools/Scripts -folder (where this script is located).'
576         sys.exit()
577
578     # Now read settings from Tools.ini
579     prog.read_ini('Tools.ini')
580     print 'Compiler: ' + prog.vs_path
581     print 'Path:' + os.getcwd()
582
583     # Remember the rootfolder
584     prog.rootpath = os.getcwd()
585
586     # Check all required tools are found (script configuration)
587     if check_tools() == False:
588         sys.exit()
589
590     # Check 64-bit ShellExtension is compiled
591     if check_x64shellext() == False:
592         sys.exit()
593
594     # Create the distribution folder if it doesn't exist
595     try:
596         if not os.path.exists(dist_root_folder):
597             os.mkdir(dist_root_folder)
598     except EnvironmentError, einst:
599         print 'Error creating distribution folder: ' + dist_root_folder
600         print einst
601         sys.exit()
602
603     # Remove old build's files
604     if cleanup_build() == False:
605         sys.exit()
606
607     if len(ver_file) > 0:
608         version_read = get_product_version(ver_file)
609         if len(version_read) > 0:
610             prog.version = version_read
611         set_resource_version(ver_file)
612
613     version_folder = 'WinMerge-' + prog.version
614     dist_folder = get_and_create_dist_folder(version_folder)
615     if dist_folder == '':
616         sys.exit(1)
617     dist_src_folder = get_src_dist_folder(dist_folder, version_folder)
618     svn_export(dist_src_folder)
619
620     setup_translations()
621
622     build_targets()
623     build_manual()
624     build_innosetup_installer(dist_folder)
625
626     dist_bin_folder = get_and_create_bin_folder(dist_folder, version_folder)
627     create_bin_folders(dist_bin_folder, dist_src_folder)
628
629     # Do the cleanup after creating binary distrib folders, as some files
630     # and folders are copied from source folders to binary folders.
631     cleanup_dlls_from_plugins(dist_src_folder)
632
633     print 'WinMerge release script ready!'
634
635
636 ### MAIN ###
637 if __name__ == "__main__":
638     main(sys.argv[1:])