mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Fix user's project name discarded by external system
This commit is contained in:
+25
-1
@@ -1,4 +1,7 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
//
|
||||
// Modified by Aleksandr Eliseev at 2026 as part of the OpenIDE project(https://openide.ru).
|
||||
// Any modifications are available on the same license terms as the original source code.
|
||||
|
||||
package com.intellij.openapi.roots.ui.configuration;
|
||||
|
||||
@@ -28,8 +31,10 @@ import com.intellij.project.ProjectKt;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import ru.openide.project.ProjectNameCustomizationState;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
@@ -149,7 +154,15 @@ public class ProjectConfigurable extends ProjectStructureElementConfigurable<Pro
|
||||
myUi.applyProjectJdkConfigurable();
|
||||
|
||||
if (myProject instanceof ProjectEx) {
|
||||
((ProjectEx)myProject).setProjectName(getProjectName());
|
||||
ProjectEx projectEx = (ProjectEx)myProject;
|
||||
String newName = getProjectName();
|
||||
projectEx.setProjectName(newName);
|
||||
// Record whether the user explicitly customized the name.
|
||||
// An external system (e.g. Gradle) sync must not overwrite a customized name;
|
||||
// resetting it to the directory name clears the flag so the sync can drive it again.
|
||||
ProjectNameCustomizationState.Companion.getInstance(myProject).setUserCustomizedName(
|
||||
isCustomProjectName(myProject, newName)
|
||||
);
|
||||
if (myDetailsComponent != null) myDetailsComponent.setText(getBannerSlogan());
|
||||
}
|
||||
});
|
||||
@@ -211,6 +224,17 @@ public class ProjectConfigurable extends ProjectStructureElementConfigurable<Pro
|
||||
return myProject.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the given name is a user customization, i.e. it differs from the project's
|
||||
* directory name (the default project name). Used to decide whether an external system sync may
|
||||
* override the project name.
|
||||
*/
|
||||
private static boolean isCustomProjectName(@NotNull Project project, @NotNull String name) {
|
||||
String basePath = project.getBasePath();
|
||||
if (basePath == null) return true;
|
||||
return !name.equals(new File(basePath).getName());
|
||||
}
|
||||
|
||||
private @Nullable String getOriginalCompilerOutputUrl() {
|
||||
final CompilerProjectExtension extension = CompilerProjectExtension.getInstance(myProject);
|
||||
return extension != null ? extension.getCompilerOutputUrl() : null;
|
||||
|
||||
+11
-2
@@ -1,4 +1,7 @@
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
//
|
||||
// Modified by Aleksandr Eliseev at 2026 as part of the OpenIDE project(https://openide.ru).
|
||||
// Any modifications are available on the same license terms as the original source code.
|
||||
package com.intellij.openapi.externalSystem.service.project.manage;
|
||||
|
||||
import com.intellij.openapi.externalSystem.model.DataNode;
|
||||
@@ -10,6 +13,7 @@ import com.intellij.openapi.externalSystem.service.project.IdeModifiableModelsPr
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemConstants;
|
||||
import com.intellij.openapi.externalSystem.util.Order;
|
||||
import ru.openide.project.ProjectNameCustomizationState;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.project.ex.ProjectEx;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
@@ -45,9 +49,14 @@ public final class ProjectDataServiceImpl extends AbstractProjectDataService<Pro
|
||||
if (!ExternalSystemApiUtil.isOneToOneMapping(project, node.getData(), modelsProvider.getModules())) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!project.getName().equals(projectData.getInternalName())) {
|
||||
renameProject(projectData.getInternalName(), projectData.getOwner(), project);
|
||||
// Don't overwrite a project name the user has explicitly customized (via File | Project
|
||||
// Structure or Refactor | Rename) when the external (e.g. Gradle) root project name differs.
|
||||
// A Gradle-driven rename (no user customization) still propagates, including across multiple syncs.
|
||||
if (!ProjectNameCustomizationState.Companion.getInstance(project).getUserCustomizedName()) {
|
||||
renameProject(projectData.getInternalName(), projectData.getOwner(), project);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+14
-1
@@ -1,4 +1,7 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
//
|
||||
// Modified by Aleksandr Eliseev at 2026 as part of the OpenIDE project(https://openide.ru).
|
||||
// Any modifications are available on the same license terms as the original source code.
|
||||
package com.intellij.platform.renameProject;
|
||||
|
||||
import com.intellij.ide.IdeBundle;
|
||||
@@ -24,6 +27,9 @@ import com.intellij.refactoring.RefactoringBundle;
|
||||
import com.intellij.refactoring.rename.RenameHandler;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import ru.openide.project.ProjectNameCustomizationState;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public final class RenameProjectHandler implements RenameHandler, TitledHandler {
|
||||
private static final Logger LOG = Logger.getInstance(RenameProjectHandler.class);
|
||||
@@ -84,6 +90,13 @@ public final class RenameProjectHandler implements RenameHandler, TitledHandler
|
||||
public static boolean renameProject(@NotNull ProjectEx project, @Nullable Module module, String newName){
|
||||
if (shouldRenameProject(project, module, newName)) {
|
||||
project.setProjectName(newName);
|
||||
// The user explicitly renamed the project from Refactor | Rename. Record it as a
|
||||
// customization so an external system (e.g. Gradle) sync doesn't overwrite it; resetting the
|
||||
// name to the directory name clears it and lets the sync drive the name again.
|
||||
String basePath = project.getBasePath();
|
||||
ProjectNameCustomizationState.Companion.getInstance(project).setUserCustomizedName(
|
||||
basePath == null || !newName.equals(new File(basePath).getName())
|
||||
);
|
||||
project.save();
|
||||
}
|
||||
|
||||
@@ -121,4 +134,4 @@ public final class RenameProjectHandler implements RenameHandler, TitledHandler
|
||||
|
||||
return module == PrimaryModuleManager.findPrimaryModule(project);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
// OpenIDE Project
|
||||
// Copyright (C) 2026 “Open Development Platform” Ltd. (https://openide.ru)
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License version 3 or later as published by the Free Software Foundation.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see http://www.gnu.org/licenses/.
|
||||
package ru.openide.project
|
||||
|
||||
import com.intellij.openapi.components.PersistentStateComponent
|
||||
import com.intellij.openapi.components.Service
|
||||
import com.intellij.openapi.components.State
|
||||
import com.intellij.openapi.components.Storage
|
||||
import com.intellij.openapi.components.StoragePathMacros
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.util.xmlb.XmlSerializerUtil
|
||||
|
||||
/**
|
||||
* Tracks whether the user has explicitly customized the IDE project name (via File | Project
|
||||
* Structure or Refactor | Rename on the project), as opposed to the name being derived from the
|
||||
* project directory or set by an external system (e.g. Gradle) sync.
|
||||
*
|
||||
* An external system sync that wants to rename the project to match the build model must respect
|
||||
* this flag: once the user has chosen a custom name, the sync must not overwrite it. The flag is
|
||||
* cleared again when the user resets the name to the project directory name, so an external system
|
||||
* can resume driving the name.
|
||||
*/
|
||||
@Service(Service.Level.PROJECT)
|
||||
@State(name = "ProjectNameCustomizationState", storages = [Storage(StoragePathMacros.WORKSPACE_FILE)])
|
||||
class ProjectNameCustomizationState : PersistentStateComponent<ProjectNameCustomizationState> {
|
||||
|
||||
companion object {
|
||||
fun getInstance(project: Project): ProjectNameCustomizationState =
|
||||
project.getService(ProjectNameCustomizationState::class.java)
|
||||
}
|
||||
|
||||
var userCustomizedName: Boolean = false
|
||||
|
||||
override fun getState(): ProjectNameCustomizationState = this
|
||||
|
||||
override fun loadState(state: ProjectNameCustomizationState) {
|
||||
XmlSerializerUtil.copyBean(state, this)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user