mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-20 21:41:24 +07:00
Python: drop unused, deprecated symbols.
Still used symbols are in `DeprecatedUtils` now to be dropped later GitOrigin-RevId: 550eab3d417185b868072b06101bf7634263b4a2
This commit is contained in:
committed by
intellij-monorepo-bot
parent
c8fb196d52
commit
01754edfcb
@@ -1,46 +0,0 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.jetbrains.python.newProject;
|
||||
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Project generation settings selected on the first page of the new project dialog.
|
||||
*
|
||||
* @author catherine
|
||||
* @deprecated Use {@link com.jetbrains.python.newProjectWizard}
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public class PyNewProjectSettings {
|
||||
private Sdk mySdk;
|
||||
/**
|
||||
* Path on remote server for remote project
|
||||
*/
|
||||
private @Nullable String myRemotePath;
|
||||
|
||||
private @Nullable Object myInterpreterInfoForStatistics;
|
||||
|
||||
public final @Nullable Sdk getSdk() {
|
||||
return mySdk;
|
||||
}
|
||||
|
||||
public final void setSdk(final @Nullable Sdk sdk) {
|
||||
mySdk = sdk;
|
||||
}
|
||||
|
||||
public final void setRemotePath(final @Nullable String remotePath) {
|
||||
myRemotePath = remotePath;
|
||||
}
|
||||
|
||||
public final void setInterpreterInfoForStatistics(@Nullable Object interpreterInfoForStatistics) {
|
||||
myInterpreterInfoForStatistics = interpreterInfoForStatistics;
|
||||
}
|
||||
|
||||
public final @Nullable Object getInterpreterInfoForStatistics() {
|
||||
return myInterpreterInfoForStatistics;
|
||||
}
|
||||
|
||||
public final @Nullable String getRemotePath() {
|
||||
return myRemotePath;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.python.community.plugin.java.facet;
|
||||
|
||||
import com.intellij.ide.util.projectWizard.ModuleWizardStep;
|
||||
|
||||
@@ -24,7 +24,7 @@ import com.jetbrains.python.Result
|
||||
import com.jetbrains.python.configuration.PyConfigurableInterpreterList
|
||||
import com.jetbrains.python.errorProcessing.ErrorSink
|
||||
import com.jetbrains.python.inspections.PyInterpreterInspection
|
||||
import com.jetbrains.python.newProject.steps.ProjectSpecificSettingsStep
|
||||
import com.jetbrains.python.newProject.DeprecatedUtils
|
||||
import com.jetbrains.python.projectCreation.createVenvAndSdk
|
||||
import com.jetbrains.python.sdk.PySdkToInstall
|
||||
import com.jetbrains.python.sdk.add.PySdkPathChoosingComboBox
|
||||
@@ -111,7 +111,7 @@ internal class PythonLangSupport(private val errorSink: ErrorSink = ShowingMessa
|
||||
|
||||
override fun startFromWelcomeFrame(startCallback: (Sdk?) -> Unit) {
|
||||
val allExistingSdks = listOf(*PyConfigurableInterpreterList.getInstance(null).model.sdks)
|
||||
val existingSdks = ProjectSpecificSettingsStep.getValidPythonSdks(allExistingSdks)
|
||||
val existingSdks = DeprecatedUtils.getValidPythonSdks(allExistingSdks)
|
||||
|
||||
ApplicationManager.getApplication().executeOnPooledThread {
|
||||
val context = UserDataHolderBase()
|
||||
|
||||
@@ -8,7 +8,7 @@ import com.intellij.openapi.util.UserDataHolderBase
|
||||
import com.intellij.ui.dsl.builder.Panel
|
||||
import com.jetbrains.python.configuration.PyConfigurableInterpreterList
|
||||
import com.jetbrains.python.inspections.PyInterpreterInspection
|
||||
import com.jetbrains.python.newProject.steps.ProjectSpecificSettingsStep
|
||||
import com.jetbrains.python.newProject.DeprecatedUtils
|
||||
import com.jetbrains.python.sdk.findBaseSdks
|
||||
import com.jetbrains.python.sdk.flavors.PythonSdkFlavor
|
||||
import com.jetbrains.python.sdk.pythonSdk
|
||||
@@ -59,7 +59,7 @@ object PythonLessonsUtil {
|
||||
}
|
||||
|
||||
val allExistingSdks = listOf(*PyConfigurableInterpreterList.getInstance(null).model.sdks)
|
||||
val existingSdks = ProjectSpecificSettingsStep.getValidPythonSdks(allExistingSdks)
|
||||
val existingSdks = DeprecatedUtils.getValidPythonSdks(allExistingSdks)
|
||||
|
||||
val interpreterVersions = CompletableFuture<List<String>>()
|
||||
ApplicationManager.getApplication().executeOnPooledThread {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.jetbrains.python.module;
|
||||
|
||||
import com.intellij.ide.util.projectWizard.ModuleBuilder;
|
||||
@@ -21,8 +21,6 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static com.jetbrains.python.newProject.PythonProjectGenerator.NO_SETTINGS;
|
||||
|
||||
|
||||
public class PythonModuleBuilderBase extends ModuleBuilder {
|
||||
private final List<Runnable> mySdkChangedListeners = ContainerUtil.createLockFreeCopyOnWriteList();
|
||||
@@ -92,7 +90,7 @@ public class PythonModuleBuilderBase extends ModuleBuilder {
|
||||
if (contentRoots.length > 0 && contentRoots[0] != null) {
|
||||
dir = contentRoots[0];
|
||||
}
|
||||
myGenerator.generateProject(project, dir, NO_SETTINGS, module);
|
||||
myGenerator.generateProject(project, dir, new Object(), module);
|
||||
}
|
||||
return module;
|
||||
}
|
||||
|
||||
175
python/src/com/jetbrains/python/newProject/DeprecatedUtils.java
Normal file
175
python/src/com/jetbrains/python/newProject/DeprecatedUtils.java
Normal file
@@ -0,0 +1,175 @@
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.jetbrains.python.newProject;
|
||||
|
||||
import com.intellij.execution.ExecutionException;
|
||||
import com.intellij.openapi.application.Application;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.progress.Task;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.jetbrains.python.PyBundle;
|
||||
import com.jetbrains.python.PyPsiPackageUtil;
|
||||
import com.jetbrains.python.packaging.PyPackage;
|
||||
import com.jetbrains.python.packaging.PyPackageManager;
|
||||
import com.jetbrains.python.packaging.PyPackageUtil;
|
||||
import com.jetbrains.python.packaging.PyPackagesNotificationPanel;
|
||||
import com.jetbrains.python.packaging.ui.PyPackageManagementService;
|
||||
import com.jetbrains.python.sdk.PreferredSdkComparator;
|
||||
import com.jetbrains.python.sdk.PySdkExtKt;
|
||||
import com.jetbrains.python.sdk.PythonSdkType;
|
||||
import com.jetbrains.python.sdk.PythonSdkUtil;
|
||||
import one.util.streamex.StreamEx;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
|
||||
/**
|
||||
* Various ancient utils that are still used, but will be dropped soon.
|
||||
*
|
||||
* @deprecated Use {@link com.jetbrains.python.newProjectWizard}
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
@ApiStatus.Internal
|
||||
public final class DeprecatedUtils {
|
||||
private DeprecatedUtils() {
|
||||
}
|
||||
/**
|
||||
* @param sdkAndException if you have SDK and execution exception provide them here (both must not be null).
|
||||
*/
|
||||
private static void reportPackageInstallationFailure(final @NotNull String frameworkName,
|
||||
final @Nullable Pair<Sdk, ExecutionException> sdkAndException) {
|
||||
|
||||
final PyPackageManagementService.PyPackageInstallationErrorDescription errorDescription =
|
||||
getErrorDescription(sdkAndException, frameworkName);
|
||||
final Application app = ApplicationManager.getApplication();
|
||||
app.invokeLater(() -> {
|
||||
PyPackagesNotificationPanel.showPackageInstallationError(PyBundle.message("python.new.project.install.failed.title", frameworkName),
|
||||
errorDescription);
|
||||
});
|
||||
}
|
||||
|
||||
private static @NotNull PyPackageManagementService.PyPackageInstallationErrorDescription getErrorDescription(final @Nullable Pair<Sdk, ExecutionException> sdkAndException,
|
||||
@NotNull String packageName) {
|
||||
PyPackageManagementService.PyPackageInstallationErrorDescription errorDescription = null;
|
||||
if (sdkAndException != null) {
|
||||
final ExecutionException exception = sdkAndException.second;
|
||||
errorDescription =
|
||||
PyPackageManagementService.toErrorDescription(Collections.singletonList(exception), sdkAndException.first, packageName);
|
||||
if (errorDescription == null) {
|
||||
errorDescription = PyPackageManagementService.PyPackageInstallationErrorDescription.createFromMessage(exception.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
if (errorDescription == null) {
|
||||
errorDescription = PyPackageManagementService.PyPackageInstallationErrorDescription.createFromMessage(
|
||||
PyBundle.message("python.new.project.error.solution.another.sdk"));
|
||||
}
|
||||
return errorDescription;
|
||||
}
|
||||
|
||||
|
||||
//TODO: Support for plugin also
|
||||
|
||||
/**
|
||||
* Installs framework and runs callback on success.
|
||||
* Installation runs in modal dialog and callback is posted to AWT thread.
|
||||
* <p>
|
||||
* If "forceInstallFramework" is passed then installs framework in any case.
|
||||
* If SDK is remote then checks if it has interpreter and installs if missing
|
||||
*
|
||||
* @param frameworkName user-readable framework name (i.e. "Django")
|
||||
* @param requirement name of requirement to install (i.e. "django")
|
||||
* @param forceInstallFramework pass true if you are sure required framework is missing
|
||||
* @param callback to be called after installation (or instead of is framework is installed) on AWT thread
|
||||
* @return future to be used instead of callback.
|
||||
*/
|
||||
public static @NotNull Future<Void> installFrameworkIfNeeded(final @NotNull Project project,
|
||||
final @NotNull String frameworkName,
|
||||
final @NotNull String requirement,
|
||||
final @NotNull Sdk sdk,
|
||||
final boolean forceInstallFramework,
|
||||
final @Nullable Runnable callback) {
|
||||
|
||||
var future = new CompletableFuture<Void>();
|
||||
|
||||
// For remote SDK we are not sure if framework exists or not, so we'll check it anyway
|
||||
if (forceInstallFramework || PythonSdkUtil.isRemote(sdk)) {
|
||||
|
||||
ProgressManager.getInstance()
|
||||
.run(new Task.Modal(project, PyBundle.message("python.install.framework.ensure.installed", frameworkName), false) {
|
||||
@Override
|
||||
public void run(final @NotNull ProgressIndicator indicator) {
|
||||
installPackages(frameworkName, forceInstallFramework, indicator, requirement, sdk);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onThrowable(@NotNull Throwable error) {
|
||||
future.completeExceptionally(error);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess() {
|
||||
future.complete(null);
|
||||
// Installed / checked successfully, call callback on AWT
|
||||
if (callback != null) {
|
||||
callback.run();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
future.complete(null);
|
||||
// No need to install, but still need to call callback on AWT
|
||||
if (callback != null) {
|
||||
assert SwingUtilities.isEventDispatchThread();
|
||||
callback.run();
|
||||
}
|
||||
}
|
||||
return future;
|
||||
}
|
||||
|
||||
private static void installPackages(final @NotNull String frameworkName,
|
||||
boolean forceInstallFramework,
|
||||
@NotNull ProgressIndicator indicator,
|
||||
final @NotNull String requirement,
|
||||
final @NotNull Sdk sdk) {
|
||||
final PyPackageManager packageManager = PyPackageManager.getInstance(sdk);
|
||||
boolean installed = false;
|
||||
if (!forceInstallFramework) {
|
||||
// First check if we need to do it
|
||||
indicator.setText(PyBundle.message("python.install.framework.checking.is.installed", frameworkName));
|
||||
final List<PyPackage> packages = PyPackageUtil.refreshAndGetPackagesModally(sdk);
|
||||
installed = PyPsiPackageUtil.findPackage(packages, requirement) != null;
|
||||
}
|
||||
|
||||
if (!installed) {
|
||||
indicator.setText(PyBundle.message("python.install.framework.installing", frameworkName));
|
||||
try {
|
||||
packageManager.install(requirement);
|
||||
packageManager.refresh();
|
||||
}
|
||||
catch (final ExecutionException e) {
|
||||
reportPackageInstallationFailure(requirement, Pair.create(sdk, e));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Migrate to interpreter service
|
||||
public static @NotNull List<Sdk> getValidPythonSdks(@NotNull List<Sdk> existingSdks) {
|
||||
return StreamEx
|
||||
.of(existingSdks)
|
||||
.filter(sdk -> sdk != null && sdk.getSdkType() instanceof PythonSdkType && PySdkExtKt.getSdkSeemsValid(sdk))
|
||||
.sorted(new PreferredSdkComparator())
|
||||
.toList();
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.jetbrains.python.newProject
|
||||
|
||||
import com.intellij.ide.highlighter.ModuleFileType
|
||||
@@ -19,7 +19,6 @@ import com.intellij.ui.dsl.builder.AlignX
|
||||
import com.intellij.ui.dsl.builder.Panel
|
||||
import com.jetbrains.python.PyBundle
|
||||
import com.jetbrains.python.PythonModuleTypeBase
|
||||
import com.jetbrains.python.newProject.steps.ProjectSpecificSettingsStep
|
||||
import com.jetbrains.python.newProject.steps.PyAddExistingSdkPanel
|
||||
import com.jetbrains.python.sdk.PySdkProvider
|
||||
import com.jetbrains.python.sdk.PySdkSettings
|
||||
@@ -237,5 +236,5 @@ private fun existingSdks(context: WizardContext): List<Sdk> {
|
||||
disposeUIResources()
|
||||
})
|
||||
}
|
||||
return ProjectSpecificSettingsStep.getValidPythonSdks(sdksModel.sdks.toList())
|
||||
return DeprecatedUtils.getValidPythonSdks(sdksModel.sdks.toList())
|
||||
}
|
||||
|
||||
@@ -1,407 +0,0 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.jetbrains.python.newProject;
|
||||
|
||||
import com.intellij.execution.ExecutionException;
|
||||
import com.intellij.facet.ui.ValidationResult;
|
||||
import com.intellij.icons.AllIcons.General;
|
||||
import com.intellij.openapi.application.Application;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.progress.Task;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.util.NlsContexts.DialogMessage;
|
||||
import com.intellij.openapi.util.NlsSafe;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.platform.DirectoryProjectGeneratorBase;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.jetbrains.python.PyBundle;
|
||||
import com.jetbrains.python.PyPsiPackageUtil;
|
||||
import com.jetbrains.python.newProject.collector.InterpreterStatisticsInfo;
|
||||
import com.jetbrains.python.newProjectWizard.collector.PyProjectTypeGenerator;
|
||||
import com.jetbrains.python.newProjectWizard.collector.PythonNewProjectWizardCollector;
|
||||
import com.jetbrains.python.packaging.PyPackage;
|
||||
import com.jetbrains.python.packaging.PyPackageManager;
|
||||
import com.jetbrains.python.packaging.PyPackageUtil;
|
||||
import com.jetbrains.python.packaging.PyPackagesNotificationPanel;
|
||||
import com.jetbrains.python.packaging.ui.PyPackageManagementService;
|
||||
import com.jetbrains.python.remote.*;
|
||||
import com.jetbrains.python.sdk.PyLazySdk;
|
||||
import com.jetbrains.python.sdk.PythonSdkUtil;
|
||||
import com.jetbrains.python.sdk.add.v2.PythonInterpreterSelectionMode;
|
||||
import com.jetbrains.python.statistics.PyStatisticToolsKt;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.io.File;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link com.jetbrains.python.newProjectWizard}
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public abstract class PythonProjectGenerator<T extends PyNewProjectSettings> extends DirectoryProjectGeneratorBase<T> implements
|
||||
PyProjectTypeGenerator {
|
||||
public static final PyNewProjectSettings NO_SETTINGS = new PyNewProjectSettings();
|
||||
private static final Logger LOGGER = Logger.getInstance(PythonProjectGenerator.class);
|
||||
|
||||
private final List<SettingsListener> myListeners = ContainerUtil.createLockFreeCopyOnWriteList();
|
||||
private final boolean myAllowRemoteProjectCreation;
|
||||
|
||||
protected Consumer<String> myErrorCallback;
|
||||
|
||||
private final @Nullable PythonInterpreterSelectionMode preferredEnvironmentType;
|
||||
|
||||
/**
|
||||
* @param allowRemoteProjectCreation if project of this type could be created remotely
|
||||
*/
|
||||
protected PythonProjectGenerator(final boolean allowRemoteProjectCreation) {
|
||||
this(allowRemoteProjectCreation, null);
|
||||
}
|
||||
|
||||
protected PythonProjectGenerator() {
|
||||
this(false, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final @NlsSafe @NotNull String getProjectTypeForStatistics() {
|
||||
return getClass().getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param allowRemoteProjectCreation if project of this type could be created remotely
|
||||
* @param preferredInterpreter interpreter type to select by default
|
||||
*/
|
||||
protected PythonProjectGenerator(final boolean allowRemoteProjectCreation,
|
||||
@Nullable PythonInterpreterSelectionMode preferredInterpreter) {
|
||||
myAllowRemoteProjectCreation = allowRemoteProjectCreation;
|
||||
preferredEnvironmentType = preferredInterpreter;
|
||||
}
|
||||
|
||||
public final void setErrorCallback(final @NotNull Consumer<String> errorCallback) {
|
||||
myErrorCallback = errorCallback;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks if project type and remote ask allows project creation.
|
||||
* Throws exception with reason if can't
|
||||
*
|
||||
* @param sdk sdk to check
|
||||
* @param projectDirectory base project directory
|
||||
* @throws PyNoProjectAllowedOnSdkException project can't be created (check message)
|
||||
*/
|
||||
public void checkProjectCanBeCreatedOnSdk(final @NotNull Sdk sdk,
|
||||
final @NotNull File projectDirectory) throws PyNoProjectAllowedOnSdkException {
|
||||
|
||||
// Check if project does not support remote creation at all
|
||||
if (!myAllowRemoteProjectCreation && PythonSdkUtil.isRemote(sdk)) {
|
||||
throw new PyNoProjectAllowedOnSdkException(
|
||||
PyBundle.message("python.remote.interpreter.can.t.create.project.this.type"));
|
||||
}
|
||||
|
||||
|
||||
// Check if project synchronizer could be used with this project dir
|
||||
// No project can be created remotely if project synchronizer can't work with it
|
||||
|
||||
final PyProjectSynchronizer synchronizer = PyProjectSynchronizerProvider.getSynchronizer(sdk);
|
||||
if (synchronizer == null) {
|
||||
return;
|
||||
}
|
||||
final String syncError = synchronizer.checkSynchronizationAvailable(new PySyncCheckOnly(projectDirectory));
|
||||
if (syncError != null) {
|
||||
throw new PyNoProjectAllowedOnSdkException(syncError);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void generateProject(final @NotNull Project project,
|
||||
final @NotNull VirtualFile baseDir,
|
||||
final @NotNull T settings,
|
||||
final @NotNull Module module) {
|
||||
// Use NO_SETTINGS to avoid nullable settings of project generator
|
||||
if (settings == NO_SETTINGS) {
|
||||
// We are in Intellij Module and framework is implemented as project template, not facet.
|
||||
// See class doc for mote info
|
||||
configureProjectNoSettings(project, baseDir, module);
|
||||
return;
|
||||
}
|
||||
|
||||
/*Instead of this method overwrite ``configureProject``*/
|
||||
|
||||
// If we deal with remote project -- use remote manager to configure it
|
||||
final Sdk sdk = settings.getSdk();
|
||||
LOGGER.info(String.format("Wizard created PythonSDK %s", sdk));
|
||||
if (sdk instanceof PyLazySdk) {
|
||||
final Sdk createdSdk = ((PyLazySdk)sdk).create();
|
||||
LOGGER.info(String.format("Lazy PythonSDK generated sdk: %s", createdSdk));
|
||||
settings.setSdk(createdSdk);
|
||||
}
|
||||
|
||||
final PyProjectSynchronizer synchronizer = sdk != null ? PyProjectSynchronizerProvider.getSynchronizer(sdk) : null;
|
||||
|
||||
if (synchronizer != null) {
|
||||
// Before project creation we need to configure sync
|
||||
// We call "checkSynchronizationAvailable" until it returns success (means sync is available)
|
||||
// Or user confirms she does not need sync
|
||||
String userProvidedPath = settings.getRemotePath();
|
||||
while (true) {
|
||||
final String syncError = synchronizer.checkSynchronizationAvailable(new PySyncCheckCreateIfPossible(module, userProvidedPath));
|
||||
if (syncError == null) {
|
||||
break;
|
||||
}
|
||||
userProvidedPath = null; // According to checkSynchronizationAvailable should be cleared
|
||||
final String message =
|
||||
PyBundle.message("python.new.project.synchronization.not.configured.dialog.message", syncError);
|
||||
if (Messages.showYesNoDialog(project,
|
||||
message,
|
||||
PyBundle.message("python.new.project.synchronization.not.configured.dialog.title"),
|
||||
General.WarningDialog) == Messages.YES) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
configureProject(project, baseDir, settings, module, synchronizer);
|
||||
reportStatistics(settings);
|
||||
}
|
||||
|
||||
/**
|
||||
* Report FUS statics on the created project.
|
||||
* Inheritors can override this method to supply customized data for the statistics.
|
||||
*/
|
||||
protected void reportStatistics(final @NotNull T settings) {
|
||||
var statisticsInfo = settings.getInterpreterInfoForStatistics();
|
||||
if (statisticsInfo instanceof InterpreterStatisticsInfo interpreterStatisticsInfo && settings.getSdk() != null) {
|
||||
PythonNewProjectWizardCollector.logPythonNewProjectGenerated(interpreterStatisticsInfo,
|
||||
PyStatisticToolsKt.getVersion(settings.getSdk()),
|
||||
this,
|
||||
Collections.emptyList());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as {@link #configureProject(Project, VirtualFile, PyNewProjectSettings, Module, PyProjectSynchronizer)}
|
||||
* but with out of settings. Called by Intellij Plugin when framework is installed as project template.
|
||||
*/
|
||||
protected void configureProjectNoSettings(final @NotNull Project project,
|
||||
final @NotNull VirtualFile baseDir,
|
||||
final @NotNull Module module) {
|
||||
throw new IllegalStateException(String.format("%s does not support project creation with out of settings. " +
|
||||
"See %s doc for detail", getClass(), PythonProjectGenerator.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* Does real work to generate project.
|
||||
* Parent class does its best to handle remote interpreters.
|
||||
* Inheritors should only create project.
|
||||
* To support remote project creation, be sure to use {@link PyProjectSynchronizer}.
|
||||
* <br/>
|
||||
* When overwriting this method, <strong>be sure</strong> to call super() or call
|
||||
* {@link PyProjectSynchronizer#syncProject(Module, PySyncDirection, Consumer, String...)} at least once: automatic sync works only after it.
|
||||
*
|
||||
* @param synchronizer null if project is local and no sync required.
|
||||
* Otherwise, be sure to use it move code between local (java) and remote (python) side.
|
||||
* Remote interpreters can't be used with out of it. Contract is following:
|
||||
* <ol>
|
||||
* <li>Create some code on python (remote) side using helpers</li>
|
||||
* <li>call {@link PyProjectSynchronizer#syncProject(Module, PySyncDirection, Consumer, String...)}</li>
|
||||
* <li>Change locally</li>
|
||||
* <li>call {@link PyProjectSynchronizer#syncProject(Module, PySyncDirection, Consumer, String...)} again in opposite direction</li>
|
||||
* </ol>
|
||||
*/
|
||||
|
||||
protected void configureProject(final @NotNull Project project,
|
||||
final @NotNull VirtualFile baseDir,
|
||||
final @NotNull T settings,
|
||||
final @NotNull Module module,
|
||||
final @Nullable PyProjectSynchronizer synchronizer) {
|
||||
// Automatic deployment works only after first sync
|
||||
if (synchronizer != null) {
|
||||
synchronizer.syncProject(module, PySyncDirection.LOCAL_TO_REMOTE, null);
|
||||
}
|
||||
}
|
||||
|
||||
public Object getProjectSettings() {
|
||||
return new PyNewProjectSettings();
|
||||
}
|
||||
|
||||
public ValidationResult warningValidation(final @Nullable Sdk sdk) {
|
||||
return ValidationResult.OK;
|
||||
}
|
||||
|
||||
public void addSettingsStateListener(@NotNull SettingsListener listener) {
|
||||
myListeners.add(listener);
|
||||
}
|
||||
|
||||
public void locationChanged(final @NotNull String newLocation) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Python interpreter type this generator prefered to use. Null if no preferences
|
||||
*/
|
||||
public final @Nullable PythonInterpreterSelectionMode getPreferredEnvironmentType() {
|
||||
return preferredEnvironmentType;
|
||||
}
|
||||
|
||||
public interface SettingsListener {
|
||||
void stateChanged();
|
||||
}
|
||||
|
||||
public void afterProjectGenerated(final @NotNull Project project) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param sdkAndException if you have SDK and execution exception provide them here (both must not be null).
|
||||
*/
|
||||
protected static void reportPackageInstallationFailure(final @NotNull String frameworkName,
|
||||
final @Nullable Pair<Sdk, ExecutionException> sdkAndException) {
|
||||
|
||||
final PyPackageManagementService.PyPackageInstallationErrorDescription errorDescription =
|
||||
getErrorDescription(sdkAndException, frameworkName);
|
||||
final Application app = ApplicationManager.getApplication();
|
||||
app.invokeLater(() -> {
|
||||
PyPackagesNotificationPanel.showPackageInstallationError(PyBundle.message("python.new.project.install.failed.title", frameworkName),
|
||||
errorDescription);
|
||||
});
|
||||
}
|
||||
|
||||
private static @NotNull PyPackageManagementService.PyPackageInstallationErrorDescription getErrorDescription(final @Nullable Pair<Sdk, ExecutionException> sdkAndException,
|
||||
@NotNull String packageName) {
|
||||
PyPackageManagementService.PyPackageInstallationErrorDescription errorDescription = null;
|
||||
if (sdkAndException != null) {
|
||||
final ExecutionException exception = sdkAndException.second;
|
||||
errorDescription =
|
||||
PyPackageManagementService.toErrorDescription(Collections.singletonList(exception), sdkAndException.first, packageName);
|
||||
if (errorDescription == null) {
|
||||
errorDescription = PyPackageManagementService.PyPackageInstallationErrorDescription.createFromMessage(exception.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
if (errorDescription == null) {
|
||||
errorDescription = PyPackageManagementService.PyPackageInstallationErrorDescription.createFromMessage(
|
||||
PyBundle.message("python.new.project.error.solution.another.sdk"));
|
||||
}
|
||||
return errorDescription;
|
||||
}
|
||||
|
||||
|
||||
//TODO: Support for plugin also
|
||||
|
||||
/**
|
||||
* Installs framework and runs callback on success.
|
||||
* Installation runs in modal dialog and callback is posted to AWT thread.
|
||||
* <p>
|
||||
* If "forceInstallFramework" is passed then installs framework in any case.
|
||||
* If SDK is remote then checks if it has interpreter and installs if missing
|
||||
*
|
||||
* @param frameworkName user-readable framework name (i.e. "Django")
|
||||
* @param requirement name of requirement to install (i.e. "django")
|
||||
* @param forceInstallFramework pass true if you are sure required framework is missing
|
||||
* @param callback to be called after installation (or instead of is framework is installed) on AWT thread
|
||||
* @return future to be used instead of callback.
|
||||
*/
|
||||
public static @NotNull Future<Void> installFrameworkIfNeeded(final @NotNull Project project,
|
||||
final @NotNull String frameworkName,
|
||||
final @NotNull String requirement,
|
||||
final @NotNull Sdk sdk,
|
||||
final boolean forceInstallFramework,
|
||||
final @Nullable Runnable callback) {
|
||||
|
||||
var future = new CompletableFuture<Void>();
|
||||
|
||||
// For remote SDK we are not sure if framework exists or not, so we'll check it anyway
|
||||
if (forceInstallFramework || PythonSdkUtil.isRemote(sdk)) {
|
||||
|
||||
ProgressManager.getInstance()
|
||||
.run(new Task.Modal(project, PyBundle.message("python.install.framework.ensure.installed", frameworkName), false) {
|
||||
@Override
|
||||
public void run(final @NotNull ProgressIndicator indicator) {
|
||||
installPackages(frameworkName, forceInstallFramework, indicator, requirement, sdk);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onThrowable(@NotNull Throwable error) {
|
||||
future.completeExceptionally(error);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess() {
|
||||
future.complete(null);
|
||||
// Installed / checked successfully, call callback on AWT
|
||||
if (callback != null) {
|
||||
callback.run();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
future.complete(null);
|
||||
// No need to install, but still need to call callback on AWT
|
||||
if (callback != null) {
|
||||
assert SwingUtilities.isEventDispatchThread();
|
||||
callback.run();
|
||||
}
|
||||
}
|
||||
return future;
|
||||
}
|
||||
|
||||
public @Nullable String getNewProjectPrefix() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean supportsWelcomeScript() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* To be thrown if project can't be created on this sdk
|
||||
*
|
||||
* @author Ilya.Kazakevich
|
||||
*/
|
||||
public static class PyNoProjectAllowedOnSdkException extends Exception {
|
||||
/**
|
||||
* @param reason why project can't be created
|
||||
*/
|
||||
PyNoProjectAllowedOnSdkException(final @NotNull @DialogMessage String reason) {
|
||||
super(reason);
|
||||
}
|
||||
}
|
||||
|
||||
private static void installPackages(final @NotNull String frameworkName,
|
||||
boolean forceInstallFramework,
|
||||
@NotNull ProgressIndicator indicator,
|
||||
final @NotNull String requirement,
|
||||
final @NotNull Sdk sdk) {
|
||||
final PyPackageManager packageManager = PyPackageManager.getInstance(sdk);
|
||||
boolean installed = false;
|
||||
if (!forceInstallFramework) {
|
||||
// First check if we need to do it
|
||||
indicator.setText(PyBundle.message("python.install.framework.checking.is.installed", frameworkName));
|
||||
final List<PyPackage> packages = PyPackageUtil.refreshAndGetPackagesModally(sdk);
|
||||
installed = PyPsiPackageUtil.findPackage(packages, requirement) != null;
|
||||
}
|
||||
|
||||
if (!installed) {
|
||||
indicator.setText(PyBundle.message("python.install.framework.installing", frameworkName));
|
||||
try {
|
||||
packageManager.install(requirement);
|
||||
packageManager.refresh();
|
||||
}
|
||||
catch (final ExecutionException e) {
|
||||
reportPackageInstallationFailure(requirement, Pair.create(sdk, e));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.jetbrains.python.newProject.steps;
|
||||
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.jetbrains.python.sdk.PreferredSdkComparator;
|
||||
import com.jetbrains.python.sdk.PySdkExtKt;
|
||||
import com.jetbrains.python.sdk.PythonSdkType;
|
||||
import one.util.streamex.StreamEx;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link com.jetbrains.python.newProjectWizard}
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public final class ProjectSpecificSettingsStep {
|
||||
private ProjectSpecificSettingsStep() {
|
||||
}
|
||||
|
||||
// TODO: Migrate to interpreter service
|
||||
public static @NotNull List<Sdk> getValidPythonSdks(@NotNull List<Sdk> existingSdks) {
|
||||
return StreamEx
|
||||
.of(existingSdks)
|
||||
.filter(sdk -> sdk != null && sdk.getSdkType() instanceof PythonSdkType && PySdkExtKt.getSdkSeemsValid(sdk))
|
||||
.sorted(new PreferredSdkComparator())
|
||||
.toList();
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
|
||||
package com.jetbrains.python.newProject.steps
|
||||
|
||||
import com.intellij.ide.IdeBundle
|
||||
import com.intellij.openapi.GitRepositoryInitializer
|
||||
import com.intellij.openapi.progress.runBackgroundableTask
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated Use [com.jetbrains.python.newProjectWizard]
|
||||
*/
|
||||
@java.lang.Deprecated(forRemoval = true)
|
||||
@Deprecated("use com.jetbrains.python.newProjectWizard", level = DeprecationLevel.ERROR)
|
||||
class PythonProjectSpecificSettingsStep {
|
||||
companion object {
|
||||
/**
|
||||
* @deprecated Use [com.jetbrains.python.newProjectWizard]
|
||||
*/
|
||||
@JvmStatic
|
||||
@java.lang.Deprecated(forRemoval = true)
|
||||
@Deprecated("use PyV3 in com.jetbrains.python.newProjectWizard or access GitRepositoryInitializer directly",
|
||||
level = DeprecationLevel.ERROR)
|
||||
fun initializeGit(project: Project, root: VirtualFile) {
|
||||
runBackgroundableTask(IdeBundle.message("progress.title.creating.git.repository"), project) {
|
||||
GitRepositoryInitializer.getInstance()?.initRepository(project, root, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,6 @@ import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.jetbrains.python.PySdkBundle;
|
||||
import com.jetbrains.python.psi.LanguageLevel;
|
||||
import com.jetbrains.python.sdk.PyLazySdk;
|
||||
import com.jetbrains.python.sdk.PySdkExtKt;
|
||||
import com.jetbrains.python.sdk.PySdkUtil;
|
||||
import com.jetbrains.python.sdk.PythonEnvUtil;
|
||||
@@ -152,10 +151,6 @@ public class PyPackageManagerImpl extends PyPackageManagerImplBase {
|
||||
|
||||
@Override
|
||||
protected @NotNull List<PyPackage> collectPackages() throws ExecutionException {
|
||||
if (getSdk() instanceof PyLazySdk) {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
try {
|
||||
LOG.debug("Collecting installed packages for the SDK " + getSdk().getName(), new Throwable());
|
||||
String output = getHelperResult(List.of("list"), false, false);
|
||||
|
||||
@@ -33,7 +33,6 @@ import com.jetbrains.python.run.PythonInterpreterTargetEnvironmentFactory;
|
||||
import com.jetbrains.python.run.PythonScriptExecution;
|
||||
import com.jetbrains.python.run.PythonScripts;
|
||||
import com.jetbrains.python.run.target.HelpersAwareTargetEnvironmentRequest;
|
||||
import com.jetbrains.python.sdk.PyLazySdk;
|
||||
import com.jetbrains.python.sdk.PySdkExtKt;
|
||||
import com.jetbrains.python.venvReader.VirtualEnvReader;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
@@ -181,10 +180,6 @@ public final class PyTargetEnvironmentPackageManager extends PyPackageManagerImp
|
||||
|
||||
@Override
|
||||
protected @NotNull List<PyPackage> collectPackages() throws ExecutionException {
|
||||
if (getSdk() instanceof PyLazySdk) {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
HelpersAwareTargetEnvironmentRequest helpersAwareRequest = getPythonTargetInterpreter();
|
||||
TargetEnvironmentRequest targetEnvironmentRequest = helpersAwareRequest.getTargetEnvironmentRequest();
|
||||
final String output;
|
||||
|
||||
@@ -6,6 +6,7 @@ import com.intellij.openapi.progress.ProgressIndicator
|
||||
import com.intellij.openapi.progress.runBlockingCancellable
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.projectRoots.Sdk
|
||||
import com.intellij.util.concurrency.annotations.RequiresBackgroundThread
|
||||
import com.jetbrains.python.PyBundle
|
||||
import com.jetbrains.python.packaging.PyPackage
|
||||
import com.jetbrains.python.packaging.PyRequirement
|
||||
@@ -16,6 +17,7 @@ import org.jetbrains.annotations.ApiStatus
|
||||
class PythonPackagesInstaller {
|
||||
companion object {
|
||||
@JvmStatic
|
||||
@RequiresBackgroundThread
|
||||
fun installPackages(
|
||||
project: Project,
|
||||
sdk: Sdk,
|
||||
|
||||
@@ -1,18 +1,4 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.jetbrains.python.remote
|
||||
|
||||
import com.intellij.openapi.extensions.ExtensionPointName
|
||||
@@ -31,7 +17,7 @@ typealias PathMappings = List<PathMappingSettings.PathMapping>
|
||||
/**
|
||||
* ProjectSynchronizer is an engine that synchronize code between local and remote system or between java (which is local)
|
||||
* and python (which may be remote).
|
||||
* This engine is sdk-specific and used by [com.jetbrains.python.newProject.PythonProjectGenerator] (and friends).
|
||||
* This engine is sdk-specific and used by [com.jetbrains.python.newProject.DeprecatedUtils] (and friends).
|
||||
*
|
||||
* When generator creates remote project, it may use python helpers (with aid of tasks) and it may need some way
|
||||
* to pull remote files, patch them and push 'em back. The way it does it is skd-specific and this interface encapsulates it.
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jetbrains.python.sdk
|
||||
|
||||
import com.intellij.openapi.projectRoots.Sdk
|
||||
import com.intellij.openapi.projectRoots.impl.ProjectJdkImpl
|
||||
import com.intellij.openapi.util.NullableComputable
|
||||
|
||||
@java.lang.Deprecated(forRemoval = true)
|
||||
@Deprecated("Migrate to `com.jetbrains.python.newProjectWizard`, it doesn't need this class", level = DeprecationLevel.WARNING)
|
||||
class PyLazySdk(name: String, private val create: NullableComputable<Sdk>) : ProjectJdkImpl(name, PythonSdkType.getInstance(), "", null) {
|
||||
fun create(): Sdk? = create.compute()
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.jetbrains.python.sdk.add.v1
|
||||
|
||||
import com.intellij.execution.target.FullPathOnTarget
|
||||
@@ -172,8 +172,6 @@ class PyAddCondaPanelModel(val targetConfiguration: TargetEnvironmentConfigurati
|
||||
|
||||
private fun condaPathIsValid(path: FullPathOnTarget): Boolean = path.matches(condaPathRegex)
|
||||
|
||||
fun isCondaPathValid() = condaPathIsValid(condaPathTextBoxRwProp.get())
|
||||
|
||||
|
||||
/**
|
||||
* Detects condas in well-known locations so user doesn't have to provide conda path
|
||||
@@ -211,15 +209,6 @@ class PyAddCondaPanelModel(val targetConfiguration: TargetEnvironmentConfigurati
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method ignores the error if condaEnvs are not loaded yet
|
||||
* @return either null (if no error in name validation) or localized error string
|
||||
*/
|
||||
fun getEnvIdentitiesNameValidationError(): @Nls String? {
|
||||
val envIdentities = getEnvIdentities().getOrElse { return null }
|
||||
return validateEnvIdentitiesName(envIdentities)
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns envIdentities from loaded envs
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user