109 input("Press enter to continue...") # secok |
113 input("Press enter to continue...") # secok |
110 |
114 |
111 os.chdir(currDir) |
115 os.chdir(currDir) |
112 |
116 |
113 sys.exit(rcode) |
117 sys.exit(rcode) |
114 |
|
115 |
|
116 def usage(rcode=2): |
|
117 """ |
|
118 Display a usage message and exit. |
|
119 |
|
120 @param rcode the return code passed back to the calling process. |
|
121 """ |
|
122 global progName, modDir, distDir, apisDir |
|
123 global macAppBundleName, macAppBundlePath, macPythonExe |
|
124 |
|
125 print() |
|
126 print("Usage:") |
|
127 if sys.platform == "darwin": |
|
128 print( |
|
129 " {0} [-chvxz] [-a dir] [-b dir] [-d dir] [-f file] [-i dir]" |
|
130 " [-m name] [-n path] [-p python] [--help] [--no-apis]" |
|
131 " [--no-info] [--with-tools] [--verbose] [--yes]".format(progName) |
|
132 ) |
|
133 elif sys.platform.startswith(("win", "cygwin")): |
|
134 print( |
|
135 " {0} [-chvxz] [-a dir] [-b dir] [-d dir] [-f file]" |
|
136 " [--clean-desktop] [--help] [--no-apis] [--no-info]" |
|
137 " [--with-tools] [--verbose] [--yes]".format(progName) |
|
138 ) |
|
139 else: |
|
140 print( |
|
141 " {0} [-chvxz] [-a dir] [-b dir] [-d dir] [-f file] [-i dir]" |
|
142 " [--help] [--no-apis] [--no-info] [--with-tools] [--verbose]" |
|
143 " [--yes]".format(progName) |
|
144 ) |
|
145 print("where:") |
|
146 print(" -h, --help display this help message") |
|
147 print(" -a dir where the API files will be installed") |
|
148 if apisDir: |
|
149 print(" (default: {0})".format(apisDir)) |
|
150 else: |
|
151 print(" (no default value)") |
|
152 print(" --no-apis don't install API files") |
|
153 print(" -b dir where the binaries will be installed") |
|
154 print(" (default: {0})".format(platBinDir)) |
|
155 print(" -d dir where eric python files will be installed") |
|
156 print(" (default: {0})".format(modDir)) |
|
157 print(" -f file configuration file naming the various installation paths") |
|
158 if not sys.platform.startswith(("win", "cygwin")): |
|
159 print(" -i dir temporary install prefix") |
|
160 print(" (default: {0})".format(distDir)) |
|
161 if sys.platform == "darwin": |
|
162 print(" -m name name of the Mac app bundle") |
|
163 print(" (default: {0})".format(macAppBundleName)) |
|
164 print(" -n path path of the directory the Mac app bundle will") |
|
165 print(" be created in") |
|
166 print(" (default: {0})".format(macAppBundlePath)) |
|
167 print(" -p python path of the python executable") |
|
168 print(" (default: {0})".format(macPythonExe)) |
|
169 print(" -c don't cleanup old installation first") |
|
170 print(" -v, --verbose print some more information") |
|
171 print(" -x don't perform dependency checks (use on your own risk)") |
|
172 print(" -z don't compile the installed python files") |
|
173 print(" --yes answer 'yes' to all questions") |
|
174 print() |
|
175 if sys.platform.startswith(("win", "cygwin")): |
|
176 print(" --clean-desktop delete desktop links before installation") |
|
177 print(" --no-info don't create the install info file") |
|
178 print(" --with-tools install qt6-applications") |
|
179 print() |
|
180 print("The file given to the -f option must be valid Python code defining a") |
|
181 print( |
|
182 "dictionary called 'cfg' with the keys 'ericDir', 'ericPixDir'," |
|
183 " 'ericIconDir'," |
|
184 ) |
|
185 print("'ericDTDDir', 'ericCSSDir', 'ericStylesDir', 'ericThemesDir',") |
|
186 print(" 'ericDocDir', ericExamplesDir',") |
|
187 print("'ericTranslationsDir', 'ericTemplatesDir', 'ericCodeTemplatesDir',") |
|
188 print("'ericOthersDir','bindir', 'mdir' and 'apidir.") |
|
189 print( |
|
190 "These define the directories for the installation of the various" |
|
191 " parts of eric." |
|
192 ) |
|
193 |
|
194 exit(rcode) |
|
195 |
118 |
196 |
119 |
197 def initGlobals(): |
120 def initGlobals(): |
198 """ |
121 """ |
199 Module function to set the values of globals that need more than a |
122 Module function to set the values of globals that need more than a |
1639 print("Sorry, please install PyQt6.") |
1556 print("Sorry, please install PyQt6.") |
1640 print("Error: {0}".format(msg)) |
1557 print("Error: {0}".format(msg)) |
1641 exit(1) |
1558 exit(1) |
1642 print("Found PyQt6") |
1559 print("Found PyQt6") |
1643 |
1560 |
1644 try: |
1561 pyuic = "pyuic6" |
1645 pyuic = "pyuic6" |
1562 if importlib.util.find_spec("PyQt6.uic") is None: |
1646 from PyQt6 import uic # __IGNORE_WARNING__ |
|
1647 except ImportError as err: |
|
1648 print("Sorry, {0} is not installed.".format(pyuic)) |
1563 print("Sorry, {0} is not installed.".format(pyuic)) |
1649 if verbose: |
|
1650 print("Error: {0}".format(err)) |
|
1651 exit(1) |
1564 exit(1) |
1652 print("Found {0}".format(pyuic)) |
1565 print("Found {0}".format(pyuic)) |
1653 |
1566 |
1654 try: |
1567 if importlib.util.find_spec("PyQt6.QtWebEngineWidgets") is None: |
1655 from PyQt6 import QtWebEngineWidgets # __IGNORE_WARNING__ |
|
1656 except ImportError as err: |
|
1657 if isSudo: |
1568 if isSudo: |
1658 print("Optional 'PyQt6-WebEngine' could not be detected.") |
1569 print("Optional 'PyQt6-WebEngine' could not be detected.") |
1659 else: |
1570 else: |
1660 msg = "Optional 'PyQt6-WebEngine' could not be detected.{0}".format( |
1571 msg = "Optional 'PyQt6-WebEngine' could not be detected." |
1661 "\nError: {0}".format(err) if verbose else "" |
|
1662 ) |
|
1663 pipInstall( |
1572 pipInstall( |
1664 "PyQt6-WebEngine>={0}".format( |
1573 "PyQt6-WebEngine>={0}".format( |
1665 versionToStr(requiredVersions["pyqt6-webengine"]) |
1574 versionToStr(requiredVersions["pyqt6-webengine"]) |
1666 ), |
1575 ), |
1667 msg, |
1576 msg, |
1668 ) |
1577 ) |
1669 print("Found PyQt6-WebEngine") |
1578 print("Found PyQt6-WebEngine") |
1670 |
1579 |
1671 try: |
1580 if importlib.util.find_spec("PyQt6.QtCharts") is None: |
1672 from PyQt6 import QtCharts # __IGNORE_WARNING__ |
|
1673 except ImportError as err: |
|
1674 if isSudo: |
1581 if isSudo: |
1675 print("Optional 'PyQt6-Charts' could not be detected.") |
1582 print("Optional 'PyQt6-Charts' could not be detected.") |
1676 else: |
1583 else: |
1677 msg = "Optional 'PyQt6-Charts' could not be detected.{0}".format( |
1584 msg = "Optional 'PyQt6-Charts' could not be detected." |
1678 "\nError: {0}".format(err) if verbose else "" |
|
1679 ) |
|
1680 pipInstall( |
1585 pipInstall( |
1681 "PyQt6-Charts>={0}".format( |
1586 "PyQt6-Charts>={0}".format( |
1682 versionToStr(requiredVersions["pyqt6-charts"]) |
1587 versionToStr(requiredVersions["pyqt6-charts"]) |
1683 ), |
1588 ), |
1684 msg, |
1589 msg, |
1685 ) |
1590 ) |
1686 print("Found PyQt6-Charts") |
1591 print("Found PyQt6-Charts") |
1687 |
1592 |
1688 try: |
1593 if importlib.util.find_spec("PyQt6.Qsci") is None: |
1689 from PyQt6 import Qsci # __IGNORE_WARNING__ |
1594 msg = "'PyQt6-QScintilla' could not be detected." |
1690 except ImportError as err: |
|
1691 msg = "'PyQt6-QScintilla' could not be detected.{0}".format( |
|
1692 "\nError: {0}".format(err) if verbose else "" |
|
1693 ) |
|
1694 installed = not isSudo and pipInstall( |
1595 installed = not isSudo and pipInstall( |
1695 "PyQt6-QScintilla>={0}".format( |
1596 "PyQt6-QScintilla>={0}".format( |
1696 versionToStr(requiredVersions["pyqt6-qscintilla"]) |
1597 versionToStr(requiredVersions["pyqt6-qscintilla"]) |
1697 ), |
1598 ), |
1698 msg, |
1599 msg, |
1699 ) |
1600 ) |
1700 if installed: |
1601 message = None if installed else "PyQt6-QScintilla could not be installed." |
1701 # try to import it again |
|
1702 try: |
|
1703 from PyQt6 import Qsci # __IGNORE_WARNING__ |
|
1704 |
|
1705 message = None |
|
1706 except ImportError as msg: |
|
1707 message = str(msg) |
|
1708 else: |
|
1709 message = "PyQt6-QScintilla could not be installed." |
|
1710 if message: |
1602 if message: |
1711 print("Sorry, please install QScintilla2 and") |
1603 print("Sorry, please install QScintilla2 and") |
1712 print("its PyQt6 wrapper.") |
1604 print("its PyQt6 wrapper.") |
1713 print("Error: {0}".format(message)) |
1605 print("Error: {0}".format(message)) |
1714 exit(1) |
1606 exit(1) |
2180 """ |
2077 """ |
2181 majorVersion, minorVersion = sys.version_info[:2] |
2078 majorVersion, minorVersion = sys.version_info[:2] |
2182 return "eric7 (Python {0}.{1})".format(majorVersion, minorVersion) |
2079 return "eric7 (Python {0}.{1})".format(majorVersion, minorVersion) |
2183 |
2080 |
2184 |
2081 |
|
2082 def createArgumentParser(): |
|
2083 """ |
|
2084 Function to create an argument parser. |
|
2085 |
|
2086 @return created argument parser object |
|
2087 @rtype argparse.ArgumentParser |
|
2088 """ |
|
2089 parser = argparse.ArgumentParser( |
|
2090 description="Install eric7 from the source code tree.", |
|
2091 epilog="The file given to the -f option must be valid Python code defining a" |
|
2092 "dictionary called 'cfg' with the keys 'ericDir', 'ericPixDir', ericIconDir'," |
|
2093 " 'ericDTDDir', 'ericCSSDir', 'ericStylesDir', 'ericThemesDir', ericDocDir'," |
|
2094 " ericExamplesDir', ericTranslationsDir', 'ericTemplatesDir'," |
|
2095 " 'ericCodeTemplatesDir', ericOthersDir','bindir', 'mdir' and 'apidir." |
|
2096 "These define the directories for the installation of the various parts of" |
|
2097 " eric.", |
|
2098 ) |
|
2099 |
|
2100 parser.add_argument( |
|
2101 "-a", |
|
2102 metavar="dir", |
|
2103 default=apisDir if apisDir else None, |
|
2104 help="directory where the API files will be installed ({0})".format( |
|
2105 "default: {0}".format(apisDir) if apisDir else "no default value" |
|
2106 ), |
|
2107 ) |
|
2108 parser.add_argument( |
|
2109 "--no-apis", |
|
2110 action="store_true", |
|
2111 help="don't install API files", |
|
2112 ) |
|
2113 parser.add_argument( |
|
2114 "-b", |
|
2115 metavar="dir", |
|
2116 default=platBinDir, |
|
2117 help="directory where the binaries will be installed (default: {0})".format( |
|
2118 platBinDir |
|
2119 ), |
|
2120 ) |
|
2121 parser.add_argument( |
|
2122 "-d", |
|
2123 metavar="dir", |
|
2124 default=modDir, |
|
2125 help="directory where eric Python files will be installed" |
|
2126 " (default: {0})".format(modDir), |
|
2127 ) |
|
2128 parser.add_argument( |
|
2129 "-f", |
|
2130 metavar="file", |
|
2131 help="configuration file naming the various installation paths", |
|
2132 ) |
|
2133 if not sys.platform.startswith(("win", "cygwin")): |
|
2134 parser.add_argument( |
|
2135 "-i", |
|
2136 metavar="dir", |
|
2137 default=distDir, |
|
2138 help="temporary install prefix (default: {0})".format(distDir), |
|
2139 ) |
|
2140 if sys.platform == "darwin": |
|
2141 parser.add_argument( |
|
2142 "-m", |
|
2143 metavar="name", |
|
2144 default=macAppBundleName, |
|
2145 help="name of the Mac app bundle (default: {0})".format(macAppBundleName), |
|
2146 ) |
|
2147 parser.add_argument( |
|
2148 "-n", |
|
2149 metavar="path", |
|
2150 default=macAppBundlePath, |
|
2151 help="path of the directory the Mac app bundle will be created in" |
|
2152 " (default: {0})".format(macAppBundlePath), |
|
2153 ) |
|
2154 parser.add_argument( |
|
2155 "-p", |
|
2156 metavar="python", |
|
2157 default=macPythonExe, |
|
2158 help="path of the python executable (default: {0})".format(macPythonExe), |
|
2159 ) |
|
2160 parser.add_argument( |
|
2161 "-c", |
|
2162 action="store_false", |
|
2163 help="don't cleanup old installation first", |
|
2164 ) |
|
2165 parser.add_argument( |
|
2166 "-v", |
|
2167 "--verbose", |
|
2168 action="store_true", |
|
2169 help="print some more information", |
|
2170 ) |
|
2171 parser.add_argument( |
|
2172 "-x", |
|
2173 action="store_false", |
|
2174 help="don't perform dependency checks (use on your own risk)", |
|
2175 ) |
|
2176 parser.add_argument( |
|
2177 "-z", |
|
2178 action="store_false", |
|
2179 help="don't compile the installed python files", |
|
2180 ) |
|
2181 parser.add_argument( |
|
2182 "--yes", |
|
2183 action="store_true", |
|
2184 help="answer 'yes' to all questions", |
|
2185 ) |
|
2186 if sys.platform.startswith(("win", "cygwin")): |
|
2187 parser.add_argument( |
|
2188 "--clean-desktop", |
|
2189 action="store_true", |
|
2190 help="delete desktop links before installation", |
|
2191 ) |
|
2192 parser.add_argument( |
|
2193 "--no-info", |
|
2194 action="store_true", |
|
2195 help="don't create the install info file", |
|
2196 ) |
|
2197 parser.add_argument( |
|
2198 "--with-tools", |
|
2199 action="store_true", |
|
2200 help="install the 'qt6-applications' package", |
|
2201 ) |
|
2202 |
|
2203 return parser |
|
2204 |
|
2205 |
2185 def main(argv): |
2206 def main(argv): |
2186 """ |
2207 """ |
2187 The main function of the script. |
2208 The main function of the script. |
2188 |
2209 |
2189 @param argv list of command line arguments |
2210 @param argv list of command line arguments |
2190 @type list of str |
2211 @type list of str |
2191 """ |
2212 """ |
2192 # Parse the command line. |
2213 global modDir, doCleanup, doCompile, distDir, cfg, apisDir |
2193 global progName, modDir, doCleanup, doCompile, distDir, cfg, apisDir |
2214 global sourceDir, eric7SourceDir, configName, platBinDir |
2194 global sourceDir, eric7SourceDir, configName |
|
2195 global macAppBundlePath, macAppBundleName, macPythonExe |
2215 global macAppBundlePath, macAppBundleName, macPythonExe |
2196 global installApis, doCleanDesktopLinks, yes2All |
2216 global installApis, doCleanDesktopLinks, yes2All |
2197 global createInstallInfoFile, installCwd |
2217 global createInstallInfoFile, installCwd |
2198 global withPyqt6Tools |
2218 global withPyqt6Tools |
2199 global verbose |
2219 global verbose |
2200 |
2220 |
2201 if sys.version_info < (3, 8, 0) or sys.version_info > (3, 99, 99): |
2221 if sys.version_info < (3, 8, 0) or sys.version_info > (3, 99, 99): |
2202 print("Sorry, eric requires at least Python 3.8 for running.") |
2222 print("Sorry, eric requires at least Python 3.8 for running.") |
2203 exit(5) |
2223 exit(5) |
2204 |
2224 |
2205 progName = os.path.basename(argv[0]) |
|
2206 |
|
2207 installCwd = os.getcwd() |
2225 installCwd = os.getcwd() |
2208 |
2226 |
2209 if os.path.dirname(argv[0]): |
2227 if os.path.dirname(argv[0]): |
2210 os.chdir(os.path.dirname(argv[0])) |
2228 os.chdir(os.path.dirname(argv[0])) |
2211 |
2229 |
2212 initGlobals() |
2230 initGlobals() |
2213 |
2231 |
2214 try: |
2232 parser = createArgumentParser() |
2215 if sys.platform.startswith(("win", "cygwin")): |
2233 args = parser.parse_args() |
2216 optlist, args = getopt.getopt( |
2234 |
2217 argv[1:], |
2235 apisDir = args.a |
2218 "chvxza:b:d:f:", |
2236 platBinDir = args.b |
2219 [ |
2237 modDir = args.d |
2220 "clean-desktop", |
2238 depChecks = args.x |
2221 "help", |
2239 doCleanup = args.c |
2222 "no-apis", |
2240 doCompile = args.z |
2223 "no-info", |
2241 installApis = not args.no_apis |
2224 "verbose", |
2242 yes2All = args.yes |
2225 "with-tools", |
2243 withPyqt6Tools = args.with_tools |
2226 "yes", |
2244 createInstallInfoFile = not args.no_info |
2227 ], |
2245 verbose = args.verbose |
2228 ) |
2246 if sys.platform == "darwin": |
2229 elif sys.platform == "darwin": |
2247 macAppBundleName = args.m |
2230 optlist, args = getopt.getopt( |
2248 macAppBundlePath = args.n |
2231 argv[1:], |
2249 macPythonExe = args.p |
2232 "chvxza:b:d:f:i:m:n:p:", |
2250 if sys.platform.startswith(("win", "cygwin")): |
2233 ["help", "no-apis", "no-info", "with-tools", "verbose", "yes"], |
2251 doCleanDesktopLinks = args.clean_desktop |
2234 ) |
2252 else: |
2235 else: |
2253 if args.i: |
2236 optlist, args = getopt.getopt( |
2254 distDir = os.path.normpath(args.i) |
2237 argv[1:], |
2255 if args.f: |
2238 "chvxza:b:d:f:i:", |
2256 with open(args.f) as f: |
2239 ["help", "no-apis", "no-info", "with-tools", "verbose", "yes"], |
2257 try: |
2240 ) |
2258 exec(compile(f.read(), args.f, "exec"), globals()) |
2241 except getopt.GetoptError as err: |
2259 # secok |
2242 print(err) |
2260 if len(cfg) != configLength: |
2243 usage() |
|
2244 |
|
2245 global platBinDir |
|
2246 |
|
2247 depChecks = True |
|
2248 |
|
2249 for opt, arg in optlist: |
|
2250 if opt in ["-h", "--help"]: |
|
2251 usage(0) |
|
2252 elif opt == "-a": |
|
2253 apisDir = arg |
|
2254 elif opt == "-b": |
|
2255 platBinDir = arg |
|
2256 elif opt == "-d": |
|
2257 modDir = arg |
|
2258 elif opt == "-i": |
|
2259 distDir = os.path.normpath(arg) |
|
2260 elif opt == "-x": |
|
2261 depChecks = False |
|
2262 elif opt == "-c": |
|
2263 doCleanup = False |
|
2264 elif opt == "-z": |
|
2265 doCompile = False |
|
2266 elif opt == "-f": |
|
2267 with open(arg) as f: |
|
2268 try: |
|
2269 exec(compile(f.read(), arg, "exec"), globals()) |
|
2270 # secok |
|
2271 if len(cfg) != configLength: |
|
2272 print( |
|
2273 "The configuration dictionary in '{0}' is" |
|
2274 " incorrect. Aborting".format(arg) |
|
2275 ) |
|
2276 exit(6) |
|
2277 except Exception as exc: |
|
2278 print( |
2261 print( |
2279 "The configuration file '{0}' is not valid Python source." |
2262 "The configuration dictionary in '{0}' is" |
2280 " It will be ignored. Installation will be performed with" |
2263 " incorrect. Aborting".format(args.f) |
2281 " defaults.".format(arg) |
|
2282 ) |
2264 ) |
2283 print("ERROR: {0}".format(str(exc))) |
2265 exit(6) |
2284 cfg = {} |
2266 except Exception as exc: |
2285 elif opt == "-m" and sys.platform == "darwin": |
2267 print( |
2286 macAppBundleName = arg |
2268 "The configuration file '{0}' is not valid Python source." |
2287 elif opt == "-n" and sys.platform == "darwin": |
2269 " It will be ignored. Installation will be performed with" |
2288 macAppBundlePath = arg |
2270 " defaults.".format(args.f) |
2289 elif opt == "-p" and sys.platform == "darwin": |
2271 ) |
2290 macPythonExe = arg |
2272 print("ERROR: {0}".format(str(exc))) |
2291 elif opt == "--no-apis": |
2273 cfg = {} |
2292 installApis = False |
|
2293 elif opt == "--clean-desktop": |
|
2294 doCleanDesktopLinks = True |
|
2295 elif opt == "--yes": |
|
2296 yes2All = True |
|
2297 elif opt == "--with-tools": |
|
2298 withPyqt6Tools = True |
|
2299 elif opt == "--no-info": |
|
2300 createInstallInfoFile = False |
|
2301 elif opt in ["-v", "--verbose"]: |
|
2302 verbose = True |
|
2303 |
2274 |
2304 infoName = "" |
2275 infoName = "" |
2305 installFromSource = not os.path.isdir(sourceDir) |
2276 installFromSource = not os.path.isdir(sourceDir) |
2306 |
2277 |
2307 # check dependencies |
2278 # check dependencies |