From 0adcf3598f8c70bb3f085272295557f306f444fc Mon Sep 17 00:00:00 2001 From: Serhat Yenican <104850907+serhat-yenican-sonarsource@users.noreply.github.com> Date: Fri, 8 Nov 2024 10:03:35 +0100 Subject: [PATCH] CODEFIX-188 Enable Ai CodeFix for new projects if all projects enabled option is selected (#12216) --- .../common/component/ComponentUpdaterIT.java | 29 +++++++++++++++++++ .../common/component/ComponentUpdater.java | 15 ++++++++-- 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/server/sonar-webserver-common/src/it/java/org/sonar/server/common/component/ComponentUpdaterIT.java b/server/sonar-webserver-common/src/it/java/org/sonar/server/common/component/ComponentUpdaterIT.java index 03c0dea0122..f7d25a3ff1e 100644 --- a/server/sonar-webserver-common/src/it/java/org/sonar/server/common/component/ComponentUpdaterIT.java +++ b/server/sonar-webserver-common/src/it/java/org/sonar/server/common/component/ComponentUpdaterIT.java @@ -26,6 +26,11 @@ import org.apache.commons.lang3.StringUtils; import org.junit.Before; import org.junit.Rule; import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.NullAndEmptySource; +import org.junit.jupiter.params.provider.NullSource; +import org.junit.jupiter.params.provider.ValueSource; import org.sonar.db.component.ComponentQualifiers; import org.sonar.db.component.ComponentScopes; import org.sonar.api.utils.System2; @@ -37,6 +42,7 @@ import org.sonar.db.audit.AuditPersister; import org.sonar.db.component.BranchDto; import org.sonar.db.component.BranchType; import org.sonar.db.component.ComponentDto; +import org.sonar.db.property.PropertyDto; import org.sonar.server.component.ComponentTypesRule; import org.sonar.db.project.CreationMethod; import org.sonar.db.project.ProjectDto; @@ -76,6 +82,8 @@ import static org.sonar.db.component.ComponentQualifiers.APP; import static org.sonar.db.component.ComponentQualifiers.PROJECT; import static org.sonar.db.component.ComponentQualifiers.VIEW; import static org.sonar.db.component.BranchDto.DEFAULT_MAIN_BRANCH_NAME; +import static org.sonar.server.common.component.ComponentUpdater.ENABLED_FOR_ALL_PROJECTS; +import static org.sonar.server.common.component.ComponentUpdater.SUGGESTION_FEATURE_ENABLED_PROPERTY; public class ComponentUpdaterIT { @@ -530,9 +538,30 @@ public class ComponentUpdaterIT { .creationMethod(CreationMethod.LOCAL_API) .build(); ProjectDto projectDto = underTest.create(db.getSession(), creationParameters).projectDto(); + assertThat(projectDto.getAiCodeFixEnabled()).isFalse(); assertThat(projectDto.getCreationMethod()).isEqualTo(CreationMethod.LOCAL_API); } + @ParameterizedTest + @NullSource + @ValueSource(strings = {"DISABLED", "ENABLED_FOR_ALL_PROJECTS", "ENABLED_FOR_SOME_PROJECTS"}) + void create_whenAiCodeFixEnabledForAllProjects_setAiCodeFixEnabled(String enablementOption) { + Optional.ofNullable(enablementOption).ifPresent(s -> { + db.properties() + .insertProperty(SUGGESTION_FEATURE_ENABLED_PROPERTY, enablementOption, null); + }); + + ComponentCreationParameters creationParameters = ComponentCreationParameters.builder() + .newComponent(DEFAULT_COMPONENT) + .creationMethod(CreationMethod.LOCAL_API) + .mainBranchName("main") + .build(); + + ProjectDto projectDto = underTest.create(db.getSession(), creationParameters).projectDto(); + assertThat(projectDto.getAiCodeFixEnabled()).isEqualTo(ENABLED_FOR_ALL_PROJECTS.equals(enablementOption)); + db.getDbClient().purgeDao().deleteProject(db.getSession(), projectDto.getUuid(), projectDto.getQualifier(), projectDto.getName(), projectDto.getKey()); + } + @Test public void create_whenCreationMethodIsAlmImportBrowser_persistsIt() { ComponentCreationParameters creationParameters = ComponentCreationParameters.builder() diff --git a/server/sonar-webserver-common/src/main/java/org/sonar/server/common/component/ComponentUpdater.java b/server/sonar-webserver-common/src/main/java/org/sonar/server/common/component/ComponentUpdater.java index 13d8d703b29..2c74aa544c7 100644 --- a/server/sonar-webserver-common/src/main/java/org/sonar/server/common/component/ComponentUpdater.java +++ b/server/sonar-webserver-common/src/main/java/org/sonar/server/common/component/ComponentUpdater.java @@ -40,6 +40,7 @@ import org.sonar.db.portfolio.PortfolioDto; import org.sonar.db.portfolio.PortfolioDto.SelectionMode; import org.sonar.db.project.CreationMethod; import org.sonar.db.project.ProjectDto; +import org.sonar.db.property.PropertyDto; import org.sonar.db.user.UserDto; import org.sonar.server.common.permission.Operation; import org.sonar.server.common.permission.PermissionTemplateService; @@ -61,6 +62,8 @@ import static org.sonar.server.exceptions.BadRequestException.throwBadRequestExc public class ComponentUpdater { + static final String SUGGESTION_FEATURE_ENABLED_PROPERTY = "sonar.ai.suggestions.enabled"; + static final String ENABLED_FOR_ALL_PROJECTS = "ENABLED_FOR_ALL_PROJECTS"; private static final Set PROJ_APP_QUALIFIERS = Set.of(ComponentQualifiers.PROJECT, ComponentQualifiers.APP); private static final String KEY_ALREADY_EXISTS_ERROR = "Could not create %s with key: \"%s\". A similar key already exists: \"%s\""; private static final String MALFORMED_KEY_ERROR = "Malformed key for %s: '%s'. %s."; @@ -128,7 +131,8 @@ public class ComponentUpdater { PortfolioDto portfolioDto = null; if (isProjectOrApp(componentDto)) { - projectDto = toProjectDto(componentDto, now, componentCreationParameters.creationMethod()); + var isAiCodeFixEnabled = isAiCodeFixEnabledForAllProjects(); + projectDto = toProjectDto(componentDto, now, componentCreationParameters.creationMethod(), isAiCodeFixEnabled); dbClient.projectDao().insert(dbSession, projectDto); addToFavourites(dbSession, projectDto, componentCreationParameters.userUuid(), componentCreationParameters.userLogin()); mainBranch = createMainBranch(dbSession, componentDto.uuid(), projectDto.getUuid(), componentCreationParameters.mainBranchName()); @@ -148,6 +152,12 @@ public class ComponentUpdater { return new ComponentCreationData(componentDto, portfolioDto, mainBranch, projectDto); } + private boolean isAiCodeFixEnabledForAllProjects() { + return Optional.ofNullable(dbClient.propertiesDao().selectGlobalProperty(SUGGESTION_FEATURE_ENABLED_PROPERTY)) + .map(PropertyDto::getValue) + .stream().anyMatch(ENABLED_FOR_ALL_PROJECTS::equals); + } + private void applyPublicPermissionsForCreator(DbSession dbSession, ProjectDto projectDto, @Nullable String userUuid) { if (userUuid != null) { UserDto userDto = dbClient.userDao().selectByUuid(dbSession, userUuid); @@ -205,7 +215,7 @@ public class ComponentUpdater { return component; } - private ProjectDto toProjectDto(ComponentDto component, long now, CreationMethod creationMethod) { + private ProjectDto toProjectDto(ComponentDto component, long now, CreationMethod creationMethod, boolean isAiCodeFixEnabled) { return new ProjectDto() .setUuid(uuidFactory.create()) .setKey(component.getKey()) @@ -214,6 +224,7 @@ public class ComponentUpdater { .setPrivate(component.isPrivate()) .setDescription(component.description()) .setCreationMethod(creationMethod) + .setAiCodeFixEnabled(isAiCodeFixEnabled) .setUpdatedAt(now) .setCreatedAt(now); } -- 2.39.5