9306:90dc02c8a384 | 9371:1da8bc75946f |
---|---|
5 | 5 |
6 """ | 6 """ |
7 Module implementing the project management functionality. | 7 Module implementing the project management functionality. |
8 """ | 8 """ |
9 | 9 |
10 import contextlib | |
11 import copy | |
12 import fnmatch | |
13 import glob | |
14 import json | |
10 import os | 15 import os |
16 import pathlib | |
17 import shutil | |
11 import time | 18 import time |
12 import shutil | |
13 import glob | |
14 import fnmatch | |
15 import copy | |
16 import zipfile | 19 import zipfile |
17 import contextlib | |
18 import pathlib | |
19 | 20 |
20 from PyQt6.QtCore import ( | 21 from PyQt6.QtCore import ( |
21 pyqtSlot, | 22 pyqtSlot, |
22 QFile, | 23 QFile, |
23 pyqtSignal, | 24 pyqtSignal, |
30 from PyQt6.QtGui import QKeySequence, QAction | 31 from PyQt6.QtGui import QKeySequence, QAction |
31 from PyQt6.QtWidgets import QLineEdit, QToolBar, QDialog, QInputDialog, QMenu | 32 from PyQt6.QtWidgets import QLineEdit, QToolBar, QDialog, QInputDialog, QMenu |
32 from PyQt6.Qsci import QsciScintilla | 33 from PyQt6.Qsci import QsciScintilla |
33 | 34 |
34 from EricWidgets.EricApplication import ericApp | 35 from EricWidgets.EricApplication import ericApp |
35 from EricWidgets import EricFileDialog, EricMessageBox | 36 from EricWidgets import EricFileDialog, EricMessageBox, EricPathPickerDialog |
36 from EricWidgets.EricListSelectionDialog import EricListSelectionDialog | 37 from EricWidgets.EricListSelectionDialog import EricListSelectionDialog |
37 from EricWidgets.EricProgressDialog import EricProgressDialog | 38 from EricWidgets.EricProgressDialog import EricProgressDialog |
38 from EricGui.EricOverrideCursor import EricOverrideCursor, EricOverridenCursor | 39 from EricGui.EricOverrideCursor import EricOverrideCursor, EricOverridenCursor |
39 | 40 |
40 from Globals import recentNameProject | 41 from Globals import recentNameProject |
542 }, | 543 }, |
543 "EOL": -1, | 544 "EOL": -1, |
544 "DOCSTRING": "", | 545 "DOCSTRING": "", |
545 "TESTING_FRAMEWORK": "", | 546 "TESTING_FRAMEWORK": "", |
546 "LICENSE": "", | 547 "LICENSE": "", |
548 "EMBEDDED_VENV": False, | |
547 } | 549 } |
548 | 550 |
549 self.__initDebugProperties() | 551 self.__initDebugProperties() |
550 | 552 |
551 self.pudata = { | 553 self.pudata = { |
552 "VCSOVERRIDE": "", | 554 "VCSOVERRIDE": "", |
553 "VCSSTATUSMONITORINTERVAL": 0, | 555 "VCSSTATUSMONITORINTERVAL": 0, |
554 } | 556 } |
555 | 557 |
556 self.vcs = self.initVCS() | 558 self.vcs = self.initVCS() |
559 | |
560 self.__initVenvConfiguration() | |
557 | 561 |
558 def getData(self, category, key): | 562 def getData(self, category, key): |
559 """ | 563 """ |
560 Public method to get data out of the project data store. | 564 Public method to get data out of the project data store. |
561 | 565 |
805 self.__dirty = dirty | 809 self.__dirty = dirty |
806 self.saveAct.setEnabled(dirty) | 810 self.saveAct.setEnabled(dirty) |
807 self.dirty.emit(dirty) | 811 self.dirty.emit(dirty) |
808 if self.__dirty: | 812 if self.__dirty: |
809 self.projectChanged.emit() | 813 self.projectChanged.emit() |
814 | |
815 # autosave functionality | |
816 if dirty and Preferences.getProject("AutoSaveProject"): | |
817 self.saveProject() | |
810 | 818 |
811 def isDirty(self): | 819 def isDirty(self): |
812 """ | 820 """ |
813 Public method to return the dirty state. | 821 Public method to return the dirty state. |
814 | 822 |
2783 self.newProject.emit() | 2791 self.newProject.emit() |
2784 | 2792 |
2785 else: | 2793 else: |
2786 self.newProjectHooks.emit() | 2794 self.newProjectHooks.emit() |
2787 self.newProject.emit() | 2795 self.newProject.emit() |
2796 | |
2797 if self.pdata["EMBEDDED_VENV"]: | |
2798 self.__createEmbeddedEnvironment() | |
2799 self.menuEnvironmentAct.setEnabled(self.pdata["EMBEDDED_VENV"]) | |
2788 | 2800 |
2789 def newProjectAddFiles(self, mainscript): | 2801 def newProjectAddFiles(self, mainscript): |
2790 """ | 2802 """ |
2791 Public method to add files to a new project. | 2803 Public method to add files to a new project. |
2792 | 2804 |
2951 self.projectPropertiesChanged.emit() | 2963 self.projectPropertiesChanged.emit() |
2952 | 2964 |
2953 if self.pdata["PROJECTTYPE"] != projectType: | 2965 if self.pdata["PROJECTTYPE"] != projectType: |
2954 self.__reorganizeFiles() | 2966 self.__reorganizeFiles() |
2955 | 2967 |
2968 if self.pdata["EMBEDDED_VENV"] and not self.__findEmbeddedEnvironment(): | |
2969 self.__createEmbeddedEnvironment() | |
2970 | |
2956 def __showUserProperties(self): | 2971 def __showUserProperties(self): |
2957 """ | 2972 """ |
2958 Private slot to display the user specific properties dialog. | 2973 Private slot to display the user specific properties dialog. |
2959 """ | 2974 """ |
2960 vcsSystem = self.pdata["VCS"] or None | 2975 vcsSystem = self.pdata["VCS"] or None |
3190 # about errors | 3205 # about errors |
3191 if Preferences.getProject("AutoLoadDbgProperties"): | 3206 if Preferences.getProject("AutoLoadDbgProperties"): |
3192 self.__readDebugProperties(True) | 3207 self.__readDebugProperties(True) |
3193 | 3208 |
3194 self.__model.projectOpened() | 3209 self.__model.projectOpened() |
3195 self.projectOpenedHooks.emit() | 3210 |
3196 self.projectOpened.emit() | 3211 if self.pdata["EMBEDDED_VENV"]: |
3212 envPath = self.__findEmbeddedEnvironment() | |
3213 if bool(envPath): | |
3214 self.__loadEnvironmentConfiguration() | |
3215 if not bool( | |
3216 self.__venvConfiguration["interpreter"] | |
3217 ) or not os.access( | |
3218 self.__venvConfiguration["interpreter"], os.X_OK | |
3219 ): | |
3220 self.__configureEnvironment(envPath) | |
3221 else: | |
3222 self.__createEmbeddedEnvironment() | |
3223 self.menuEnvironmentAct.setEnabled(self.pdata["EMBEDDED_VENV"]) | |
3224 | |
3225 self.projectOpenedHooks.emit() | |
3226 self.projectOpened.emit() | |
3197 | 3227 |
3198 if Preferences.getProject("SearchNewFiles"): | 3228 if Preferences.getProject("SearchNewFiles"): |
3199 self.__doSearchNewFiles() | 3229 self.__doSearchNewFiles() |
3200 | 3230 |
3201 # read a project tasks file | 3231 # read a project tasks file |
3444 self.pluginGrp.setEnabled(False) | 3474 self.pluginGrp.setEnabled(False) |
3445 self.makeGrp.setEnabled(False) | 3475 self.makeGrp.setEnabled(False) |
3446 self.menuMakeAct.setEnabled(False) | 3476 self.menuMakeAct.setEnabled(False) |
3447 self.menuOtherToolsAct.setEnabled(False) | 3477 self.menuOtherToolsAct.setEnabled(False) |
3448 self.menuFormattingAct.setEnabled(False) | 3478 self.menuFormattingAct.setEnabled(False) |
3479 self.menuEnvironmentAct.setEnabled(False) | |
3449 | 3480 |
3450 self.__model.projectClosed() | 3481 self.__model.projectClosed() |
3451 self.projectClosedHooks.emit() | 3482 self.projectClosedHooks.emit() |
3452 self.projectClosed.emit(shutdown) | 3483 self.projectClosed.emit(shutdown) |
3453 | 3484 |
3883 environment name via the debugger settings if none was configured | 3914 environment name via the debugger settings if none was configured |
3884 @type bool | 3915 @type bool |
3885 @return name of the project's virtual environment | 3916 @return name of the project's virtual environment |
3886 @rtype str | 3917 @rtype str |
3887 """ | 3918 """ |
3888 venvName = self.getDebugProperty("VIRTUALENV") | 3919 venvName = ( |
3920 self.__venvConfiguration["name"] | |
3921 if self.pdata["EMBEDDED_VENV"] and bool(self.__venvConfiguration["name"]) | |
3922 else self.getDebugProperty("VIRTUALENV") | |
3923 ) | |
3889 if ( | 3924 if ( |
3890 not venvName | 3925 not venvName |
3891 and resolveDebugger | 3926 and resolveDebugger |
3892 and self.getProjectLanguage() in ("Python3", "MicroPython", "Cython") | 3927 and self.getProjectLanguage() in ("Python3", "MicroPython", "Cython") |
3893 ): | 3928 ): |
3904 environment was configured | 3939 environment was configured |
3905 @type bool | 3940 @type bool |
3906 @return path of the project's interpreter | 3941 @return path of the project's interpreter |
3907 @rtype str | 3942 @rtype str |
3908 """ | 3943 """ |
3909 interpreter = "" | 3944 interpreter = ( |
3910 venvName = self.getProjectVenv() | 3945 self.__venvConfiguration["interpreter"] |
3911 if venvName: | 3946 if self.pdata["EMBEDDED_VENV"] |
3912 interpreter = ( | 3947 else "" |
3913 ericApp() | 3948 ) |
3914 .getObject("VirtualEnvManager") | 3949 if not interpreter: |
3915 .getVirtualenvInterpreter(venvName) | 3950 venvName = self.getProjectVenv() |
3916 ) | 3951 if venvName: |
3952 interpreter = ( | |
3953 ericApp() | |
3954 .getObject("VirtualEnvManager") | |
3955 .getVirtualenvInterpreter(venvName) | |
3956 ) | |
3917 if not interpreter and resolveGlobal: | 3957 if not interpreter and resolveGlobal: |
3918 interpreter = Globals.getPythonExecutable() | 3958 interpreter = Globals.getPythonExecutable() |
3919 | 3959 |
3920 return interpreter | 3960 return interpreter |
3921 | 3961 |
3924 Public method to get the executable search path prefix of the project. | 3964 Public method to get the executable search path prefix of the project. |
3925 | 3965 |
3926 @return executable search path prefix | 3966 @return executable search path prefix |
3927 @rtype str | 3967 @rtype str |
3928 """ | 3968 """ |
3929 execPath = "" | 3969 if self.pdata["EMBEDDED_VENV"]: |
3930 venvName = self.getProjectVenv() | 3970 execPath = self.__venvConfiguration["exec_path"] |
3931 if venvName: | 3971 else: |
3932 execPath = ( | 3972 execPath = "" |
3933 ericApp().getObject("VirtualEnvManager").getVirtualenvExecPath(venvName) | 3973 venvName = self.getProjectVenv() |
3934 ) | 3974 if venvName: |
3975 execPath = ( | |
3976 ericApp() | |
3977 .getObject("VirtualEnvManager") | |
3978 .getVirtualenvExecPath(venvName) | |
3979 ) | |
3935 | 3980 |
3936 return execPath | 3981 return execPath |
3937 | 3982 |
3938 def getProjectTestingFramework(self): | 3983 def getProjectTestingFramework(self): |
3939 """ | 3984 """ |
4917 self.blackDiffFormattingAct.triggered.connect( | 4962 self.blackDiffFormattingAct.triggered.connect( |
4918 lambda: self.__performFormatWithBlack(BlackFormattingAction.Diff) | 4963 lambda: self.__performFormatWithBlack(BlackFormattingAction.Diff) |
4919 ) | 4964 ) |
4920 self.actions.append(self.blackDiffFormattingAct) | 4965 self.actions.append(self.blackDiffFormattingAct) |
4921 | 4966 |
4967 self.blackConfigureAct = EricAction( | |
4968 self.tr("Configure"), | |
4969 self.tr("Configure"), | |
4970 0, | |
4971 0, | |
4972 self.blackFormattingGrp, | |
4973 "project_black_configure", | |
4974 ) | |
4975 self.blackConfigureAct.setStatusTip( | |
4976 self.tr( | |
4977 "Enter the parameters for formatting the project sources with 'Black'." | |
4978 ) | |
4979 ) | |
4980 self.blackConfigureAct.setWhatsThis( | |
4981 self.tr( | |
4982 "<b>Configure</b>" | |
4983 "<p>This shows a dialog to enter the parameters for formatting the" | |
4984 " project sources with 'Black'.</p>" | |
4985 ) | |
4986 ) | |
4987 self.blackConfigureAct.triggered.connect(self.__configureBlack) | |
4988 self.actions.append(self.blackConfigureAct) | |
4989 | |
4990 ################################################################### | |
4991 ## Project - embedded environment actions | |
4992 ################################################################### | |
4993 | |
4994 self.embeddedEnvironmentGrp = createActionGroup(self) | |
4995 | |
4996 self.installVenvAct = EricAction( | |
4997 self.tr("Install Project"), | |
4998 self.tr("&Install Project"), | |
4999 0, | |
5000 0, | |
5001 self.embeddedEnvironmentGrp, | |
5002 "project_venv_install", | |
5003 ) | |
5004 self.installVenvAct.setStatusTip( | |
5005 self.tr("Install the project into the embedded environment.") | |
5006 ) | |
5007 self.installVenvAct.setWhatsThis( | |
5008 self.tr( | |
5009 "<b>Install Project</b>" | |
5010 "<p>This installs the project into the embedded virtual environment" | |
5011 " in editable mode (i.e. development mode).</p>" | |
5012 ) | |
5013 ) | |
5014 self.installVenvAct.triggered.connect(self.__installProjectIntoEnvironment) | |
5015 self.actions.append(self.installVenvAct) | |
5016 | |
5017 self.configureVenvAct = EricAction( | |
5018 self.tr("Configure"), | |
5019 self.tr("&Configure"), | |
5020 0, | |
5021 0, | |
5022 self.embeddedEnvironmentGrp, | |
5023 "project_venv_configure", | |
5024 ) | |
5025 self.configureVenvAct.setStatusTip( | |
5026 self.tr("Configure the embedded environment.") | |
5027 ) | |
5028 self.configureVenvAct.setWhatsThis( | |
5029 self.tr( | |
5030 "<b>Configure</b>" | |
5031 "<p>This opens a dialog to configure the embedded virtual environment" | |
5032 " of the project.</p>" | |
5033 ) | |
5034 ) | |
5035 self.configureVenvAct.triggered.connect(self.__configureEnvironment) | |
5036 self.actions.append(self.configureVenvAct) | |
5037 | |
4922 self.closeAct.setEnabled(False) | 5038 self.closeAct.setEnabled(False) |
4923 self.saveAct.setEnabled(False) | 5039 self.saveAct.setEnabled(False) |
4924 self.saveasAct.setEnabled(False) | 5040 self.saveasAct.setEnabled(False) |
4925 self.actGrp2.setEnabled(False) | 5041 self.actGrp2.setEnabled(False) |
4926 self.propsAct.setEnabled(False) | 5042 self.propsAct.setEnabled(False) |
4940 """ | 5056 """ |
4941 menu = QMenu(self.tr("&Project"), self.parent()) | 5057 menu = QMenu(self.tr("&Project"), self.parent()) |
4942 self.recentMenu = QMenu(self.tr("Open &Recent Projects"), menu) | 5058 self.recentMenu = QMenu(self.tr("Open &Recent Projects"), menu) |
4943 self.sessionMenu = QMenu(self.tr("Session"), menu) | 5059 self.sessionMenu = QMenu(self.tr("Session"), menu) |
4944 self.debuggerMenu = QMenu(self.tr("Debugger"), menu) | 5060 self.debuggerMenu = QMenu(self.tr("Debugger"), menu) |
5061 self.environmentMenu = QMenu(self.tr("Embedded Environment"), menu) | |
4945 | 5062 |
4946 toolsMenu = QMenu(self.tr("Project-T&ools"), self.parent()) | 5063 toolsMenu = QMenu(self.tr("Project-T&ools"), self.parent()) |
4947 self.vcsMenu = QMenu(self.tr("&Version Control"), toolsMenu) | 5064 self.vcsMenu = QMenu(self.tr("&Version Control"), toolsMenu) |
4948 self.vcsMenu.setTearOffEnabled(True) | 5065 self.vcsMenu.setTearOffEnabled(True) |
4949 self.vcsProjectHelper.initMenu(self.vcsMenu) | 5066 self.vcsProjectHelper.initMenu(self.vcsMenu) |
4972 "Debugger": self.debuggerMenu, | 5089 "Debugger": self.debuggerMenu, |
4973 "Packagers": self.packagersMenu, | 5090 "Packagers": self.packagersMenu, |
4974 "Make": self.makeMenu, | 5091 "Make": self.makeMenu, |
4975 "OtherTools": self.othersMenu, | 5092 "OtherTools": self.othersMenu, |
4976 "Formatting": self.formattingMenu, | 5093 "Formatting": self.formattingMenu, |
5094 "Environment": self.environmentMenu, | |
4977 } | 5095 } |
4978 | 5096 |
4979 # connect the aboutToShow signals | 5097 # connect the aboutToShow signals |
4980 self.recentMenu.aboutToShow.connect(self.__showContextMenuRecent) | 5098 self.recentMenu.aboutToShow.connect(self.__showContextMenuRecent) |
4981 self.recentMenu.triggered.connect(self.__openRecent) | 5099 self.recentMenu.triggered.connect(self.__openRecent) |
4988 self.sessionMenu.aboutToShow.connect(self.__showContextMenuSession) | 5106 self.sessionMenu.aboutToShow.connect(self.__showContextMenuSession) |
4989 self.debuggerMenu.aboutToShow.connect(self.__showContextMenuDebugger) | 5107 self.debuggerMenu.aboutToShow.connect(self.__showContextMenuDebugger) |
4990 self.makeMenu.aboutToShow.connect(self.__showContextMenuMake) | 5108 self.makeMenu.aboutToShow.connect(self.__showContextMenuMake) |
4991 self.othersMenu.aboutToShow.connect(self.__showContextMenuOthers) | 5109 self.othersMenu.aboutToShow.connect(self.__showContextMenuOthers) |
4992 self.formattingMenu.aboutToShow.connect(self.__showContextMenuFormat) | 5110 self.formattingMenu.aboutToShow.connect(self.__showContextMenuFormat) |
5111 self.environmentMenu.aboutToShow.connect(self.__showContextMenuEnvironment) | |
4993 menu.aboutToShow.connect(self.__showMenu) | 5112 menu.aboutToShow.connect(self.__showMenu) |
4994 | 5113 |
4995 # build the show menu | 5114 # build the show menu |
4996 self.menuShow.setTearOffEnabled(True) | 5115 self.menuShow.setTearOffEnabled(True) |
4997 self.menuShow.addAction(self.codeMetricsAct) | 5116 self.menuShow.addAction(self.codeMetricsAct) |
5009 self.sessionMenu.addActions(self.sessActGrp.actions()) | 5128 self.sessionMenu.addActions(self.sessActGrp.actions()) |
5010 | 5129 |
5011 # build the debugger menu | 5130 # build the debugger menu |
5012 self.debuggerMenu.setTearOffEnabled(True) | 5131 self.debuggerMenu.setTearOffEnabled(True) |
5013 self.debuggerMenu.addActions(self.dbgActGrp.actions()) | 5132 self.debuggerMenu.addActions(self.dbgActGrp.actions()) |
5133 | |
5134 # build the environment menu | |
5135 self.environmentMenu.setTearOffEnabled(True) | |
5136 self.environmentMenu.addActions(self.embeddedEnvironmentGrp.actions()) | |
5014 | 5137 |
5015 # build the packagers menu | 5138 # build the packagers menu |
5016 self.packagersMenu.setTearOffEnabled(True) | 5139 self.packagersMenu.setTearOffEnabled(True) |
5017 self.packagersMenu.addActions(self.pluginGrp.actions()) | 5140 self.packagersMenu.addActions(self.pluginGrp.actions()) |
5018 self.packagersMenu.addSeparator() | 5141 self.packagersMenu.addSeparator() |
5046 menu.addSeparator() | 5169 menu.addSeparator() |
5047 menu.addAction(self.propsAct) | 5170 menu.addAction(self.propsAct) |
5048 menu.addAction(self.userPropsAct) | 5171 menu.addAction(self.userPropsAct) |
5049 menu.addAction(self.filetypesAct) | 5172 menu.addAction(self.filetypesAct) |
5050 menu.addAction(self.lexersAct) | 5173 menu.addAction(self.lexersAct) |
5174 menu.addSeparator() | |
5175 self.menuEnvironmentAct = menu.addMenu(self.environmentMenu) | |
5051 menu.addSeparator() | 5176 menu.addSeparator() |
5052 self.menuDebuggerAct = menu.addMenu(self.debuggerMenu) | 5177 self.menuDebuggerAct = menu.addMenu(self.debuggerMenu) |
5053 self.menuSessionAct = menu.addMenu(self.sessionMenu) | 5178 self.menuSessionAct = menu.addMenu(self.sessionMenu) |
5054 | 5179 |
5055 # build the project tools menu | 5180 # build the project tools menu |
5081 self.menuApidocAct.setEnabled(False) | 5206 self.menuApidocAct.setEnabled(False) |
5082 self.menuPackagersAct.setEnabled(False) | 5207 self.menuPackagersAct.setEnabled(False) |
5083 self.menuMakeAct.setEnabled(False) | 5208 self.menuMakeAct.setEnabled(False) |
5084 self.menuOtherToolsAct.setEnabled(False) | 5209 self.menuOtherToolsAct.setEnabled(False) |
5085 self.menuFormattingAct.setEnabled(False) | 5210 self.menuFormattingAct.setEnabled(False) |
5211 self.menuEnvironmentAct.setEnabled(False) | |
5086 | 5212 |
5087 self.__menu = menu | 5213 self.__menu = menu |
5088 self.__toolsMenu = toolsMenu | 5214 self.__toolsMenu = toolsMenu |
5089 | 5215 |
5090 return menu, toolsMenu | 5216 return menu, toolsMenu |
5125 def __showMenu(self): | 5251 def __showMenu(self): |
5126 """ | 5252 """ |
5127 Private method to set up the project menu. | 5253 Private method to set up the project menu. |
5128 """ | 5254 """ |
5129 self.menuRecentAct.setEnabled(len(self.recent) > 0) | 5255 self.menuRecentAct.setEnabled(len(self.recent) > 0) |
5256 self.menuEnvironmentAct.setEnabled(self.pdata["EMBEDDED_VENV"]) | |
5130 | 5257 |
5131 self.showMenu.emit("Main", self.__menus["Main"]) | 5258 self.showMenu.emit("Main", self.__menus["Main"]) |
5132 | 5259 |
5133 def __syncRecent(self): | 5260 def __syncRecent(self): |
5134 """ | 5261 """ |
6556 | 6683 |
6557 def __showContextMenuFormat(self): | 6684 def __showContextMenuFormat(self): |
6558 """ | 6685 """ |
6559 Private slot called before the 'Code Formatting' menu is shown. | 6686 Private slot called before the 'Code Formatting' menu is shown. |
6560 """ | 6687 """ |
6561 self.showMenu.emit("Formatting", self.othersMenu) | 6688 self.showMenu.emit("Formatting", self.formattingMenu) |
6562 | 6689 |
6563 @pyqtSlot() | 6690 @pyqtSlot() |
6564 def __aboutBlack(self): | 6691 def __aboutBlack(self): |
6565 """ | 6692 """ |
6566 Private slot to show some information about the installed 'Black' tool. | 6693 Private slot to show some information about the installed 'Black' tool. |
6597 from CodeFormatting.BlackFormattingDialog import BlackFormattingDialog | 6724 from CodeFormatting.BlackFormattingDialog import BlackFormattingDialog |
6598 | 6725 |
6599 if ericApp().getObject("ViewManager").checkAllDirty(): | 6726 if ericApp().getObject("ViewManager").checkAllDirty(): |
6600 dlg = BlackConfigurationDialog(withProject=True) | 6727 dlg = BlackConfigurationDialog(withProject=True) |
6601 if dlg.exec() == QDialog.DialogCode.Accepted: | 6728 if dlg.exec() == QDialog.DialogCode.Accepted: |
6602 config = dlg.getConfiguration() | 6729 config = dlg.getConfiguration(saveToProject=True) |
6603 | 6730 |
6604 formattingDialog = BlackFormattingDialog( | 6731 formattingDialog = BlackFormattingDialog( |
6605 config, | 6732 config, |
6606 self.getProjectFiles("SOURCES", normalized=True), | 6733 self.getProjectFiles("SOURCES", normalized=True), |
6607 project=self, | 6734 project=self, |
6608 action=action, | 6735 action=action, |
6609 ) | 6736 ) |
6610 formattingDialog.exec() | 6737 formattingDialog.exec() |
6611 | 6738 |
6739 @pyqtSlot() | |
6740 def __configureBlack(self): | |
6741 """ | |
6742 Private slot to enter the parameters for formatting the project sources with | |
6743 'Black'. | |
6744 """ | |
6745 from CodeFormatting.BlackConfigurationDialog import BlackConfigurationDialog | |
6746 | |
6747 dlg = BlackConfigurationDialog(withProject=True, onlyProject=True) | |
6748 if dlg.exec() == QDialog.DialogCode.Accepted: | |
6749 dlg.getConfiguration(saveToProject=True) | |
6750 # The data is saved to the project as a side effect. | |
6751 | |
6752 ######################################################################### | |
6753 ## Below are methods implementing the 'Embedded Environment' support | |
6754 ######################################################################### | |
6755 | |
6756 def __showContextMenuEnvironment(self): | |
6757 """ | |
6758 Private slot called before the 'Embedded Environment' menu is shown. | |
6759 """ | |
6760 self.showMenu.emit("Environment", self.environmentMenu) | |
6761 | |
6762 def __findEmbeddedEnvironment(self): | |
6763 """ | |
6764 Private method to find the path of the embedded virtual environment. | |
6765 | |
6766 @return path of the embedded virtual environment (empty if not found) | |
6767 @rtype str | |
6768 """ | |
6769 for venvPathName in (".venv", "venv", ".env", "env"): | |
6770 venvPath = os.path.join(self.getProjectPath(), venvPathName) | |
6771 if os.path.isdir(venvPath): | |
6772 return venvPath | |
6773 | |
6774 return "" | |
6775 | |
6776 def __setEmbeddedEnvironmentProjectConfig(self, value): | |
6777 """ | |
6778 Private method to set the embedded environment project configuration. | |
6779 | |
6780 @param value flag indicating an embedded environment | |
6781 @type bool | |
6782 """ | |
6783 if value != self.pdata["EMBEDDED_VENV"]: | |
6784 self.pdata["EMBEDDED_VENV"] = value | |
6785 self.setDirty(True) | |
6786 | |
6787 def __initVenvConfiguration(self): | |
6788 """ | |
6789 Private method to initialize the environment configuration. | |
6790 """ | |
6791 self.__venvConfiguration = { | |
6792 "name": "embedded environment", | |
6793 "interpreter": "", | |
6794 "exec_path": "", | |
6795 } | |
6796 | |
6797 def __createEmbeddedEnvironment(self): | |
6798 """ | |
6799 Private method to create the embedded virtual environment. | |
6800 """ | |
6801 pythonPath, ok = EricPathPickerDialog.getStrPath( | |
6802 None, | |
6803 self.tr("Python Executable"), | |
6804 self.tr("Enter the Python interpreter for the virtual environment:"), | |
6805 defaultDirectory=Globals.getPythonExecutable(), | |
6806 ) | |
6807 if not ok: | |
6808 # user canceled the environment creation | |
6809 self.__setEmbeddedEnvironmentProjectConfig(False) | |
6810 return | |
6811 | |
6812 configuration = { | |
6813 "envType": "pyvenv", | |
6814 "targetDirectory": os.path.join(self.getProjectPath(), ".venv"), | |
6815 "openTarget": False, | |
6816 "createLog": True, | |
6817 "createScript": True, | |
6818 "logicalName": self.__venvConfiguration["name"], | |
6819 "pythonExe": pythonPath, | |
6820 } | |
6821 from VirtualEnv.VirtualenvExecDialog import VirtualenvExecDialog | |
6822 | |
6823 dia = VirtualenvExecDialog(configuration, None) | |
6824 dia.show() | |
6825 dia.start([configuration["targetDirectory"]]) | |
6826 dia.exec() | |
6827 | |
6828 self.__configureEnvironment() | |
6829 if not self.__venvConfiguration["interpreter"]: | |
6830 # user canceled the environment creation | |
6831 self.__setEmbeddedEnvironmentProjectConfig(False) | |
6832 return | |
6833 | |
6834 @pyqtSlot() | |
6835 def __configureEnvironment(self, environmentPath=""): | |
6836 """ | |
6837 Private slot to configure the embedded environment. | |
6838 | |
6839 @param environmentPath path of the virtual environment (defaults to "") | |
6840 @type str (optional) | |
6841 """ | |
6842 from .ProjectVenvConfigurationDialog import ProjectVenvConfigurationDialog | |
6843 | |
6844 if not environmentPath: | |
6845 environmentPath = os.path.join(self.getProjectPath(), ".venv") | |
6846 | |
6847 dlg = ProjectVenvConfigurationDialog( | |
6848 self.__venvConfiguration["name"], | |
6849 environmentPath, | |
6850 self.__venvConfiguration["interpreter"], | |
6851 self.__venvConfiguration["exec_path"], | |
6852 ) | |
6853 if dlg.exec() == QDialog.DialogCode.Accepted: | |
6854 ( | |
6855 self.__venvConfiguration["interpreter"], | |
6856 self.__venvConfiguration["exec_path"], | |
6857 ) = dlg.getData() | |
6858 self.__saveEnvironmentConfiguration() | |
6859 self.__setEmbeddedEnvironmentProjectConfig(True) | |
6860 elif not self.__venvConfiguration["interpreter"]: | |
6861 self.__setEmbeddedEnvironmentProjectConfig(False) | |
6862 | |
6863 def __installProjectIntoEnvironment(self): | |
6864 """ | |
6865 Private method to install the project into the embedded environment in | |
6866 development mode. | |
6867 """ | |
6868 pip = ericApp().getObject("Pip") | |
6869 pip.installEditableProject(self.getProjectInterpreter(), self.getProjectPath()) | |
6870 | |
6871 def __saveEnvironmentConfiguration(self): | |
6872 """ | |
6873 Private method to save the embedded environment configuration. | |
6874 """ | |
6875 with contextlib.suppress(OSError), open( | |
6876 os.path.join(self.getProjectManagementDir(), "venv_config.json"), "w" | |
6877 ) as f: | |
6878 json.dump(self.__venvConfiguration, f, indent=2) | |
6879 | |
6880 def __loadEnvironmentConfiguration(self): | |
6881 """ | |
6882 Private method to load the embedded environment configuration. | |
6883 """ | |
6884 try: | |
6885 with open( | |
6886 os.path.join(self.getProjectManagementDir(), "venv_config.json"), "r" | |
6887 ) as f: | |
6888 self.__venvConfiguration = json.load(f) | |
6889 | |
6890 if not os.path.isfile( | |
6891 self.__venvConfiguration["interpreter"] | |
6892 ) or not os.access(self.__venvConfiguration["interpreter"], os.X_OK): | |
6893 self.__venvConfiguration["interpreter"] = "" | |
6894 except (OSError, json.JSONDecodeError): | |
6895 # the configuration file does not exist or is invalid JSON | |
6896 self.__initVenvConfiguration() | |
6897 | |
6612 | 6898 |
6613 # | 6899 # |
6614 # eflag: noqa = M601 | 6900 # eflag: noqa = M601 |