eric5_api.py

changeset 908
d00447340771
parent 791
9ec2ac20e54e
child 945
8cd4d08fa9f6
equal deleted inserted replaced
907:74904673b366 908:d00447340771
1 #!/usr/bin/env python3
2 # -*- coding: utf-8 -*-
3
4 # Copyright (c) 2003 - 2011 Detlev Offenbach <detlev@die-offenbachs.de>
5 #
6
7 """
8 Eric5 API Generator
9
10 This is the main Python script of the API generator. It is
11 this script that gets called via the API generation interface.
12 This script can be used via the commandline as well.
13 """
14
15 import glob
16 import os
17 import sys
18 import fnmatch
19
20 import Utilities.ModuleParser
21 from DocumentationTools.APIGenerator import APIGenerator
22 from UI.Info import Version
23 import Utilities
24 import DocumentationTools
25
26 def usage():
27 """
28 Function to print some usage information.
29
30 It prints a reference of all commandline parameters that may
31 be used and ends the application.
32 """
33 print("eric5_api")
34 print()
35 print("Copyright (c) 2004 - 2011 Detlev Offenbach <detlev@die-offenbachs.de>.")
36 print()
37 print("Usage:")
38 print()
39 print(" eric5_api [options] files...")
40 print()
41 print("where files can be either python modules, package")
42 print("directories or ordinary directories.")
43 print()
44 print("Options:")
45 print()
46 print(" -b name or --base=name")
47 print(" Use the given name as the name of the base package.")
48 print(" -e eol-type or --eol=eol-type")
49 print(" Use the given eol type to terminate lines.")
50 print(" Valid values are 'cr', 'lf' and 'crlf'.")
51 print(" --exclude-file=pattern")
52 print(" Specify a filename pattern of files to be excluded.")
53 print(" This option may be repeated multiple times.")
54 print(" -h or --help")
55 print(" Show this help and exit.")
56 print(" -l language or --language=language")
57 print(" Generate an API file for the given programming language.")
58 print(" Supported programming languages are:")
59 print(" -o filename or --output=filename")
60 print(" Write the API information to the named file. A '%L' placeholder")
61 print(" is replaced by the language of the API file (see --language).")
62 print(" -p or --private")
63 print(" Include private methods and functions.")
64 print(" -R, -r or --recursive")
65 print(" Perform a recursive search for source files.")
66 print(" -t ext or --extension=ext")
67 print(" Add the given extension to the list of file extensions.")
68 print(" This option may be given multiple times.")
69 print(" -V or --version")
70 print(" Show version information and exit.")
71 print(" -x directory or --exclude=directory")
72 print(" Specify a directory basename to be excluded.")
73 print(" This option may be repeated multiple times.")
74 for lang in sorted(DocumentationTools.supportedExtensionsDictForApis.keys()):
75 print(" * {0}".format(lang))
76 print(" The default is 'Python3'.")
77 print(" This option may be repeated multiple times.")
78 sys.exit(1)
79
80 def version():
81 """
82 Function to show the version information.
83 """
84 print("""eric5_api {0}
85
86 Eric5 API generator.
87
88 Copyright (c) 2004 - 2011 Detlev Offenbach <detlev@die-offenbachs.de>
89 This is free software; see the LICENSE.GPL3 for copying conditions.
90 There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
91 PARTICULAR PURPOSE.""".format(Version))
92 sys.exit(1)
93
94 def main():
95 """
96 Main entry point into the application.
97 """
98 global supportedExtensions
99
100 import getopt
101
102 try:
103 opts, args = getopt.getopt(sys.argv[1:], "b:e:hl:o:pRrt:Vx:",
104 ["base=", "eol=", "exclude=", "exclude-file=", "extension=", "help",
105 "language=", "output=", "private", "recursive",
106 "version", ])
107 except getopt.error:
108 usage()
109
110 excludeDirs = ["CVS", ".svn", "_svn", ".ropeproject", "_ropeproject",
111 ".eric5project", "_eric5project", "dist", "build", "doc", "docs"]
112 excludePatterns = []
113 outputFileName = ""
114 recursive = False
115 basePackage = ""
116 includePrivate = False
117 progLanguages = []
118 extensions = []
119 newline = None
120
121 for k, v in opts:
122 if k in ["-o", "--output"]:
123 outputFileName = v
124 elif k in ["-R", "-r", "--recursive"]:
125 recursive = True
126 elif k in ["-x", "--exclude"]:
127 excludeDirs.append(v)
128 elif k == "--exclude-file":
129 excludePatterns.append(v)
130 elif k in ["-h", "--help"]:
131 usage()
132 elif k in ["-V", "--version"]:
133 version()
134 elif k in ["-t", "--extension"]:
135 if not v.startswith("."):
136 v = ".{0}".format(v)
137 extensions.append(v)
138 elif k in ["-b", "--base"]:
139 basePackage = v
140 elif k in ["-p", "--private"]:
141 includePrivate = True
142 elif k in ["-l", "--language"]:
143 if v not in progLanguages:
144 if v not in \
145 list(DocumentationTools.supportedExtensionsDictForApis.keys()):
146 sys.stderr.write("Wrong language given: {0}. Aborting\n".format(v))
147 sys.exit(1)
148 else:
149 progLanguages.append(v)
150 elif k in ["-e", "--eol"]:
151 if v.lower() == "cr":
152 newline = '\r'
153 elif v.lower() == "lf":
154 newline = '\n'
155 elif v.lower() == "crlf":
156 newline = '\r\n'
157
158 if not args:
159 usage()
160
161 if outputFileName == "":
162 sys.stderr.write("No output file given. Aborting\n")
163 sys.exit(1)
164
165 if len(progLanguages) == 0:
166 progLanguages = ["Python3"]
167
168 for progLanguage in sorted(progLanguages):
169 basename = ""
170 apis = []
171
172 supportedExtensions = \
173 DocumentationTools.supportedExtensionsDictForApis[progLanguage]
174 supportedExtensions.extend(extensions)
175 if "%L" in outputFileName:
176 outputFile = outputFileName.replace("%L", progLanguage)
177 else:
178 if len(progLanguages) == 1:
179 outputFile = outputFileName
180 else:
181 root, ext = os.path.splitext(outputFileName)
182 outputFile = "{0}-{1}{2}".format(root, progLanguage.lower(), ext)
183
184 for arg in args:
185 if os.path.isdir(arg):
186 if os.path.exists(os.path.join(arg,
187 Utilities.joinext("__init__", ".py"))):
188 basename = os.path.dirname(arg)
189 if arg == '.':
190 sys.stderr.write("The directory '.' is a package.\n")
191 sys.stderr.write("Please repeat the call giving its real name.\n")
192 sys.stderr.write("Ignoring the directory.\n")
193 continue
194 else:
195 basename = arg
196 if basename:
197 basename = "{0}{1}".format(basename, os.sep)
198
199 if recursive and not os.path.islink(arg):
200 names = [arg] + Utilities.getDirs(arg, excludeDirs)
201 else:
202 names = [arg]
203 else:
204 basename = ""
205 names = [arg]
206
207 for filename in sorted(names):
208 inpackage = False
209 if os.path.isdir(filename):
210 files = []
211 for ext in supportedExtensions:
212 files.extend(glob.glob(os.path.join(filename,
213 Utilities.joinext("*", ext))))
214 initFile = os.path.join(filename,
215 Utilities.joinext("__init__", ext))
216 if initFile in files:
217 inpackage = True
218 files.remove(initFile)
219 files.insert(0, initFile)
220 elif progLanguage != "Python3":
221 # assume package
222 inpackage = True
223 else:
224 if Utilities.isWindowsPlatform() and glob.has_magic(filename):
225 files = glob.glob(filename)
226 else:
227 files = [filename]
228
229 for file in files:
230 skipIt = False
231 for pattern in excludePatterns:
232 if fnmatch.fnmatch(os.path.basename(file), pattern):
233 skipIt = True
234 break
235 if skipIt:
236 continue
237
238 try:
239 module = Utilities.ModuleParser.readModule(file,
240 basename = basename, inpackage = inpackage)
241 apiGenerator = APIGenerator(module)
242 api = apiGenerator.genAPI(True, basePackage, includePrivate)
243 except IOError as v:
244 sys.stderr.write("{0} error: {1}\n".format(file, v[1]))
245 continue
246 except ImportError as v:
247 sys.stderr.write("{0} error: {1}\n".format(file, v))
248 continue
249
250 for apiEntry in api:
251 if not apiEntry in apis:
252 apis.append(apiEntry)
253 sys.stdout.write("-- {0} -- {1} ok\n".format(progLanguage, file))
254
255 outdir = os.path.dirname(outputFile)
256 if outdir and not os.path.exists(outdir):
257 os.makedirs(outdir)
258 try:
259 out = open(outputFile, "w", encoding = "utf-8", newline = newline)
260 out.write("\n".join(sorted(apis)) + "\n")
261 out.close()
262 except IOError as v:
263 sys.stderr.write("{0} error: {1}\n".format(outputFile, v[1]))
264 sys.exit(3)
265
266 sys.stdout.write('\nDone.\n')
267 sys.exit(0)
268
269 if __name__ == '__main__':
270 main()

eric ide

mercurial