2 # -*- coding: utf-8 -*-
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
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
25 def FindSConsBuildDir(root
):
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.
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"):
37 for compiler
in ["g++"]:
38 path
= "build/" + sys
.platform
+ "/" + compiler
+ "/release"
39 if os
.path
.isfile(root
+ "/" + path
+ "/CaBSP/CaBSP"):
42 raise Exception("Could not find the SCons build directory.")
45 def BuildDoxygenDocs(SourceDir
):
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`.
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":
67 with
open(root
+ "/" + filename
, 'r') as tmplFile
:
68 with
open(root
+ "/../src/" + filename
, 'r') as srcFile
:
69 srcLines
= srcFile
.readlines()
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
]:
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
):
89 Recursively uploads the contents of `LocalDir` to `RemoteDir`,
90 using the already established (opened) FTP connection `sftp`.
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
:
98 sftp
.put(LocalDir
+ "/" + filename
,
99 RemoteDir
+ "/" + filename
)
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()
112 BuildDoxygenDocs(CafuRoot
)
116 from ftp_login
import GetFtpLogin
118 # For convenience, install the file from the related template file
119 # (which is under version control) automatically.
120 d
= os
.path
.dirname(__file__
)
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")
142 print "No FTP login details given, not uploading."