Fix issue in Rocket.lua script.
[cafu-Engine.git] / Doxygen / build.py
blob379d80580fb2a79499874bbd75f41b17dda4055a
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3 import argparse
4 import os
5 import shutil
6 import subprocess
7 import sys
9 # In order to install module "paramiko", follow these steps:
11 # 1. As a prerequisite under Windows, install a prebuilt binary of PyCrypto
12 # from http://www.voidspace.org.uk/python/modules.shtml#pycrypto
13 # As we use 32-bit versions of Python 2.7 (as explained at
14 # http://www.cafu.de/wiki/cppdev:gettingstarted#python_and_scons), usually
15 # the right choice is
16 # http://www.voidspace.org.uk/downloads/pycrypto26/pycrypto-2.6.win32-py2.7.exe
18 # 2. Both under Windows and Linux, install Paramiko at the command line:
19 # pip install paramiko
20 # If pip is not yet installed on your system, install it as explained at
21 # http://www.pip-installer.org/en/latest/installing.html
22 import paramiko
25 def FindSConsBuildDir(root):
26 """
27 Starting at the given Cafu root directory, this method guesses where all the program
28 files are that were built by a previously successful run of SCons.
29 """
30 if sys.platform == "win32":
31 for compiler in ["vc15", "vc14", "vc13", "vc12", "vc11", "vc10", "vc9", "vc8"]:
32 for arch in ["amd64", "x64", "x86"]:
33 path = "build/" + sys.platform + "/" + compiler + "/" + arch + "/release"
34 if os.path.isfile(root + "/" + path + "/CaBSP/CaBSP.exe"):
35 return path
36 else:
37 for compiler in ["g++"]:
38 path = "build/" + sys.platform + "/" + compiler + "/release"
39 if os.path.isfile(root + "/" + path + "/CaBSP/CaBSP"):
40 return path
42 raise Exception("Could not find the SCons build directory.")
45 def BuildDoxygenDocs(SourceDir):
46 """
47 Builds the C++ and Lua reference documentation in a Cafu source code repository `SourceDir`.
49 The directory `SourceDir` must be the root directory of a Cafu source code repository checkout
50 in which in which all programs and libraries have already successfully been built.
52 The actions of the function modify the contents of the `cpp/out`, `scripting/tmpl` and
53 `scripting/out` directories in `SourceDir`.
54 """
55 PathCaWE = FindSConsBuildDir(SourceDir) + "/CaWE/CaWE"
57 subprocess.call([SourceDir + "/" + PathCaWE, "--update-doxygen"], cwd=SourceDir)
59 # For all files in the Doxygen/scripting/tmpl directory, make sure that they
60 # - don't contain the string "// WARNING" (e.g. about mismatches),
61 # - don't contain any lines that the related files in ../src don't have.
62 for root, dirs, files in os.walk(SourceDir + "/Doxygen/scripting/tmpl"):
63 for filename in files:
64 if filename == "README.txt":
65 continue
67 with open(root + "/" + filename, 'r') as tmplFile:
68 with open(root + "/../src/" + filename, 'r') as srcFile:
69 srcLines = srcFile.readlines()
70 srcLineNr = 0
72 for tmplLine in tmplFile:
73 if "// WARNING" in tmplLine:
74 raise Exception('Found a "// WARNING ..." comment in file "{0}".'.format(filename))
76 while tmplLine != srcLines[srcLineNr]:
77 srcLineNr += 1
78 if srcLineNr >= len(srcLines):
79 raise Exception('A line in template file "{0}" does not exist in the related source '
80 'file:\n\n{1}\nUse e.g. BeyondCompare to review the situation.'.format(filename, tmplLine))
82 # TODO: See http://marc.info/?l=doxygen-users&m=126909030104387&w=2 about Doxygen exit codes.
83 subprocess.call(["doxygen", "Doxygen/cpp/Doxyfile"], cwd=SourceDir)
84 subprocess.call(["doxygen", "Doxygen/scripting/Doxyfile"], cwd=SourceDir)
87 def Upload(sftp, LocalDir, RemoteDir):
88 """
89 Recursively uploads the contents of `LocalDir` to `RemoteDir`,
90 using the already established (opened) FTP connection `sftp`.
91 """
92 for root, dirs, files in os.walk(LocalDir):
93 relpath = os.path.relpath(root, LocalDir)
94 # print "root =", root, "relpath =", relpath, "dirs =", dirs, "#files =", len(files), "files[0] =", files[0]
96 for filename in files:
97 if relpath == ".":
98 sftp.put(LocalDir + "/" + filename,
99 RemoteDir + "/" + filename)
100 else:
101 # TODO: This will fail if `relpath` does not yet exist in `RemoteDir`.
102 sftp.put(LocalDir + "/" + relpath + "/" + filename,
103 RemoteDir + "/" + relpath + "/" + filename)
106 if __name__ == "__main__":
107 parser = argparse.ArgumentParser(description="Builds and uploads the C++ and Lua reference documentation.")
108 parser.add_argument("-u", "--upload", action="store_true", help="upload via FTP")
109 args = parser.parse_args()
111 CafuRoot = "."
112 BuildDoxygenDocs(CafuRoot)
114 if args.upload:
115 try:
116 from ftp_login import GetFtpLogin
117 except ImportError:
118 # For convenience, install the file from the related template file
119 # (which is under version control) automatically.
120 d = os.path.dirname(__file__)
121 shutil.copy(
122 os.path.join(d, "ftp_login.py.tmpl"),
123 os.path.join(d, "ftp_login.py"))
124 from ftp_login import GetFtpLogin
126 ftp_username, ftp_password = GetFtpLogin()
128 if ftp_username and ftp_password:
129 print "Uploading files..."
130 ssh = paramiko.SSHClient()
132 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
133 ssh.connect('ftp.cafu.de', username=ftp_username, password=ftp_password)
135 sftp = ssh.open_sftp()
137 Upload(sftp, CafuRoot + "/Doxygen/cpp/out/html", "cafu/api/c++")
138 Upload(sftp, CafuRoot + "/Doxygen/scripting/out/html", "cafu/api/lua")
140 sftp.close()
141 else:
142 print "No FTP login details given, not uploading."