23 from eric7.SystemUtilities import FileSystemUtilities, OSUtilities |
23 from eric7.SystemUtilities import FileSystemUtilities, OSUtilities |
24 from eric7.UI.Info import Version |
24 from eric7.UI.Info import Version |
25 from eric7.Utilities import ModuleParser |
25 from eric7.Utilities import ModuleParser |
26 |
26 |
27 |
27 |
28 def usage(): |
28 def createArgumentParser(): |
29 """ |
29 """ |
30 Function to print some usage information. |
30 Function to create an argument parser. |
31 |
31 |
32 It prints a reference of all commandline parameters that may |
32 @return created argument parser object |
33 be used and ends the application. |
33 @rtype argparse.ArgumentParser |
34 """ |
34 """ |
35 print("eric7_api") |
35 parser = argparse.ArgumentParser( |
36 print() |
36 description=( |
37 print("Copyright (c) 2004 - 2023 Detlev Offenbach <detlev@die-offenbachs.de>.") |
37 "Create API files to be used by 'QScintilla' or the 'eric Assistant'" |
38 print() |
38 " plugin." |
39 print("Usage:") |
39 ), |
40 print() |
40 epilog="Copyright (c) 2004 - 2023 Detlev Offenbach <detlev@die-offenbachs.de>.", |
41 print(" eric7_api [options] files...") |
41 add_help=False, |
42 print() |
42 ) |
43 print("where files can be either python modules, package") |
43 |
44 print("directories or ordinary directories.") |
44 parser.add_argument( |
45 print() |
45 "file", |
46 print("Options:") |
46 nargs="*", |
47 print() |
47 help="'file' can be either python modules, package directories or ordinary" |
48 print(" -b name or --base=name") |
48 " directories.", |
49 print(" Use the given name as the name of the base package.") |
49 ) |
50 print(" -e eol-type or --eol=eol-type") |
50 parser.add_argument( |
51 print(" Use the given eol type to terminate lines.") |
51 "-b", |
52 print(" Valid values are 'cr', 'lf' and 'crlf'.") |
52 "--base", |
53 print(" --exclude-file=pattern") |
53 default="", |
54 print(" Specify a filename pattern of files to be excluded.") |
54 help="Use the given name as the name of the base package.", |
55 print(" This option may be repeated multiple times.") |
55 ) |
56 print(" -h or --help") |
56 parser.add_argument( |
57 print(" Show this help and exit.") |
57 "-e", |
58 print(" -i or --ignore") |
58 "--eol", |
59 print(" Ignore the set of builtin modules") |
59 choices=["cr", "lf", "crlf"], |
60 print(" -l language or --language=language") |
60 help="Use the given eol type to terminate lines.", |
61 print(" Generate an API file for the given programming language.") |
61 ) |
62 print(" Supported programming languages are:") |
62 parser.add_argument( |
63 for lang in sorted(DocumentationTools.supportedExtensionsDictForApis.keys()): |
63 "--exclude-file", |
64 print(" * {0}".format(lang)) |
64 action="append", |
65 print(" The default is 'Python3'.") |
65 default=[], |
66 print(" This option may be repeated multiple times.") |
66 help="Specify a filename pattern of files to be excluded. This option may be" |
67 print(" -o filename or --output=filename") |
67 " repeated multiple times.", |
68 print( |
68 ) |
69 " Write the API information to the named file." |
69 parser.add_argument( |
70 " A '%L' placeholder" # __IGNORE_WARNING_M601__ |
70 "-h", "--help", action="store_true", help="Show this help and exit." |
71 ) |
71 ) |
72 print(" is replaced by the language of the API file (see --language).") |
72 parser.add_argument( |
73 print(" -p or --private") |
73 "-i", |
74 print(" Include private methods and functions.") |
74 "--ignore", |
75 print(" -R, -r or --recursive") |
75 action="store_true", |
76 print(" Perform a recursive search for source files.") |
76 help="Ignore the set of builtin modules.", |
77 print(" -t ext or --extension=ext") |
77 ) |
78 print(" Add the given extension to the list of file extensions.") |
78 parser.add_argument( |
79 print(" This option may be given multiple times.") |
79 "-l", |
80 print(" -V or --version") |
80 "--language", |
81 print(" Show version information and exit.") |
81 action="append", |
82 print(" -x directory or --exclude=directory") |
82 default=[], |
83 print(" Specify a directory basename to be excluded.") |
83 choices=DocumentationTools.supportedExtensionsDictForApis.keys(), |
84 print(" This option may be repeated multiple times.") |
84 help="Generate an API file for the given programming language. The default" |
85 sys.exit(1) |
85 " is 'Python3'. This option may be repeated multiple times.", |
|
86 ) |
|
87 parser.add_argument( |
|
88 "-o", |
|
89 "--output", |
|
90 default="", |
|
91 help="Write the API information to the named file. A '%%L'" # noqa: M601 |
|
92 " placeholder is replaced by the language of the API file (see --language).", |
|
93 ) |
|
94 parser.add_argument( |
|
95 "-p", |
|
96 "--private", |
|
97 action="store_true", |
|
98 help="Include private methods and functions.", |
|
99 ) |
|
100 parser.add_argument( |
|
101 "-R", |
|
102 "-r", |
|
103 "--recursive", |
|
104 action="store_true", |
|
105 help="Perform a recursive search for source files.", |
|
106 ) |
|
107 parser.add_argument( |
|
108 "-t", |
|
109 "--extension", |
|
110 action="append", |
|
111 default=[], |
|
112 help="Add the given extension to the list of file extensions. This option may" |
|
113 " be given multiple times.", |
|
114 ) |
|
115 parser.add_argument( |
|
116 "-V", |
|
117 "--version", |
|
118 action="store_true", |
|
119 help="Show version information and exit.", |
|
120 ) |
|
121 parser.add_argument( |
|
122 "-x", |
|
123 "--exclude", |
|
124 action="append", |
|
125 default=[], |
|
126 help="Specify a directory basename to be excluded. This option may be repeated" |
|
127 " multiple times.", |
|
128 ) |
|
129 |
|
130 return parser |
86 |
131 |
87 |
132 |
88 def version(): |
133 def version(): |
89 """ |
134 """ |
90 Function to show the version information. |
135 Function to show the version information. |
141 ".eric7project", |
182 ".eric7project", |
142 "dist", |
183 "dist", |
143 "build", |
184 "build", |
144 "doc", |
185 "doc", |
145 "docs", |
186 "docs", |
|
187 ] + args.exclude |
|
188 excludePatterns = args.exclude_file |
|
189 outputFileName = args.output |
|
190 recursive = args.recursive |
|
191 basePackage = args.base |
|
192 includePrivate = args.private |
|
193 progLanguages = args.language |
|
194 extensions = [ |
|
195 ext if ext.startswith(".") else ".{0}".format(ext) for ext in args.extension |
146 ] |
196 ] |
147 excludePatterns = [] |
197 ignoreBuiltinModules = args.ignore |
148 outputFileName = "" |
198 newline = { |
149 recursive = False |
199 "cr": "\r", |
150 basePackage = "" |
200 "lf": "\n", |
151 includePrivate = False |
201 "crlf": "\r\n", |
152 progLanguages = [] |
202 }[args.eol] |
153 extensions = [] |
|
154 newline = None |
|
155 ignoreBuiltinModules = False |
|
156 |
|
157 for k, v in opts: |
|
158 if k in ["-o", "--output"]: |
|
159 outputFileName = v |
|
160 elif k in ["-R", "-r", "--recursive"]: |
|
161 recursive = True |
|
162 elif k in ["-x", "--exclude"]: |
|
163 excludeDirs.append(v) |
|
164 elif k == "--exclude-file": |
|
165 excludePatterns.append(v) |
|
166 elif k in ["-h", "--help"]: |
|
167 usage() |
|
168 elif k in ["-i", "--ignore"]: |
|
169 ignoreBuiltinModules = True |
|
170 elif k in ["-V", "--version"]: |
|
171 version() |
|
172 elif k in ["-t", "--extension"]: |
|
173 if not v.startswith("."): |
|
174 v = ".{0}".format(v) |
|
175 extensions.append(v) |
|
176 elif k in ["-b", "--base"]: |
|
177 basePackage = v |
|
178 elif k in ["-p", "--private"]: |
|
179 includePrivate = True |
|
180 elif k in ["-l", "--language"]: |
|
181 if v not in progLanguages: |
|
182 if v not in DocumentationTools.supportedExtensionsDictForApis: |
|
183 sys.stderr.write("Wrong language given: {0}. Aborting\n".format(v)) |
|
184 sys.exit(1) |
|
185 else: |
|
186 progLanguages.append(v) |
|
187 elif k in ["-e", "--eol"]: |
|
188 if v.lower() == "cr": |
|
189 newline = "\r" |
|
190 elif v.lower() == "lf": |
|
191 newline = "\n" |
|
192 elif v.lower() == "crlf": |
|
193 newline = "\r\n" |
|
194 |
|
195 if not args: |
|
196 usage() |
|
197 |
|
198 if outputFileName == "": |
|
199 sys.stderr.write("No output file given. Aborting\n") |
|
200 sys.exit(1) |
|
201 |
203 |
202 if len(progLanguages) == 0: |
204 if len(progLanguages) == 0: |
203 progLanguages = ["Python3"] |
205 progLanguages = ["Python3"] |
204 |
206 |
205 for progLanguage in sorted(progLanguages): |
207 for progLanguage in sorted(progLanguages): |
225 else: |
227 else: |
226 root, ext = os.path.splitext(outputFileName) |
228 root, ext = os.path.splitext(outputFileName) |
227 outputFile = "{0}-{1}{2}".format(root, progLanguage.lower(), ext) |
229 outputFile = "{0}-{1}{2}".format(root, progLanguage.lower(), ext) |
228 basesFile = os.path.splitext(outputFile)[0] + ".bas" |
230 basesFile = os.path.splitext(outputFile)[0] + ".bas" |
229 |
231 |
230 for arg in args: |
232 for argsfile in args.file: |
231 if os.path.isdir(arg): |
233 if os.path.isdir(argsfile): |
232 if os.path.exists( |
234 if os.path.exists( |
233 os.path.join(arg, FileSystemUtilities.joinext("__init__", ".py")) |
235 os.path.join( |
|
236 argsfile, FileSystemUtilities.joinext("__init__", ".py") |
|
237 ) |
234 ): |
238 ): |
235 basename = os.path.dirname(arg) |
239 basename = os.path.dirname(argsfile) |
236 if arg == ".": |
240 if argsfile == ".": |
237 sys.stderr.write("The directory '.' is a package.\n") |
241 sys.stderr.write("The directory '.' is a package.\n") |
238 sys.stderr.write( |
242 sys.stderr.write( |
239 "Please repeat the call giving its real name.\n" |
243 "Please repeat the call giving its real name.\n" |
240 ) |
244 ) |
241 sys.stderr.write("Ignoring the directory.\n") |
245 sys.stderr.write("Ignoring the directory.\n") |
242 continue |
246 continue |
243 else: |
247 else: |
244 basename = arg |
248 basename = argsfile |
245 if basename: |
249 if basename: |
246 basename = "{0}{1}".format(basename, os.sep) |
250 basename = "{0}{1}".format(basename, os.sep) |
247 |
251 |
248 if recursive and not os.path.islink(arg): |
252 if recursive and not os.path.islink(argsfile): |
249 names = [arg] + FileSystemUtilities.getDirs(arg, excludeDirs) |
253 names = [argsfile] + FileSystemUtilities.getDirs( |
|
254 argsfile, excludeDirs |
|
255 ) |
250 else: |
256 else: |
251 names = [arg] |
257 names = [argsfile] |
252 else: |
258 else: |
253 basename = "" |
259 basename = "" |
254 names = [arg] |
260 names = [argsfile] |
255 |
261 |
256 for filename in sorted(names): |
262 for filename in sorted(names): |
257 inpackage = False |
263 inpackage = False |
258 if os.path.isdir(filename): |
264 if os.path.isdir(filename): |
259 files = [] |
265 files = [] |