3 |
3 |
4 # Copyright (c) 2003 - 2013 Detlev Offenbach <detlev@die-offenbachs.de> |
4 # Copyright (c) 2003 - 2013 Detlev Offenbach <detlev@die-offenbachs.de> |
5 # |
5 # |
6 |
6 |
7 """ |
7 """ |
8 Eric5 API Generator |
8 Eric5 API Generator. |
9 |
9 |
10 This is the main Python script of the API generator. It is |
10 This is the main Python script of the API generator. It is |
11 this script that gets called via the API generation interface. |
11 this script that gets called via the API generation interface. |
12 This script can be used via the commandline as well. |
12 This script can be used via the commandline as well. |
13 """ |
13 """ |
40 It prints a reference of all commandline parameters that may |
40 It prints a reference of all commandline parameters that may |
41 be used and ends the application. |
41 be used and ends the application. |
42 """ |
42 """ |
43 print("eric5_api") |
43 print("eric5_api") |
44 print() |
44 print() |
45 print("Copyright (c) 2004 - 2013 Detlev Offenbach <detlev@die-offenbachs.de>.") |
45 print("Copyright (c) 2004 - 2013 Detlev Offenbach" |
|
46 " <detlev@die-offenbachs.de>.") |
46 print() |
47 print() |
47 print("Usage:") |
48 print("Usage:") |
48 print() |
49 print() |
49 print(" eric5_api [options] files...") |
50 print(" eric5_api [options] files...") |
50 print() |
51 print() |
64 print(" -h or --help") |
65 print(" -h or --help") |
65 print(" Show this help and exit.") |
66 print(" Show this help and exit.") |
66 print(" -l language or --language=language") |
67 print(" -l language or --language=language") |
67 print(" Generate an API file for the given programming language.") |
68 print(" Generate an API file for the given programming language.") |
68 print(" Supported programming languages are:") |
69 print(" Supported programming languages are:") |
69 for lang in sorted(DocumentationTools.supportedExtensionsDictForApis.keys()): |
70 for lang in sorted( |
|
71 DocumentationTools.supportedExtensionsDictForApis.keys()): |
70 print(" * {0}".format(lang)) |
72 print(" * {0}".format(lang)) |
71 print(" The default is 'Python3'.") |
73 print(" The default is 'Python3'.") |
72 print(" This option may be repeated multiple times.") |
74 print(" This option may be repeated multiple times.") |
73 print(" -o filename or --output=filename") |
75 print(" -o filename or --output=filename") |
74 print(" Write the API information to the named file. A '%L' placeholder") |
76 print(" Write the API information to the named file." |
75 print(" is replaced by the language of the API file (see --language).") |
77 " A '%L' placeholder") |
|
78 print(" is replaced by the language of the API file" |
|
79 " (see --language).") |
76 print(" -p or --private") |
80 print(" -p or --private") |
77 print(" Include private methods and functions.") |
81 print(" Include private methods and functions.") |
78 print(" -R, -r or --recursive") |
82 print(" -R, -r or --recursive") |
79 print(" Perform a recursive search for source files.") |
83 print(" Perform a recursive search for source files.") |
80 print(" -t ext or --extension=ext") |
84 print(" -t ext or --extension=ext") |
111 |
115 |
112 import getopt |
116 import getopt |
113 |
117 |
114 try: |
118 try: |
115 opts, args = getopt.getopt(sys.argv[1:], "b:e:hl:o:pRrt:Vx:", |
119 opts, args = getopt.getopt(sys.argv[1:], "b:e:hl:o:pRrt:Vx:", |
116 ["base=", "eol=", "exclude=", "exclude-file=", "extension=", "help", |
120 ["base=", "eol=", "exclude=", "exclude-file=", "extension=", |
117 "language=", "output=", "private", "recursive", |
121 "help", "language=", "output=", "private", "recursive", |
118 "version", ]) |
122 "version", ]) |
119 except getopt.error: |
123 except getopt.error: |
120 usage() |
124 usage() |
121 |
125 |
122 excludeDirs = ["CVS", ".svn", "_svn", ".ropeproject", "_ropeproject", |
126 excludeDirs = ["CVS", ".svn", "_svn", ".ropeproject", "_ropeproject", |
123 ".eric5project", "_eric5project", "dist", "build", "doc", "docs"] |
127 ".eric5project", "_eric5project", "dist", "build", "doc", |
|
128 "docs"] |
124 excludePatterns = [] |
129 excludePatterns = [] |
125 outputFileName = "" |
130 outputFileName = "" |
126 recursive = False |
131 recursive = False |
127 basePackage = "" |
132 basePackage = "" |
128 includePrivate = False |
133 includePrivate = False |
152 elif k in ["-p", "--private"]: |
157 elif k in ["-p", "--private"]: |
153 includePrivate = True |
158 includePrivate = True |
154 elif k in ["-l", "--language"]: |
159 elif k in ["-l", "--language"]: |
155 if v not in progLanguages: |
160 if v not in progLanguages: |
156 if v not in \ |
161 if v not in \ |
157 list(DocumentationTools.supportedExtensionsDictForApis.keys()): |
162 DocumentationTools.supportedExtensionsDictForApis: |
158 sys.stderr.write("Wrong language given: {0}. Aborting\n".format(v)) |
163 sys.stderr.write( |
|
164 "Wrong language given: {0}. Aborting\n".format(v)) |
159 sys.exit(1) |
165 sys.exit(1) |
160 else: |
166 else: |
161 progLanguages.append(v) |
167 progLanguages.append(v) |
162 elif k in ["-e", "--eol"]: |
168 elif k in ["-e", "--eol"]: |
163 if v.lower() == "cr": |
169 if v.lower() == "cr": |
190 else: |
196 else: |
191 if len(progLanguages) == 1: |
197 if len(progLanguages) == 1: |
192 outputFile = outputFileName |
198 outputFile = outputFileName |
193 else: |
199 else: |
194 root, ext = os.path.splitext(outputFileName) |
200 root, ext = os.path.splitext(outputFileName) |
195 outputFile = "{0}-{1}{2}".format(root, progLanguage.lower(), ext) |
201 outputFile = "{0}-{1}{2}".format(root, progLanguage.lower(), |
|
202 ext) |
196 basesFile = os.path.splitext(outputFile)[0] + '.bas' |
203 basesFile = os.path.splitext(outputFile)[0] + '.bas' |
197 |
204 |
198 for arg in args: |
205 for arg in args: |
199 if os.path.isdir(arg): |
206 if os.path.isdir(arg): |
200 if os.path.exists(os.path.join(arg, |
207 if os.path.exists(os.path.join(arg, |
201 Utilities.joinext("__init__", ".py"))): |
208 Utilities.joinext("__init__", ".py"))): |
202 basename = os.path.dirname(arg) |
209 basename = os.path.dirname(arg) |
203 if arg == '.': |
210 if arg == '.': |
204 sys.stderr.write("The directory '.' is a package.\n") |
211 sys.stderr.write("The directory '.' is a package.\n") |
205 sys.stderr.write("Please repeat the call giving its real name.\n") |
212 sys.stderr.write( |
|
213 "Please repeat the call giving its real name.\n") |
206 sys.stderr.write("Ignoring the directory.\n") |
214 sys.stderr.write("Ignoring the directory.\n") |
207 continue |
215 continue |
208 else: |
216 else: |
209 basename = arg |
217 basename = arg |
210 if basename: |
218 if basename: |
221 for filename in sorted(names): |
229 for filename in sorted(names): |
222 inpackage = False |
230 inpackage = False |
223 if os.path.isdir(filename): |
231 if os.path.isdir(filename): |
224 files = [] |
232 files = [] |
225 for ext in supportedExtensions: |
233 for ext in supportedExtensions: |
226 files.extend(glob.glob(os.path.join(filename, |
234 files.extend(glob.glob(os.path.join( |
227 Utilities.joinext("*", ext)))) |
235 filename, Utilities.joinext("*", ext)))) |
228 initFile = os.path.join(filename, |
236 initFile = os.path.join( |
229 Utilities.joinext("__init__", ext)) |
237 filename, Utilities.joinext("__init__", ext)) |
230 if initFile in files: |
238 if initFile in files: |
231 inpackage = True |
239 inpackage = True |
232 files.remove(initFile) |
240 files.remove(initFile) |
233 files.insert(0, initFile) |
241 files.insert(0, initFile) |
234 elif progLanguage != "Python3": |
242 elif progLanguage != "Python3": |
235 # assume package |
243 # assume package |
236 inpackage = True |
244 inpackage = True |
237 else: |
245 else: |
238 if Utilities.isWindowsPlatform() and glob.has_magic(filename): |
246 if Utilities.isWindowsPlatform() and \ |
|
247 glob.has_magic(filename): |
239 files = glob.glob(filename) |
248 files = glob.glob(filename) |
240 else: |
249 else: |
241 files = [filename] |
250 files = [filename] |
242 |
251 |
243 for file in files: |
252 for file in files: |
251 |
260 |
252 try: |
261 try: |
253 module = Utilities.ModuleParser.readModule(file, |
262 module = Utilities.ModuleParser.readModule(file, |
254 basename=basename, inpackage=inpackage) |
263 basename=basename, inpackage=inpackage) |
255 apiGenerator = APIGenerator(module) |
264 apiGenerator = APIGenerator(module) |
256 api = apiGenerator.genAPI(True, basePackage, includePrivate) |
265 api = apiGenerator.genAPI(True, basePackage, |
|
266 includePrivate) |
257 bases = apiGenerator.genBases(includePrivate) |
267 bases = apiGenerator.genBases(includePrivate) |
258 except IOError as v: |
268 except IOError as v: |
259 sys.stderr.write("{0} error: {1}\n".format(file, v[1])) |
269 sys.stderr.write("{0} error: {1}\n".format(file, v[1])) |
260 continue |
270 continue |
261 except ImportError as v: |
271 except ImportError as v: |
266 if not apiEntry in apis: |
276 if not apiEntry in apis: |
267 apis.append(apiEntry) |
277 apis.append(apiEntry) |
268 for basesEntry in bases: |
278 for basesEntry in bases: |
269 if bases[basesEntry]: |
279 if bases[basesEntry]: |
270 basesDict[basesEntry] = bases[basesEntry][:] |
280 basesDict[basesEntry] = bases[basesEntry][:] |
271 sys.stdout.write("-- {0} -- {1} ok\n".format(progLanguage, file)) |
281 sys.stdout.write("-- {0} -- {1} ok\n".format( |
|
282 progLanguage, file)) |
272 |
283 |
273 outdir = os.path.dirname(outputFile) |
284 outdir = os.path.dirname(outputFile) |
274 if outdir and not os.path.exists(outdir): |
285 if outdir and not os.path.exists(outdir): |
275 os.makedirs(outdir) |
286 os.makedirs(outdir) |
276 try: |
287 try: |