diff --git a/python/pluginResources/messages/PyBundle.properties b/python/pluginResources/messages/PyBundle.properties index 7cb9ad1f8a18..22d97cab047d 100644 --- a/python/pluginResources/messages/PyBundle.properties +++ b/python/pluginResources/messages/PyBundle.properties @@ -394,6 +394,26 @@ python.sdk.pipenv.pip.file.watcher=Pipfile Watcher python.sdk.new.project.environment=Environment: python.sdk.new.project.environment.type=Environment type: +python.sdk.poetry.executable.not.found=Poetry executable is not found +python.sdk.poetry.executable=Poetry executable: +python.sdk.poetry.select.executable.title=Select Path to Poetry Executable +python.sdk.poetry.associated.project=Associated project: +python.sdk.poetry.associated.module=Associated module: +python.sdk.poetry.execution.exception.no.project.message=Cannot find the project associated with this Poetry environment +python.sdk.poetry.execution.exception.no.poetry.message=Cannot find Poetry +python.sdk.poetry.execution.exception.error.running.poetry.message=Error Running Poetry +python.sdk.poetry.quickfix.fix.pipenv.name=Fix Poetry interpreter +python.sdk.poetry.quickfix.use.pipenv.name=Use Poetry interpreter +python.sdk.poetry.pip.file.lock.not.found=poetry.lock is not found +python.sdk.poetry.pip.file.lock.out.of.date=poetry.lock is out of date +python.sdk.poetry.pip.file.notification.content=Run poetry lock or poetry update +python.sdk.poetry.pip.file.notification.content.without.updating=Run poetry lock, poetry lock --no-update or poetry update +python.sdk.poetry.pip.file.notification.locking=Locking poetry.lock +python.sdk.poetry.pip.file.notification.locking.without.updating=Locking poetry.lock without updating +python.sdk.poetry.pip.file.notification.updating=Updating Poetry environment +python.sdk.poetry.pip.file.watcher=pyproject.toml Watcher + + python.sdk.file.not.found=File {0} is not found python.sdk.cannot.execute=Cannot execute {0} python.sdk.pipenv.has.been.selected=Pipenv interpreter has been already added, select ''{0}'' in your interpreters list diff --git a/python/src/com/jetbrains/python/sdk/poetry/PyAddNewPoetryFromFilePanel.kt b/python/src/com/jetbrains/python/sdk/poetry/PyAddNewPoetryFromFilePanel.kt index 771c284ffc18..52697939f772 100644 --- a/python/src/com/jetbrains/python/sdk/poetry/PyAddNewPoetryFromFilePanel.kt +++ b/python/src/com/jetbrains/python/sdk/poetry/PyAddNewPoetryFromFilePanel.kt @@ -7,6 +7,7 @@ import com.intellij.openapi.ui.TextFieldWithBrowseButton import com.intellij.openapi.ui.ValidationInfo import com.intellij.openapi.util.NlsSafe import com.intellij.util.ui.FormBuilder +import com.jetbrains.python.PyBundle import org.jetbrains.annotations.SystemDependent import java.awt.BorderLayout import javax.swing.JPanel @@ -27,7 +28,7 @@ class PyAddNewPoetryFromFilePanel(private val module: Module) : JPanel() { getPoetryExecutable()?.absolutePath?.also { text = it } addBrowseFolderListener( - "Select Path to Poetry Executable", + PyBundle.message("python.sdk.poetry.select.executable.title"), null, module.project, FileChooserDescriptorFactory.createSingleFileOrExecutableAppDescriptor() @@ -36,7 +37,7 @@ class PyAddNewPoetryFromFilePanel(private val module: Module) : JPanel() { layout = BorderLayout() val formPanel = FormBuilder.createFormBuilder() - .addLabeledComponent("Poetry executable:", poetryPathField) + .addLabeledComponent(PyBundle.message("python.sdk.poetry.executable"), poetryPathField) .panel add(formPanel, BorderLayout.NORTH) } diff --git a/python/src/com/jetbrains/python/sdk/poetry/PyAddNewPoetryPanel.kt b/python/src/com/jetbrains/python/sdk/poetry/PyAddNewPoetryPanel.kt index 9d92dc5099d3..5459baca5dd2 100644 --- a/python/src/com/jetbrains/python/sdk/poetry/PyAddNewPoetryPanel.kt +++ b/python/src/com/jetbrains/python/sdk/poetry/PyAddNewPoetryPanel.kt @@ -110,12 +110,17 @@ class PyAddNewPoetryPanel(private val project: Project?, val builder = FormBuilder.createFormBuilder().apply { if (module == null && modules.size > 1) { - val associatedObject = if (PlatformUtils.isPyCharm()) "project" else "module" - addLabeledComponent("Associated $associatedObject", moduleField) + val associatedObjectLabel = if (PlatformUtils.isPyCharm()) { + PyBundle.message("python.sdk.poetry.associated.module") + } + else { + PyBundle.message("python.sdk.poetry.associated.project") + } + addLabeledComponent(associatedObjectLabel, moduleField) } addLabeledComponent(PySdkBundle.message("python.venv.base.label"), baseSdkField) addComponent(installPackagesCheckBox) - addLabeledComponent("Poetry executable:", poetryPathField) + addLabeledComponent(PyBundle.message("python.sdk.poetry.executable"), poetryPathField) } add(builder.panel, BorderLayout.NORTH) update() @@ -167,7 +172,7 @@ class PyAddNewPoetryPanel(private val project: Project?, private fun validatePoetryExecutable(): ValidationInfo? { val executable = poetryPathField.text.nullize()?.let { File(it) } ?: detectPoetryExecutable() - ?: return ValidationInfo("Poetry executable is not found") + ?: return ValidationInfo(PyBundle.message("python.sdk.poetry.executable.not.found")) return when { !executable.exists() -> ValidationInfo(PyBundle.message("python.sdk.file.not.found", executable.absolutePath)) !Files.isExecutable(executable.toPath()) || !executable.isFile -> ValidationInfo( diff --git a/python/src/com/jetbrains/python/sdk/poetry/poetry.kt b/python/src/com/jetbrains/python/sdk/poetry/poetry.kt index b5a730210088..831670663acf 100644 --- a/python/src/com/jetbrains/python/sdk/poetry/poetry.kt +++ b/python/src/com/jetbrains/python/sdk/poetry/poetry.kt @@ -15,6 +15,7 @@ import com.intellij.ide.util.PropertiesComponent import com.intellij.notification.NotificationGroup import com.intellij.notification.NotificationDisplayType import com.intellij.notification.NotificationListener +import com.intellij.notification.NotificationType import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.application.ReadAction import com.intellij.openapi.editor.Document @@ -46,6 +47,7 @@ import com.intellij.openapi.vfs.VirtualFile import com.intellij.serviceContainer.AlreadyDisposedException import com.intellij.util.PathUtil import com.intellij.util.PlatformUtils +import com.jetbrains.python.PyBundle import com.jetbrains.python.PythonModuleTypeBase import com.jetbrains.python.inspections.PyPackageRequirementsInspection import com.jetbrains.python.packaging.* @@ -98,7 +100,7 @@ val Module.pyProjectToml: VirtualFile? get() = baseDir?.findChild(PY_PROJECT_TOML)?.let { virtualFile -> (this.name + virtualFile.path).let { key -> - pyProjectTomlCache.getOrPut(key, { getPyProjectTomlForPoetry(virtualFile) }).let { pair -> + pyProjectTomlCache.getOrPut(key) { getPyProjectTomlForPoetry(virtualFile) }.let { pair -> when (virtualFile.modificationStamp) { pair.first -> pair.second else -> pyProjectTomlCache.put(key, getPyProjectTomlForPoetry(virtualFile))?.second @@ -141,7 +143,7 @@ fun getPoetryExecutable(): File? = fun validatePoetryExecutable(poetryExecutable: @SystemDependent String?): ValidationInfo? { val message = if (poetryExecutable.isNullOrBlank()) { - "Poetry executable is not found" + PyBundle.message("python.sdk.poetry.executable.not.found") } else { val file = File(poetryExecutable) @@ -265,7 +267,7 @@ var Sdk.isPoetry: Boolean */ fun runPoetry(sdk: Sdk, vararg args: String): String { val projectPath = sdk.associatedModulePath - ?: throw PyExecutionException("Cannot find the project associated with this Poetry environment", + ?: throw PyExecutionException(PyBundle.message("python.sdk.poetry.execution.exception.no.project.message"), "Poetry", emptyList(), ProcessOutput()) runPoetry(projectPath, "env", "use", sdk.homePath!!) return runPoetry(projectPath, *args) @@ -276,7 +278,8 @@ fun runPoetry(sdk: Sdk, vararg args: String): String { */ fun runPoetry(projectPath: @SystemDependent String?, vararg args: String): String { val executable = getPoetryExecutable()?.path - ?: throw PyExecutionException("Cannot find Poetry", "poetry", emptyList(), ProcessOutput()) + ?: throw PyExecutionException(PyBundle.message("python.sdk.poetry.execution.exception.no.poetry.message"), "poetry", + emptyList(), ProcessOutput()) val command = listOf(executable) + args val commandLine = GeneralCommandLine(command).withWorkDirectory(projectPath) @@ -297,7 +300,8 @@ fun runPoetry(projectPath: @SystemDependent String?, vararg args: String): Strin isCancelled -> throw RunCanceledByUserException() exitCode != 0 -> - throw PyExecutionException("Error Running Poetry", executable, args.asList(), + throw PyExecutionException(PyBundle.message("python.sdk.poetry.execution.exception.error.running.poetry.message"), executable, + args.asList(), stdout, stderr, exitCode, emptyList()) else -> stdout.trim() } @@ -312,11 +316,13 @@ fun runCommand(projectPath: @SystemDependent String, command: String, vararg arg runProcess() } return with(result) { + @Suppress("DialogTitleCapitalization") when { isCancelled -> throw RunCanceledByUserException() exitCode != 0 -> - throw PyExecutionException("Error Running", command, args.asList(), + throw PyExecutionException(PyBundle.message("python.sdk.poetry.execution.exception.error.running.poetry.message"), command, + args.asList(), stdout, stderr, exitCode, emptyList()) else -> stdout } @@ -353,8 +359,8 @@ val Sdk.poetrySources: List */ class UsePoetryQuickFix(sdk: Sdk?, module: Module) : LocalQuickFix { private val quickFixName = when { - sdk != null && sdk.isAssociatedWithAnotherModule(module) -> "Fix Poetry interpreter" - else -> "Use Poetry interpreter" + sdk != null && sdk.isAssociatedWithAnotherModule(module) -> PyBundle.message("python.sdk.poetry.quickfix.fix.pipenv.name") + else -> PyBundle.message("python.sdk.poetry.quickfix.use.pipenv.name") } companion object { @@ -427,10 +433,10 @@ class PyProjectTomlWatcher : EditorFactoryListener { private val changeListenerKey = Key.create("PyProjectToml.change.listener") private val notificationActive = Key.create("PyProjectToml.notification.active") private val content: String = if (poetryVersion?.let { it < "1.1.1" } == true) { - "Run poetry lock or poetry update" + PyBundle.message("python.sdk.poetry.pip.file.notification.content") } else { - "Run poetry lock, poetry lock --no-update or poetry update" + PyBundle.message("python.sdk.poetry.pip.file.notification.content.without.updating") } override fun editorCreated(event: EditorFactoryEvent) { @@ -472,21 +478,21 @@ class PyProjectTomlWatcher : EditorFactoryListener { private fun notifyPyProjectTomlChanged(module: Module) { if (module.getUserData(notificationActive) == true) return - val what = when { - module.poetryLock == null -> "not found" - else -> "out of date" + @Suppress("DialogTitleCapitalization") val title = when (module.poetryLock) { + null -> PyBundle.message("python.sdk.poetry.pip.file.lock.not.found") + else -> PyBundle.message("python.sdk.poetry.pip.file.lock.out.of.date") } - val title = "$POETRY_LOCK is $what" - val notification = LOCK_NOTIFICATION_GROUP.createNotification(title = title, content = content, - listener = NotificationListener { notification, event -> + val notification = LOCK_NOTIFICATION_GROUP.createNotification(title, content, NotificationType.INFORMATION).setListener( + NotificationListener { notification, event -> FileDocumentManager.getInstance().saveAllDocuments() when (event.description) { "#lock" -> - runPoetryInBackground(module, listOf("lock"), "Locking $POETRY_LOCK") + runPoetryInBackground(module, listOf("lock"), PyBundle.message("python.sdk.poetry.pip.file.notification.locking")) "#noupdate" -> - runPoetryInBackground(module, listOf("lock", "--no-update"), "Locking $POETRY_LOCK without updating") + runPoetryInBackground(module, listOf("lock", "--no-update"), + PyBundle.message("python.sdk.poetry.pip.file.notification.locking.without.updating")) "#update" -> - runPoetryInBackground(module, listOf("update"), "Updating Poetry environment") + runPoetryInBackground(module, listOf("update"), PyBundle.message("python.sdk.poetry.pip.file.notification.updating")) } notification.expire() module.putUserData(notificationActive, null) @@ -515,7 +521,8 @@ private val Document.virtualFile: VirtualFile? private fun VirtualFile.getModule(project: Project): Module? = ModuleUtil.findModuleForFile(this, project) -private val LOCK_NOTIFICATION_GROUP = NotificationGroup("$PY_PROJECT_TOML Watcher", NotificationDisplayType.STICKY_BALLOON, false) +private val LOCK_NOTIFICATION_GROUP = NotificationGroup(PyBundle.message("python.sdk.poetry.pip.file.watcher"), + NotificationDisplayType.STICKY_BALLOON, false) //private val Sdk.packageManager: PyPoetryPackageManager // get() = PyPoetryPackageManager.getInstance(this) @@ -603,7 +610,7 @@ fun runPoetryInBackground(module: Module, args: List, description: Strin catch (e: RunCanceledByUserException) { } catch (e: ExecutionException) { - showSdkExecutionException(sdk, e, "Error Running Poetry") + showSdkExecutionException(sdk, e, PyBundle.message("python.sdk.poetry.execution.exception.error.running.poetry.message")) } finally { PythonSdkUtil.getSitePackagesDirectory(sdk)?.refresh(true, true)