VirtualEnv/VirtualenvConfigurationDialog.py

branch
conda
changeset 6672
2af01e538c57
parent 6645
ad476851d7e0
child 6677
6299d69a218a
--- a/VirtualEnv/VirtualenvConfigurationDialog.py	Sat Jan 26 17:04:11 2019 +0100
+++ b/VirtualEnv/VirtualenvConfigurationDialog.py	Sat Jan 26 19:42:53 2019 +0100
@@ -60,22 +60,43 @@
         self.pythonExecPicker.setDefaultDirectory(
             sys.executable.replace("w.exe", ".exe"))
         
+        self.condaTargetDirectoryPicker.setMode(
+            E5PathPickerModes.DirectoryMode)
+        self.condaTargetDirectoryPicker.setWindowTitle(
+            self.tr("Conda Environment Location"))
+        self.condaTargetDirectoryPicker.setDefaultDirectory(
+            Utilities.getHomeDir())
+        
+        self.condaCloneDirectoryPicker.setMode(
+            E5PathPickerModes.DirectoryMode)
+        self.condaCloneDirectoryPicker.setWindowTitle(
+            self.tr("Conda Environment Location"))
+        self.condaCloneDirectoryPicker.setDefaultDirectory(
+            Utilities.getHomeDir())
+        
         self.__versionRe = re.compile(r""".*?(\d+\.\d+\.\d+).*""")
         
         self.__virtualenvFound = False
         self.__pyvenvFound = False
+        self.__condaFound = False
         self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False)
         
         self.__mandatoryStyleSheet = "QLineEdit {border: 2px solid;}"
         self.targetDirectoryPicker.setStyleSheet(self.__mandatoryStyleSheet)
         self.nameEdit.setStyleSheet(self.__mandatoryStyleSheet)
+        self.condaTargetDirectoryPicker.setStyleSheet(
+            self.__mandatoryStyleSheet)
+        self.condaNameEdit.setStyleSheet(self.__mandatoryStyleSheet)
         
         self.__setVirtualenvVersion()
         self.__setPyvenvVersion()
-        if self.__virtualenvFound:
+        self.__setCondaVersion()
+        if self.__pyvenvFound:
+            self.pyvenvButton.setChecked(True)
+        elif self.__virtualenvFound:
             self.virtualenvButton.setChecked(True)
-        elif self.__pyvenvFound:
-            self.pyvenvButton.setChecked(True)
+        elif self.__condaFound:
+            self.condaButton.setChecked(True)
         
         msh = self.minimumSizeHint()
         self.resize(max(self.width(), msh.width()), msh.height())
@@ -84,17 +105,28 @@
         """
         Private method to update the enabled status of the OK button.
         """
-        self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(
-            (self.__virtualenvFound or self.__pyvenvFound) and
-            bool(self.targetDirectoryPicker.text()) and
-            bool(self.nameEdit.text())
-        )
+        if self.virtualenvButton.isChecked() or self.pyvenvButton.isChecked():
+            self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(
+                (self.__virtualenvFound or self.__pyvenvFound) and
+                bool(self.targetDirectoryPicker.text()) and
+                bool(self.nameEdit.text())
+            )
+        elif self.condaButton.isChecked():
+            enable = bool(self.condaNameEdit.text()) or \
+                bool(self.condaTargetDirectoryPicker.text())
+            if self.condaCloneGroup.isChecked():
+                enable &= bool(self.condaCloneNameEdit.text()) or \
+                    bool(self.condaCloneDirectoryPicker.text())
+            self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(enable)
+        else:
+            self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False)
     
     def __updateUi(self):
         """
         Private method to update the UI depending on the selected
         virtual environment creator (virtualenv or pyvenv).
         """
+        # venv page
         enable = self.virtualenvButton.isChecked()
         self.extraSearchPathLabel.setEnabled(enable)
         self.extraSearchPathPicker.setEnabled(enable)
@@ -108,6 +140,19 @@
         self.noSetuptoolsCheckBox.setEnabled(enable)
         self.symlinkCheckBox.setEnabled(not enable)
         self.upgradeCheckBox.setEnabled(not enable)
+        
+        # conda page
+        enable = not self.condaCloneGroup.isChecked()
+        self.condaPackagesEdit.setEnabled(enable)
+        self.condaPythonEdit.setEnabled(enable)
+        self.condaInsecureCheckBox.setEnabled(enable)
+        self.condaDryrunCheckBox.setEnabled(enable)
+        
+        # select page
+        if self.condaButton.isChecked():
+            self.venvStack.setCurrentWidget(self.condaPage)
+        else:
+            self.venvStack.setCurrentWidget(self.venvPage)
     
     @pyqtSlot(str)
     def on_targetDirectoryPicker_textChanged(self, txt):
