@@ -26,12 +26,19 @@ import org.sonar.api.batch.fs.InputFile; | |||
import org.sonar.api.database.DatabaseSession; | |||
import org.sonar.api.database.model.ResourceModel; | |||
import org.sonar.api.database.model.Snapshot; | |||
import org.sonar.api.resources.*; | |||
import org.sonar.api.resources.File; | |||
import org.sonar.api.resources.Library; | |||
import org.sonar.api.resources.Project; | |||
import org.sonar.api.resources.Qualifiers; | |||
import org.sonar.api.resources.Resource; | |||
import org.sonar.api.resources.ResourceUtils; | |||
import org.sonar.api.resources.Scopes; | |||
import org.sonar.api.security.ResourcePermissions; | |||
import org.sonar.api.utils.SonarException; | |||
import javax.persistence.NonUniqueResultException; | |||
import javax.persistence.Query; | |||
import java.util.Date; | |||
import java.util.Iterator; | |||
import java.util.List; | |||
@@ -310,15 +317,6 @@ public final class DefaultResourcePersister implements ResourcePersister { | |||
model.setPath(resource.getPath()); | |||
} | |||
if (!ResourceUtils.isLibrary(resource)) { | |||
// SONAR-4245 | |||
if (Scopes.PROJECT.equals(resource.getScope()) && | |||
Qualifiers.MODULE.equals(resource.getQualifier()) | |||
&& Qualifiers.PROJECT.equals(model.getQualifier())) { | |||
throw new SonarException( | |||
String.format("The project '%s' is already defined in SonarQube but not as a module of project '%s'. " | |||
+ "If you really want to stop directly analysing project '%s', please first delete it from SonarQube and then relaunch the analysis of project '%s'.", | |||
resource.getKey(), resource.getParent().getKey(), resource.getKey(), resource.getParent().getKey())); | |||
} | |||
model.setScope(resource.getScope()); | |||
model.setQualifier(resource.getQualifier()); | |||
} |
@@ -80,16 +80,32 @@ public class ProjectReactorValidator { | |||
private void validateModule(ProjectDefinition moduleDef, List<String> validationMessages, @Nullable String branch, String rootProjectKey) { | |||
if (!ComponentKeys.isValidModuleKey(moduleDef.getKey())) { | |||
validationMessages.add(String.format("\"%s\" is not a valid project or module key", moduleDef.getKey())); | |||
} else if (moduleDef.getParent() != null) { | |||
} else if (isSubProject(moduleDef)) { | |||
// SONAR-4692 Validate root project is the same than previous analysis to avoid module with same key in different projects | |||
String key = ComponentKeys.createKey(moduleDef.getKey(), branch); | |||
ResourceDto root = resourceDao.getRootProjectByComponentKey(key); | |||
if (root != null && !rootProjectKey.equals(root.getKey())) { | |||
throw new SonarException(String.format("Module \"%s\" is already part of project \"%s\"", moduleDef.getKey(), root.getKey())); | |||
String moduleKey = ComponentKeys.createKey(moduleDef.getKey(), branch); | |||
ResourceDto rootInDB = resourceDao.getRootProjectByComponentKey(moduleKey); | |||
if (rootInDB == null) { | |||
// This is a new module so OK | |||
return; | |||
} | |||
if (rootInDB.getKey().equals(moduleKey)) { | |||
// SONAR-4245 current subproject is actually a root project in SQ DB | |||
throw new SonarException( | |||
String.format("The project '%s' is already defined in SonarQube but not as a module of project '%s'. " | |||
+ "If you really want to stop directly analysing project '%s', please first delete it from SonarQube and then relaunch the analysis of project '%s'.", | |||
moduleKey, rootProjectKey, moduleKey, rootProjectKey)); | |||
} | |||
if (!rootProjectKey.equals(rootInDB.getKey())) { | |||
// SONAR-4692 current subproject is already a subproject in another project | |||
throw new SonarException(String.format("Module \"%s\" is already part of project \"%s\"", moduleDef.getKey(), rootInDB.getKey())); | |||
} | |||
} | |||
} | |||
private boolean isSubProject(ProjectDefinition moduleDef) { | |||
return moduleDef.getParent() != null; | |||
} | |||
private void validateBranch(List<String> validationMessages, @Nullable String branch) { | |||
if (StringUtils.isNotEmpty(branch) && !ComponentKeys.isValidBranch(branch)) { | |||
validationMessages.add(String.format("\"%s\" is not a valid branch name", branch)); |
@@ -30,7 +30,6 @@ import org.sonar.api.resources.File; | |||
import org.sonar.api.resources.Library; | |||
import org.sonar.api.resources.Project; | |||
import org.sonar.api.security.ResourcePermissions; | |||
import org.sonar.api.utils.SonarException; | |||
import org.sonar.jpa.test.AbstractDbUnitTestCase; | |||
import java.text.ParseException; | |||
@@ -122,22 +121,6 @@ public class DefaultResourcePersisterTest extends AbstractDbUnitTestCase { | |||
checkTables("shouldSaveNewMultiModulesProject", new String[] {"build_date", "created_at"}, "projects", "snapshots"); | |||
} | |||
// SONAR-4245 | |||
@Test | |||
public void shouldFailWhenTryingToConvertProjectIntoModule() { | |||
setupData("shared"); | |||
ResourcePersister persister = new DefaultResourcePersister(getSession(), mock(ResourcePermissions.class), snapshotCache, resourceCache); | |||
existingProject.setParent(multiModuleProject); | |||
persister.saveProject(multiModuleProject, null); | |||
thrown.expect(SonarException.class); | |||
thrown.expectMessage("The project 'my:key' is already defined in SonarQube but not as a module of project 'root'. " | |||
+ "If you really want to stop directly analysing project 'my:key', please first delete it from SonarQube and then relaunch the analysis of project 'root'."); | |||
persister.saveProject(existingProject, multiModuleProject); | |||
} | |||
@Test | |||
public void shouldSaveNewDirectory() { | |||
setupData("shared"); |
@@ -112,6 +112,27 @@ public class ProjectReactorValidatorTest { | |||
validator.validate(reactor); | |||
} | |||
// SONAR-4245 | |||
@Test | |||
public void shouldFailWhenTryingToConvertProjectIntoModule() { | |||
String rootProjectKey = "project-key"; | |||
String moduleKey = "module-key"; | |||
ResourceDto rootResource = mock(ResourceDto.class); | |||
when(rootResource.getKey()).thenReturn(moduleKey); | |||
when(resourceDao.getRootProjectByComponentKey(moduleKey)).thenReturn(rootResource); | |||
ProjectReactor reactor = createProjectReactor(rootProjectKey); | |||
reactor.getRoot().addSubProject(ProjectDefinition.create().setProperty(CoreProperties.PROJECT_KEY_PROPERTY, moduleKey)); | |||
thrown.expect(SonarException.class); | |||
thrown.expectMessage("The project 'module-key' is already defined in SonarQube but not as a module of project 'project-key'. " | |||
+ "If you really want to stop directly analysing project 'module-key', please first delete it from SonarQube and then relaunch the analysis of project 'project-key'."); | |||
validator.validate(reactor); | |||
} | |||
@Test | |||
public void not_fail_with_valid_key() { | |||
validator.validate(createProjectReactor("foo")); |