src/eric7/Project/Project.py

branch
eric7-maintenance
changeset 9371
1da8bc75946f
parent 9305
3b7ef53c34c7
parent 9361
718bc86e1c3f
child 9442
906485dcd210
equal deleted inserted replaced
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

eric ide

mercurial