@@ -151,6 +196,64 @@
         """
         self.__updateUi()
     
+    @pyqtSlot(bool)
+    def on_condaButton_toggled(self, checked):
+        """
+        Private slot to react to the selection of 'conda'.
+        
+        @param checked state of the checkbox
+        @type bool
+        """
+        self.__updateUi()
+    
+    @pyqtSlot(str)
+    def on_condaNameEdit_textChanged(self, txt):
+        """
+        Private slot handling a change of the conda environment name.
+        
+        @param txt environment name
+        @type str
+        """
+        self.__updateOK()
+    
+    @pyqtSlot(str)
+    def on_condaTargetDirectoryPicker_textChanged(self, txt):
+        """
+        Private slot handling a change of the conda target directory.
+        
+        @param txt target directory
+        @type str
+        """
+        self.__updateOK()
+    
+    @pyqtSlot()
+    def on_condaCloneGroup_clicked(self):
+        """
+        Private slot handling the selection of the clone group.
+        """
+        self.__updateOK()
+        self.__updateUi()
+    
+    @pyqtSlot(str)
+    def on_condaCloneNameEdit_textChanged(self, txt):
+        """
+        Private slot handling a change of the conda source environment name.
+        
+        @param txt name of the environment to be cloned
+        @type str
+        """
+        self.__updateOK()
+    
+    @pyqtSlot(str)
+    def on_condaCloneDirectoryPicker_textChanged(self, txt):
+        """
+        Private slot handling a change of the cloned from directory.
+        
+        @param txt target directory
+        @type str
+        """
+        self.__updateOK()
+    
     def __setVirtualenvVersion(self):
         """
         Private method to determine the virtualenv version and set the
@@ -259,6 +362,38 @@
         if not self.__pyvenvFound:
             self.pyvenvButton.setChecked(False)
     
+    def __setCondaVersion(self):
+        """
+        Private method to determine the conda version and set the respective
+        label.
+        """
+        exe = Preferences.getConda("CondaExecutable")
+        if not exe:
+            exe = "conda"
+        
+        proc = QProcess()
+        proc.start(exe, ["--version"])
+        if not proc.waitForStarted(5000):
+            self.__condaFound = False
+            version = self.tr('<conda not found or not configured.>')
+        else:
+            proc.waitForFinished(5000)
+            output = str(proc.readAllStandardOutput(),
+                         Preferences.getSystem("IOEncoding"),
+                         'replace').strip()
+            match = re.match(self.__versionRe, output)
+            if match:
+                self.__condaFound = True
+                version = match.group(1)
+            else:
+                self.__condaFound = False
+                version = self.tr('<conda returned strange version info.')
+        self.condaButton.setText(self.tr(
+            "conda Version: {0}".format(version)))
+        self.condaButton.setEnabled(self.__condaFound)
+        if not self.__condaFound:
+            self.condaButton.setChecked(False)
+    
     def __generateTargetDir(self):
         """
         Private method to generate a valid target directory path.
@@ -281,75 +416,97 @@
         @rtype list of str
         """
         args = []
