source: 2013/27/build_games.py @ 4391

Revision 4391, 5.4 KB checked in by tojukarp, 10 years ago (diff)

Scripts for week 27

Line 
1# -*- coding: latin-1 -*-
2"""
3Builds all the .csproj-projects in all subdirectories, copies
4compiled games to directory games and optionally writes the
5results of the build.
6"""
7
8from __future__ import with_statement
9import sys
10import os
11from os.path import *
12import shutil
13from shutil import *
14from glob import *
15from subprocess import *
16from datetime import *
17import re
18
19should_write_results = True
20
21output_dir = abspath("pelit")
22build_result_dir = abspath("build")
23lib_dir_x86 = abspath("lib")
24personal_dirs = [d for d in os.listdir(".") if isdir(d) and d not in ("lib", basename(output_dir), ".svn")]
25projects_that_did_not_build = []
26msbuild = "msbuild"
27
28
29
30def check_requirements():
31    global msbuild
32    if not exists("lib\\Jypeli.dll"):
33        raise Exception("lib\\Jypeli.dll expected")
34    return_code = call(msbuild + " /? 1> NUL 2> NUL", shell=True)
35    if return_code != 0:
36        msbuild = join(os.getenv("SystemRoot"), "Microsoft.NET\\Framework\\v4.0.30319\\MSBuild.exe")
37        if not exists(msbuild):
38            raise Exception("MSBuild not found in " + msbuild)
39
40
41def create_output_directory():
42    if not exists(output_dir):
43        os.mkdir(output_dir)
44    for d in personal_dirs:
45        if not exists(join(output_dir, d)):
46            os.mkdir(join(output_dir, d))
47
48def create_build_result_directory():
49    if not exists(build_result_dir):
50        os.mkdir(build_result_dir)
51
52
53def parse_last_changed_date(svn_info_output):
54    match = re.search("Last Changed Date: (\\d\\d\\d\\d)-(\\d\\d)-(\\d\\d) (\\d\\d):(\\d\\d)", svn_info_output)
55    if not match:
56        raise Exception("Last Changed Date not found from svn info output!")
57    year = int(match.group(1))
58    month = int(match.group(2))
59    day = int(match.group(3))
60    hour = int(match.group(4))
61    minute = int(match.group(5))
62    return datetime(year=year, month=month, day=day, hour=hour, minute=minute)
63
64
65def build_games():
66    for d in personal_dirs:
67        path = abspath(d)
68        time = datetime(2000, 1, 1)
69        if should_write_results and exists(join(path, ".svn")):
70            call("svn update " + path, shell=True)
71            outputs = Popen("svn info " + path, stdout=PIPE).communicate()
72            time = parse_last_changed_date(outputs[0])
73        build_games_in_personal_dir(path, time)
74
75
76counter = 1
77
78
79def get_weekday_name(n):
80    if n == 0: return "Maanantai"
81    if n == 1: return "Tiistai"
82    if n == 2: return "Keskiviikko"
83    if n == 3: return "Torstai"
84    if n == 4: return "Perjantai"
85    if n == 5: return "Lauantai"
86    if n == 6: return "Sunnuntai"
87    raise Exception("Invalid weekday number")
88
89
90def write_result(author, name, success, last_changed_date):
91    global counter
92    with open(join(build_result_dir, str(counter)+".txt"), "w") as f:
93        f.write(author+"\n")
94        f.write(name+"\n")
95        result = "success"
96        if not success:
97            result = "fail"
98        f.write(result+"\n")
99        formatted_time = get_weekday_name(last_changed_date.weekday()) + last_changed_date.strftime(" %H:%M")
100        f.write(formatted_time+"\n")
101    counter += 1
102
103
104def build_games_in_personal_dir(personal_dir, last_changed_date):
105    for root, dirs, files in os.walk(personal_dir):
106        if '.svn' in dirs:
107            dirs.remove('.svn')
108        projects = glob(join(root, '*.csproj'))
109        if projects:
110            if len(projects) > 1:
111                print "NOTE: There is more than one project file in", root
112
113            project_name = splitext(basename(projects[0]))[0]
114            author = basename(personal_dir)
115
116            success = build(projects[0])
117
118            if should_write_results:
119                write_result(author, project_name, success, last_changed_date)
120
121            if success:
122                dst_dir = join(output_dir, author)
123                copy_game(project_name, root, dst_dir)
124                print author + ": " + project_name
125            else:
126                projects_that_did_not_build.append(projects[0])
127
128
129def build(project_file_path):
130    build_cmd = msbuild + ' /nologo /verbosity:quiet /p:XnaProfile=Reach /p:Configuration=Release /p:"ReferencePath=%s" /t:Build "%s"' % (lib_dir_x86, project_file_path)
131    return call(build_cmd, shell=True) == 0
132
133
134def copy_game(project_name, project_dir, dst_dir):
135    bin = join(project_dir, "bin\\x86\\Release")
136    if not exists(bin):
137        print "NO BIN DIR FOUND IN", project_dir
138    dst = join(dst_dir, project_name)
139    if exists(dst):
140        rmtree(dst)
141    copytree(bin, dst, ignore=shutil.ignore_patterns('.svn', '*.pdb', 'jypeli.xml'))
142
143
144def parse_arguments():
145    for arg in sys.argv[1:]:
146        if arg == "--write-results":
147            global should_write_results
148            should_write_results = True
149        else:
150            raise Exception("Unknown argument: " + arg)
151
152
153def main():
154    try:
155        parse_arguments()
156        check_requirements()
157        create_output_directory()
158        if should_write_results: create_build_result_directory()
159        build_games()
160    except KeyboardInterrupt:
161        print "BUILD CANCELLED"
162    except Exception, e:
163        print
164        print "NOT SUCCESSFUL:", e
165        return 1
166
167    print
168    print 'Projects that did not build (%d):' % len(projects_that_did_not_build)
169    for p in projects_that_did_not_build:
170        print p
171
172
173if __name__ == '__main__':
174    sys.exit(main())
Note: See TracBrowser for help on using the repository browser.