-        if self.virtualenvButton.isChecked():
-            if self.extraSearchPathPicker.text():
-                args.append("--extra-search-dir={0}".format(
-                    Utilities.toNativeSeparators(
-                        self.extraSearchPathPicker.text())))
-            if self.promptPrefixEdit.text():
-                args.append("--prompt={0}".format(
-                    self.promptPrefixEdit.text().replace(" ", "_")))
-            if self.pythonExecPicker.text():
-                args.append("--python={0}".format(
-                    Utilities.toNativeSeparators(
-                        self.pythonExecPicker.text())))
-            elif self.versionComboBox.currentText():
-                args.append("--python=python{0}".format(
-                    self.versionComboBox.currentText()))
-            if self.verbositySpinBox.value() == 1:
-                args.append("--verbose")
-            elif self.verbositySpinBox.value() == -1:
-                args.append("--quiet")
-            if self.clearCheckBox.isChecked():
-                args.append("--clear")
-            if self.systemCheckBox.isChecked():
-                args.append("--system-site-packages")
-            if self.unzipCheckBox.isChecked():
-                args.append("--unzip-setuptools")
-            if self.noSetuptoolsCheckBox.isChecked():
-                args.append("--no-setuptools")
-            if self.noPipCcheckBox.isChecked():
-                args.append("--no-pip")
-            if self.copyCheckBox.isChecked():
-                args.append("--always-copy")
-        elif self.pyvenvButton.isChecked():
-            if self.clearCheckBox.isChecked():
-                args.append("--clear")
-            if self.systemCheckBox.isChecked():
-                args.append("--system-site-packages")
-            if self.noPipCcheckBox.isChecked():
-                args.append("--without-pip")
-            if self.copyCheckBox.isChecked():
-                args.append("--copies")
-            if self.symlinkCheckBox.isChecked():
-                args.append("--symlinks")
-            if self.upgradeCheckBox.isChecked():
-                args.append("--upgrade")
-        targetDirectory = self.__generateTargetDir()
-        args.append(targetDirectory)
+        if self.condaButton.isChecked():
+            # TODO: assemble the conda arguments
+            pass
+        else:
+            if self.virtualenvButton.isChecked():
+                if self.extraSearchPathPicker.text():
+                    args.append("--extra-search-dir={0}".format(
+                        Utilities.toNativeSeparators(
+                            self.extraSearchPathPicker.text())))
+                if self.promptPrefixEdit.text():
+                    args.append("--prompt={0}".format(
+                        self.promptPrefixEdit.text().replace(" ", "_")))
+                if self.pythonExecPicker.text():
+                    args.append("--python={0}".format(
+                        Utilities.toNativeSeparators(
+                            self.pythonExecPicker.text())))
+                elif self.versionComboBox.currentText():
+                    args.append("--python=python{0}".format(
+                        self.versionComboBox.currentText()))
+                if self.verbositySpinBox.value() == 1:
+                    args.append("--verbose")
+                elif self.verbositySpinBox.value() == -1:
+                    args.append("--quiet")
+                if self.clearCheckBox.isChecked():
+                    args.append("--clear")
+                if self.systemCheckBox.isChecked():
+                    args.append("--system-site-packages")
+                if self.unzipCheckBox.isChecked():
+                    args.append("--unzip-setuptools")
+                if self.noSetuptoolsCheckBox.isChecked():
+                    args.append("--no-setuptools")
+                if self.noPipCcheckBox.isChecked():
+                    args.append("--no-pip")
+                if self.copyCheckBox.isChecked():
+                    args.append("--always-copy")
+            elif self.pyvenvButton.isChecked():
+                if self.clearCheckBox.isChecked():
+                    args.append("--clear")
+                if self.systemCheckBox.isChecked():
+                    args.append("--system-site-packages")
+                if self.noPipCcheckBox.isChecked():
+                    args.append("--without-pip")
+                if self.copyCheckBox.isChecked():
+                    args.append("--copies")
+                if self.symlinkCheckBox.isChecked():
+                    args.append("--symlinks")
+                if self.upgradeCheckBox.isChecked():
+                    args.append("--upgrade")
+            targetDirectory = self.__generateTargetDir()
+            args.append(targetDirectory)
+        
         return args
 
     def getData(self):
         """
         Public method to retrieve the dialog data.
         
-        @return tuple containing a flag indicating the pyvenv selection, the
-            process arguments, a name for the virtual environment, a flag
-            indicating to open the target directory after creation, a flag
-            indicating to write a log file, a flag indicating to write a
-            script, the name of the target directory and the name of the
-            Python interpreter to use
-        @rtype tuple of (bool, list of str, str, bool, bool, bool, str, str)
+        @return dictionary containing the data for the two environment
+            variants. The keys for both variants are 'arguments' containing the
+            command line arguments, 'logicalName' containing the environment
+            name to be used with the virtual env manager and 'envType'
+            containing the environment type (virtualenv, pyvenv or conda). The
+            virtualenv/pyvenv specific keys are 'openTarget' containg a flag to
+            open the target directory after creation, 'createLog' containing a
+            flag to write a log file, 'createScript' containing a flag to write
+            a script, 'targetDirectory' containing the target directory and
+            'pythonExe' containing the Python interpreter to be used. The conda
+            specific keys are
+        @rtype dict
         """
+        # TODO: add the conda keys to the above description
+        # TODO: change to returning a method specific dictionary
         args = self.__generateArguments()
-        targetDirectory = self.__generateTargetDir()
-        return (
-            self.pyvenvButton.isChecked(),
-            args,
-            self.nameEdit.text(),
-            self.openCheckBox.isChecked(),
-            self.logCheckBox.isChecked(),
-            self.scriptCheckBox.isChecked(),
-            targetDirectory,
-            Utilities.toNativeSeparators(self.pythonExecPicker.text()),
-        )
+        resultDict = {
+            "arguments": args,
+            "logicalName": self.nameEdit.text(),
+        }
+        if self.condaButton.isChecked():
+            resultDict.update({
+                "envType": "conda",
+            })
+        else:
+            resultDict.update({
+                "envType": ("pyvenv" if self.pyvenvButton.isChecked() else
+                            "virtualenv"), 
+                "openTarget": self.openCheckBox.isChecked(),
+                "createLog": self.logCheckBox.isChecked(),
+                "createScript":self.scriptCheckBox.isChecked(),
+                "targetDirectory": self.__generateTargetDir(),
+                "pythonExe": Utilities.toNativeSeparators(
+                    self.pythonExecPicker.text()),
+            })
+        
+        return resultDict

eric ide

mercurial