+ 25 // level 1
+ 49 // content of DaoModule
+ 3 // content of EsSearchModule
- + 61 // content of CorePropertyDefinitions
+ + 63 // content of CorePropertyDefinitions
+ 1 // StopFlagContainer
);
assertThat(
"perm_tpl_characteristics",
"plugins",
"projects",
+ "project_branches",
"project_links",
"project_measures",
"project_qprofiles",
- "project_branches",
"properties",
"qprofile_changes",
"quality_gates",
"BRANCH_TYPE" VARCHAR(5),
"MERGE_BRANCH_UUID" VARCHAR(50),
"PULL_REQUEST_TITLE" VARCHAR(4000),
- "CREATED_AT" BIGINT NOT NULL
+ "CREATED_AT" BIGINT NOT NULL,
+ "UPDATED_AT" BIGINT NOT NULL
);
CREATE UNIQUE INDEX "PK_PROJECT_BRANCHES" ON "PROJECT_BRANCHES" ("UUID");
CREATE UNIQUE INDEX "PROJECT_BRANCHES_KEE" ON "PROJECT_BRANCHES" ("PROJECT_UUID", "KEE_TYPE", "KEE");
import org.sonar.db.ce.CeScannerContextDao;
import org.sonar.db.ce.CeTaskCharacteristicDao;
import org.sonar.db.ce.CeTaskInputDao;
+import org.sonar.db.component.BranchDao;
import org.sonar.db.component.ComponentDao;
import org.sonar.db.component.ComponentKeyUpdaterDao;
import org.sonar.db.component.ComponentLinkDao;
private final Database database;
private final MyBatis myBatis;
private final DBSessions dbSessions;
+
private final SchemaMigrationDao schemaMigrationDao;
private final AuthorizationDao authorizationDao;
private final OrganizationDao organizationDao;
private final DefaultQProfileDao defaultQProfileDao;
private final EsQueueDao esQueueDao;
private final PluginDao pluginDao;
+ private final BranchDao branchDao;
public DbClient(Database database, MyBatis myBatis, DBSessions dbSessions, Dao... daos) {
this.database = database;
defaultQProfileDao = getDao(map, DefaultQProfileDao.class);
esQueueDao = getDao(map, EsQueueDao.class);
pluginDao = getDao(map, PluginDao.class);
+ branchDao = getDao(map, BranchDao.class);
}
public DbSession openSession(boolean batch) {
return pluginDao;
}
+ public BranchDao branchDao() {
+ return branchDao;
+ }
+
protected <K extends Dao> K getDao(Map<Class, Dao> map, Class<K> clazz) {
return (K) map.get(clazz);
}
*/
package org.sonar.db.component;
+import java.util.Collection;
+import java.util.Optional;
+import javax.annotation.Nullable;
import org.sonar.api.utils.System2;
import org.sonar.db.Dao;
import org.sonar.db.DbSession;
mapper(dbSession).insert(dto, system2.now());
}
+ public void upsert(DbSession dbSession, BranchDto dto) {
+ BranchMapper mapper = mapper(dbSession);
+ long now = system2.now();
+ if (mapper.update(dto, now) == 0) {
+ mapper.insert(dto, now);
+ }
+ }
+
+ public Optional<BranchDto> selectByKey(DbSession dbSession, String projectUuid, BranchKeyType keyType, @Nullable String key) {
+ String keyInDb = BranchDto.convertKeyToDb(key);
+ return Optional.ofNullable(mapper(dbSession).selectByKey(projectUuid, keyType, keyInDb));
+ }
+
+ public Collection<BranchDto> selectByComponent(DbSession dbSession, ComponentDto component) {
+ String projectUuid = component.getMainBranchProjectUuid();
+ if (projectUuid == null) {
+ projectUuid = component.projectUuid();
+ }
+ return mapper(dbSession).selectByProjectUuid(projectUuid);
+ }
+
private static BranchMapper mapper(DbSession dbSession) {
return dbSession.getMapper(BranchMapper.class);
}
*/
package org.sonar.db.component;
+import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import static com.google.common.base.Preconditions.checkArgument;
+import static org.apache.commons.lang.StringUtils.repeat;
public class BranchDto {
+ /**
+ * Maximum length of column "kee"
+ */
+ public static final int KEE_MAX_LENGTH = 255;
+
/**
* Value of {@link #kee} when the name of main branch is not known.
* Used only if {@link #keeType} is {@link BranchKeyType#BRANCH}.
- * It does not conflict with names of real branches because the character ':'
+ * It does not conflict with names of real branches because the term ':BRANCH:'
* is not accepted.
*/
- public static final String DEFAULT_KEY_OF_MAIN_BRANCH = ":main:";
+ public static final String NULL_KEY = repeat("_", KEE_MAX_LENGTH);
/**
* Branch UUID is the projects.uuid that reference projects, branches or pull requests
/**
* If {@link #keeType} is {@link BranchKeyType#BRANCH}, then name of branch, for example
- * "feature/foo". Can be {@link #DEFAULT_KEY_OF_MAIN_BRANCH} is the name is not known.
+ * "feature/foo". Can be {@link #NULL_KEY} is the name is not known.
*
* If {@link #keeType} is {@link BranchKeyType#PR}, then id of the pull request, for
* example "1204".
this.projectUuid = s;
}
+ public boolean isMain() {
+ return projectUuid.equals(uuid);
+ }
+
public BranchKeyType getKeeType() {
return keeType;
}
this.keeType = t;
}
- public String getKee() {
+ /**
+ * This is the getter used by MyBatis mapper. It does
+ * not handle the special value used to map null field.
+ */
+ private String getKee() {
return kee;
}
- public void setKee(String s) {
- checkArgument(s.length() <= 255, "Maximum length of branch name or pull request id is 255: %s", s);
+ @CheckForNull
+ public String getKey() {
+ return convertKeyFromDb(getKee());
+ }
+
+ /**
+ * This is the setter used by MyBatis mapper. It does
+ * not handle the special value used to map null field.
+ */
+ private void setKee(String s) {
this.kee = s;
}
+ public void setKey(@Nullable String s) {
+ checkArgument(s == null || s.length() <= KEE_MAX_LENGTH, "Maximum length of branch name or pull request id is %s: %s", KEE_MAX_LENGTH, s);
+ checkArgument(!NULL_KEY.equals(s), "Branch name is not allowed: %s", s);
+ setKee(convertKeyToDb(s));
+ }
+
@Nullable
public BranchType getBranchType() {
return branchType;
public String toString() {
StringBuilder sb = new StringBuilder("BranchDto{");
sb.append("uuid='").append(uuid).append('\'');
+ sb.append(", projectUuid='").append(projectUuid).append('\'');
+ sb.append(", keeType=").append(keeType);
+ sb.append(", kee='").append(kee).append('\'');
+ sb.append(", branchType=").append(branchType);
sb.append(", mergeBranchUuid='").append(mergeBranchUuid).append('\'');
sb.append(", pullRequestTitle='").append(pullRequestTitle).append('\'');
sb.append('}');
return sb.toString();
}
+
+ static String convertKeyToDb(@Nullable String s) {
+ return s == null ? NULL_KEY : s;
+ }
+
+ @CheckForNull
+ static String convertKeyFromDb(String s) {
+ return NULL_KEY.equals(s) ? null : s;
+ }
}
*/
package org.sonar.db.component;
+import java.util.Collection;
import org.apache.ibatis.annotations.Param;
public interface BranchMapper {
void insert(@Param("dto") BranchDto dto, @Param("now") long now);
+ int update(@Param("dto") BranchDto dto, @Param("now") long now);
+
+ BranchDto selectByKey(@Param("projectUuid") String projectUuid,
+ @Param("keyType") BranchKeyType keyType, @Param("key") String key);
+
+ Collection<BranchDto> selectByProjectUuid(@Param("projectUuid") String projectUuid);
}
return this;
}
- public String getKey() {
- return getDbKey();
- }
public String scope() {
return scope;
.append("private", isPrivate)
.toString();
}
+
+ public ComponentDto copy() {
+ ComponentDto copy = new ComponentDto();
+ copy.projectUuid = projectUuid;
+ copy.id = id;
+ copy.organizationUuid = organizationUuid;
+ copy.kee = kee;
+ copy.uuid = uuid;
+ copy.uuidPath = uuidPath;
+ copy.projectUuid = projectUuid;
+ copy.rootUuid = rootUuid;
+ copy.mainBranchProjectUuid = mainBranchProjectUuid;
+ copy.moduleUuid = moduleUuid;
+ copy.moduleUuidPath = moduleUuidPath;
+ copy.copyComponentUuid = copyComponentUuid;
+ copy.developerUuid = developerUuid;
+ copy.scope = scope;
+ copy.qualifier = qualifier;
+ copy.path = path;
+ copy.deprecatedKey = deprecatedKey;
+ copy.name = name;
+ copy.longName = longName;
+ copy.language = language;
+ copy.description = description;
+ copy.tags = tags;
+ copy.enabled = enabled;
+ copy.isPrivate = isPrivate;
+ copy.createdAt = createdAt;
+ return copy;
+ }
}
}
public List<PropertyDto> selectGlobalPropertiesByKeys(DbSession session, Set<String> keys) {
- return selectByKeys(session, keys, null);
- }
-
- public List<PropertyDto> selectPropertiesByKeysAndComponentId(DbSession session, Set<String> keys, long componentId) {
- return selectByKeys(session, keys, componentId);
+ return executeLargeInputs(keys, partitionKeys -> getMapper(session).selectByKeys(partitionKeys));
}
public List<PropertyDto> selectPropertiesByKeysAndComponentIds(DbSession session, Set<String> keys, Set<Long> componentIds) {
return executeLargeInputs(componentIds, getMapper(session)::selectByComponentIds);
}
- private List<PropertyDto> selectByKeys(DbSession session, Set<String> keys, @Nullable Long componentId) {
- return executeLargeInputs(keys, partitionKeys -> getMapper(session).selectByKeys(partitionKeys, componentId));
- }
-
public List<PropertyDto> selectGlobalPropertiesByKeyQuery(DbSession session, String keyQuery) {
return getMapper(session).selectGlobalPropertiesByKeyQuery(buildLikeValue(keyQuery, WildcardPosition.BEFORE_AND_AFTER));
}
PropertyDto selectByKey(PropertyDto key);
- List<PropertyDto> selectByKeys(@Param("keys") List<String> keys, @Nullable @Param("componentId") Long componentId);
+ List<PropertyDto> selectByKeys(@Param("keys") List<String> keys);
List<PropertyDto> selectByKeysAndComponentIds(@Param("keys") List<String> keys, @Param("componentIds") List<Long> componentIds);
branch_type,
merge_branch_uuid,
pull_request_title,
- created_at
+ created_at,
+ updated_at
) values (
#{dto.uuid, jdbcType=VARCHAR},
#{dto.projectUuid, jdbcType=VARCHAR},
#{dto.branchType, jdbcType=VARCHAR},
#{dto.mergeBranchUuid, jdbcType=VARCHAR},
#{dto.pullRequestTitle, jdbcType=VARCHAR},
+ #{now, jdbcType=BIGINT},
#{now, jdbcType=BIGINT}
)
</insert>
+ <update id="update" parameterType="map" useGeneratedKeys="false">
+ update project_branches
+ set
+ merge_branch_uuid = #{dto.mergeBranchUuid, jdbcType=VARCHAR},
+ pull_request_title = #{dto.pullRequestTitle, jdbcType=VARCHAR},
+ updated_at = #{now, jdbcType=BIGINT}
+ where
+ uuid = #{dto.uuid, jdbcType=VARCHAR}
+ </update>
+
+ <select id="selectByKey" resultType="org.sonar.db.component.BranchDto">
+ select <include refid="columns" />
+ from project_branches pb
+ where
+ pb.project_uuid = #{projectUuid, jdbcType=VARCHAR} and
+ pb.kee_type = #{keyType, jdbcType=VARCHAR} and
+ pb.kee = #{key, jdbcType=VARCHAR}
+ </select>
+
+ <select id="selectByProjectUuid" parameterType="string" resultType="org.sonar.db.component.BranchDto">
+ select <include refid="columns" />
+ from project_branches pb
+ where
+ pb.project_uuid = #{projectUuid, jdbcType=VARCHAR}
+ </select>
</mapper>
<foreach collection="keys" open="(" close=")" item="key" separator=",">
#{key}
</foreach>
- <if test="componentId == null">
- and p.resource_id is null
- </if>
- <if test="componentId != null">
- and p.resource_id=#{componentId}
- </if>
+ and p.resource_id is null
and p.user_id is null
order by p.id
</select>
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.db.component;
+
+import java.util.Map;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.utils.System2;
+import org.sonar.api.utils.internal.TestSystem2;
+import org.sonar.db.DbSession;
+import org.sonar.db.DbTester;
+
+import static org.apache.commons.lang.StringUtils.repeat;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.entry;
+
+public class BranchDaoTest {
+
+ private static final long NOW = 1_000L;
+ private static final String SELECT_FROM = "select project_uuid as \"projectUuid\", uuid as \"uuid\", branch_type as \"branchType\", kee_type as \"keeType\", " +
+ "kee as \"kee\", merge_branch_uuid as \"mergeBranchUuid\", pull_request_title as \"pullRequestTitle\", created_at as \"createdAt\", updated_at as \"updatedAt\" " +
+ "from project_branches ";
+ private System2 system2 = new TestSystem2().setNow(NOW);
+
+ @Rule
+ public DbTester db = DbTester.create(system2);
+
+ private DbSession dbSession = db.getSession();
+ private BranchDao underTest = new BranchDao(system2);
+
+ @Test
+ public void insert_branch_with_only_nonnull_fields() {
+ BranchDto dto = new BranchDto();
+ dto.setProjectUuid("U1");
+ dto.setUuid("U2");
+ dto.setBranchType(BranchType.SHORT);
+ dto.setKeeType(BranchKeyType.BRANCH);
+ dto.setKey("feature/foo");
+
+ underTest.insert(dbSession, dto);
+
+ Map<String, Object> map = db.selectFirst(dbSession, SELECT_FROM + " where uuid='" + dto.getUuid() + "'");
+ assertThat(map).contains(
+ entry("projectUuid", "U1"),
+ entry("uuid", "U2"),
+ entry("branchType", "SHORT"),
+ entry("keeType", "BRANCH"),
+ entry("kee", "feature/foo"),
+ entry("mergeBranchUuid", null),
+ entry("pullRequestTitle", null),
+ entry("createdAt", 1_000L),
+ entry("updatedAt", 1_000L)
+ );
+ }
+
+ @Test
+ public void insert_branch_with_all_fields_and_max_length_values() {
+ BranchDto dto = new BranchDto();
+ dto.setProjectUuid(repeat("a", 50));
+ dto.setUuid(repeat("b", 50));
+ dto.setBranchType(BranchType.SHORT);
+ dto.setKeeType(BranchKeyType.BRANCH);
+ dto.setKey(repeat("c", 255));
+ dto.setMergeBranchUuid(repeat("d", 50));
+ dto.setPullRequestTitle(repeat("e", 4_000));
+
+ underTest.insert(dbSession, dto);
+
+ Map<String, Object> map = db.selectFirst(dbSession, SELECT_FROM + " where uuid='" + dto.getUuid() + "'");
+ assertThat((String)map.get("projectUuid")).contains("a").isEqualTo(dto.getProjectUuid());
+ assertThat((String)map.get("uuid")).contains("b").isEqualTo(dto.getUuid());
+ assertThat((String)map.get("kee")).contains("c").isEqualTo(dto.getKey());
+ assertThat((String)map.get("mergeBranchUuid")).contains("d").isEqualTo(dto.getMergeBranchUuid());
+ assertThat((String)map.get("pullRequestTitle")).contains("e").isEqualTo(dto.getPullRequestTitle());
+ }
+
+ @Test
+ public void null_value_of_kee_column_is_converted_in_db() {
+ BranchDto dto = new BranchDto();
+ dto.setProjectUuid("u1");
+ dto.setUuid("u2");
+ dto.setKeeType(BranchKeyType.BRANCH);
+ dto.setKey(null);
+
+ underTest.insert(dbSession, dto);
+
+ Map<String, Object> map = db.selectFirst(dbSession, SELECT_FROM + " where uuid='" + dto.getUuid() + "'");
+ assertThat(map).contains(entry("kee", BranchDto.NULL_KEY));
+ BranchDto loaded = underTest.selectByKey(dbSession, dto.getProjectUuid(), dto.getKeeType(), null).get();
+ assertThat(loaded.getKey()).isNull();
+ }
+
+ @Test
+ public void upsert() {
+ BranchDto dto = new BranchDto();
+ dto.setProjectUuid("U1");
+ dto.setUuid("U2");
+ dto.setBranchType(BranchType.LONG);
+ dto.setKeeType(BranchKeyType.BRANCH);
+ dto.setKey("foo");
+ underTest.insert(dbSession, dto);
+
+ // the fields that can be updated
+ dto.setMergeBranchUuid("U3");
+ dto.setPullRequestTitle("theTitle");
+
+ // the fields that can't be updated. New values are ignored.
+ dto.setProjectUuid("ignored");
+ dto.setBranchType(BranchType.SHORT);
+ dto.setKeeType(BranchKeyType.PR);
+ underTest.upsert(dbSession, dto);
+
+ BranchDto loaded = underTest.selectByKey(dbSession, "U1", BranchKeyType.BRANCH, "foo").get();
+ assertThat(loaded.getMergeBranchUuid()).isEqualTo("U3");
+ assertThat(loaded.getPullRequestTitle()).isEqualTo("theTitle");
+ assertThat(loaded.getProjectUuid()).isEqualTo("U1");
+ assertThat(loaded.getBranchType()).isEqualTo(BranchType.LONG);
+ assertThat(loaded.getKeeType()).isEqualTo(BranchKeyType.BRANCH);
+ }
+
+ @Test
+ public void selectByKey() {
+ BranchDto mainBranch = new BranchDto();
+ mainBranch.setProjectUuid("U1");
+ mainBranch.setUuid("U1");
+ mainBranch.setBranchType(BranchType.LONG);
+ mainBranch.setKeeType(BranchKeyType.BRANCH);
+ mainBranch.setKey("master");
+ underTest.insert(dbSession, mainBranch);
+
+ BranchDto featureBranch = new BranchDto();
+ featureBranch.setProjectUuid("U1");
+ featureBranch.setUuid("U2");
+ featureBranch.setBranchType(BranchType.SHORT);
+ featureBranch.setKeeType(BranchKeyType.BRANCH);
+ featureBranch.setKey("feature/foo");
+ featureBranch.setMergeBranchUuid("U3");
+ underTest.insert(dbSession, featureBranch);
+
+ // select the feature branch
+ BranchDto loaded = underTest.selectByKey(dbSession, "U1", BranchKeyType.BRANCH, "feature/foo").get();
+ assertThat(loaded.getUuid()).isEqualTo(featureBranch.getUuid());
+ assertThat(loaded.getKey()).isEqualTo(featureBranch.getKey());
+ assertThat(loaded.getProjectUuid()).isEqualTo(featureBranch.getProjectUuid());
+ assertThat(loaded.getBranchType()).isEqualTo(featureBranch.getBranchType());
+ assertThat(loaded.getKeeType()).isEqualTo(featureBranch.getKeeType());
+ assertThat(loaded.getMergeBranchUuid()).isEqualTo(featureBranch.getMergeBranchUuid());
+ assertThat(loaded.getPullRequestTitle()).isEqualTo(featureBranch.getPullRequestTitle());
+
+ // select a pull request with same key than the feature branch
+ assertThat(underTest.selectByKey(dbSession, "U1", BranchKeyType.PR, "feature/foo")).isEmpty();
+
+ // select a branch on another project with same branch name
+ assertThat(underTest.selectByKey(dbSession, "U3", BranchKeyType.BRANCH, "feature/foo")).isEmpty();
+ }
+
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.db.component;
+
+import org.junit.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class BranchDtoTest {
+
+ private BranchDto underTest = new BranchDto();
+
+ @Test
+ public void isMain_is_true_if_branch_uuid_equals_project_uuid() {
+ underTest.setProjectUuid("U1");
+ underTest.setUuid("U1");
+
+ assertThat(underTest.isMain()).isTrue();
+ }
+
+ @Test
+ public void isMain_is_false_if_branch_uuid_does_not_equal_project_uuid() {
+ underTest.setProjectUuid("U1");
+ underTest.setUuid("U2");
+
+ assertThat(underTest.isMain()).isFalse();
+ }
+}
public void get_by_key_on_disabled_component() {
ComponentDto project = db.components().insertPrivateProject(p -> p.setEnabled(false));
- ComponentDto result = underTest.selectOrFailByKey(dbSession, project.getKey());
+ ComponentDto result = underTest.selectOrFailByKey(dbSession, project.getDbKey());
assertThat(result.isEnabled()).isFalse();
}
public void get_by_key_on_a_root_project() {
ComponentDto project = db.components().insertPrivateProject();
- ComponentDto result = underTest.selectOrFailByKey(dbSession, project.getKey());
+ ComponentDto result = underTest.selectOrFailByKey(dbSession, project.getDbKey());
assertThat(result.getDbKey()).isEqualTo(project.getDbKey());
assertThat(result.uuid()).isEqualTo(project.uuid());
ComponentDto project1 = db.components().insertPrivateProject();
ComponentDto project2 = db.components().insertPrivateProject();
- List<ComponentDto> results = underTest.selectByKeys(dbSession, asList(project1.getKey(), project2.getKey()));
+ List<ComponentDto> results = underTest.selectByKeys(dbSession, asList(project1.getDbKey(), project2.getDbKey()));
assertThat(results)
- .extracting(ComponentDto::uuid, ComponentDto::getKey)
+ .extracting(ComponentDto::uuid, ComponentDto::getDbKey)
.containsExactlyInAnyOrder(
- tuple(project1.uuid(), project1.getKey()),
- tuple(project2.uuid(), project2.getKey()));
+ tuple(project1.uuid(), project1.getDbKey()),
+ tuple(project2.uuid(), project2.getDbKey()));
assertThat(underTest.selectByKeys(dbSession, singletonList("unknown"))).isEmpty();
}
List<ComponentDto> results = underTest.selectByIds(dbSession, asList(project1.getId(), project2.getId()));
assertThat(results)
- .extracting(ComponentDto::uuid, ComponentDto::getKey)
+ .extracting(ComponentDto::uuid, ComponentDto::getDbKey)
.containsExactlyInAnyOrder(
- tuple(project1.uuid(), project1.getKey()),
- tuple(project2.uuid(), project2.getKey()));
+ tuple(project1.uuid(), project1.getDbKey()),
+ tuple(project2.uuid(), project2.getDbKey()));
assertThat(underTest.selectByIds(dbSession, singletonList(0L))).isEmpty();
}
List<ComponentDto> results = underTest.selectByUuids(dbSession, asList(project1.uuid(), project2.uuid()));
assertThat(results)
- .extracting(ComponentDto::uuid, ComponentDto::getKey)
+ .extracting(ComponentDto::uuid, ComponentDto::getDbKey)
.containsExactlyInAnyOrder(
- tuple(project1.uuid(), project1.getKey()),
- tuple(project2.uuid(), project2.getKey()));
+ tuple(project1.uuid(), project1.getDbKey()),
+ tuple(project2.uuid(), project2.getDbKey()));
assertThat(underTest.selectByUuids(dbSession, singletonList("unknown"))).isEmpty();
}
List<ComponentDto> results = underTest.selectByUuids(dbSession, asList(project1.uuid(), project2.uuid()));
assertThat(results)
- .extracting(ComponentDto::getKey, ComponentDto::isEnabled)
+ .extracting(ComponentDto::getDbKey, ComponentDto::isEnabled)
.containsExactlyInAnyOrder(
tuple(project1.getDbKey(), true),
tuple(project2.getDbKey(), false));
.isEmpty();
}
- @Test
- public void select_component_properties_by_keys() throws Exception {
- ComponentDto project = dbTester.components().insertPrivateProject();
- UserDto user = dbTester.users().insertUser();
-
- String key = "key";
- String anotherKey = "anotherKey";
- insertProperties(
- newGlobalPropertyDto().setKey(key),
- newComponentPropertyDto(project).setKey(key),
- newUserPropertyDto(user).setKey(key),
- newComponentPropertyDto(project).setKey(anotherKey));
-
- assertThat(underTest.selectPropertiesByKeysAndComponentId(session, newHashSet(key), project.getId())).extracting("key").containsOnly(key);
- assertThat(underTest.selectPropertiesByKeysAndComponentId(session, newHashSet(key, anotherKey), project.getId())).extracting("key").containsOnly(key, anotherKey);
- assertThat(underTest.selectPropertiesByKeysAndComponentId(session, newHashSet(key, anotherKey, "unknown"), project.getId())).extracting("key").containsOnly(key, anotherKey);
-
- assertThat(underTest.selectPropertiesByKeysAndComponentId(session, newHashSet("unknown"), project.getId())).isEmpty();
- assertThat(underTest.selectPropertiesByKeysAndComponentId(session, newHashSet(key), 123456789L)).isEmpty();
- }
-
@Test
public void select_component_properties_by_ids() throws Exception {
ComponentDto project = dbTester.components().insertPrivateProject();
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-
package org.sonar.server.platform.db.migration.version.v66;
import java.sql.SQLException;
.setColumnName("created_at")
.setIsNullable(false)
.build())
+ .addColumn(BigIntegerColumnDef.newBigIntegerColumnDefBuilder()
+ .setColumnName("updated_at")
+ .setIsNullable(false)
+ .build())
.build()
);
}
db.assertColumnDefinition(TABLE, "merge_branch_uuid", Types.VARCHAR, 50, true);
db.assertColumnDefinition(TABLE, "pull_request_title", Types.VARCHAR, 4000, true);
db.assertColumnDefinition(TABLE, "created_at", Types.BIGINT, null, false);
+ db.assertColumnDefinition(TABLE, "updated_at", Types.BIGINT, null, false);
db.assertPrimaryKey(TABLE, "pk_" + TABLE, "uuid");
}
public CeTask submit(String organizationKey, String projectKey, @Nullable String projectBranch, @Nullable String projectName, Map<String, String> characteristics,
InputStream reportInput) {
try (DbSession dbSession = dbClient.openSession(false)) {
- String effectiveProjectKey = ComponentKeys.createKey(projectKey, projectBranch);
OrganizationDto organizationDto = getOrganizationDtoOrFail(dbSession, organizationKey);
+ String effectiveProjectKey = ComponentKeys.createKey(projectKey, projectBranch);
Optional<ComponentDto> opt = dbClient.componentDao().selectByKey(dbSession, effectiveProjectKey);
ensureOrganizationIsConsistent(opt, organizationDto);
ComponentDto project = opt.or(() -> createProject(dbSession, organizationDto, projectKey, projectBranch, projectName));
}
}
- private ComponentDto createProject(DbSession dbSession, OrganizationDto organization, String projectKey, @Nullable String projectBranch, @Nullable String projectName) {
+ private ComponentDto createProject(DbSession dbSession, OrganizationDto organization, String projectKey, @Nullable String deprecatedBranch, @Nullable String projectName) {
userSession.checkPermission(OrganizationPermission.PROVISION_PROJECTS, organization);
Integer userId = userSession.getUserId();
+ String effectiveProjectKey = ComponentKeys.createEffectiveKey(projectKey, deprecatedBranch);
boolean wouldCurrentUserHaveScanPermission = permissionTemplateService.wouldUserHaveScanPermissionWithDefaultTemplate(
- dbSession, organization.getUuid(), userId, projectBranch, projectKey, Qualifiers.PROJECT);
+ dbSession, organization.getUuid(), userId, effectiveProjectKey, Qualifiers.PROJECT);
if (!wouldCurrentUserHaveScanPermission) {
throw insufficientPrivilegesException();
}
.setOrganizationUuid(organization.getUuid())
.setKey(projectKey)
.setName(StringUtils.defaultIfBlank(projectName, projectKey))
- .setBranch(projectBranch)
+ .setBranch(deprecatedBranch)
.setQualifier(Qualifiers.PROJECT)
.setPrivate(newProjectPrivate)
.build();
package org.sonar.server.computation.task.projectanalysis.analysis;
import java.util.Map;
+import java.util.Optional;
import javax.annotation.CheckForNull;
import org.sonar.server.qualityprofile.QualityProfile;
boolean isCrossProjectDuplicationEnabled();
/**
+ * Branch is present whatever the type of branch (long or short, main or not). However
+ * it is absent when analyzing a pull request.
+ *
* @throws IllegalStateException if branch has not been set
*/
- @CheckForNull
- String getBranch();
+ Optional<Branch> getBranch();
+
+ /**
+ * The project as represented by the main branch. It is used to load settings
+ * like Quality gates, webhooks and configuration.
+ *
+ * In case of analysis of main branch, the returned value is the main branch,
+ * so its uuid and key are the same in
+ * {@link org.sonar.server.computation.task.projectanalysis.component.TreeRootHolder#getRoot().
+ *
+ * In case of analysis of non-main branch or pull request, the returned value
+ * is the main branch. Its uuid and key are different than
+ * {@link org.sonar.server.computation.task.projectanalysis.component.TreeRootHolder#getRoot().
+ *
+ * @throws IllegalStateException if project has not been set
+ */
+ Project getProject();
/**
* @throws IllegalStateException if root component ref has not been set
import com.google.common.collect.ImmutableMap;
import java.util.Map;
+import java.util.Optional;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import org.sonar.server.computation.util.InitializedProperty;
private final InitializedProperty<Boolean> incrementalAnalysis = new InitializedProperty<>();
private final InitializedProperty<Analysis> baseProjectSnapshot = new InitializedProperty<>();
private final InitializedProperty<Boolean> crossProjectDuplicationEnabled = new InitializedProperty<>();
- private final InitializedProperty<String> branch = new InitializedProperty<>();
+ private final InitializedProperty<Branch> branch = new InitializedProperty<>();
+ private final InitializedProperty<Project> project = new InitializedProperty<>();
private final InitializedProperty<Integer> rootComponentRef = new InitializedProperty<>();
private final InitializedProperty<Map<String, QualityProfile>> qProfilesPerLanguage = new InitializedProperty<>();
private final InitializedProperty<Map<String, ScannerPlugin>> pluginsByKey = new InitializedProperty<>();
}
@Override
- public MutableAnalysisMetadataHolder setBranch(@Nullable String branch) {
+ public MutableAnalysisMetadataHolder setBranch(@Nullable Branch branch) {
checkState(!this.branch.isInitialized(), "Branch has already been set");
this.branch.setProperty(branch);
return this;
}
@Override
- public String getBranch() {
+ public Optional<Branch> getBranch() {
checkState(branch.isInitialized(), "Branch has not been set");
- return branch.getProperty();
+ return Optional.ofNullable(branch.getProperty());
+ }
+
+ @Override
+ public MutableAnalysisMetadataHolder setProject(Project project) {
+ checkState(!this.project.isInitialized(), "Project has already been set");
+ this.project.setProperty(project);
+ return this;
+ }
+
+ @Override
+ public Project getProject() {
+ checkState(project.isInitialized(), "Project has not been set");
+ return project.getProperty();
}
@Override
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.computation.task.projectanalysis.analysis;
+
+import java.util.Optional;
+import javax.annotation.concurrent.Immutable;
+import org.sonar.db.component.BranchType;
+import org.sonar.server.computation.task.projectanalysis.component.ComponentKeyGenerator;
+
+@Immutable
+public interface Branch extends ComponentKeyGenerator {
+
+ BranchType getType();
+
+ boolean isMain();
+
+ /**
+ * Name can be empty when it's not known on the main branch
+ * (regular analysis without the branch parameters)
+ */
+ Optional<String> getName();
+
+ /**
+ * Whether the cross-project duplication tracker must be enabled
+ * or not.
+ */
+ boolean supportsCrossProjectCpd();
+}
/**
* @throws IllegalStateException if branch has already been set
*/
- MutableAnalysisMetadataHolder setBranch(@Nullable String branch);
+ MutableAnalysisMetadataHolder setBranch(@Nullable Branch branch);
+
+ /**
+ * @throws IllegalStateException if project has already been set
+ */
+ MutableAnalysisMetadataHolder setProject(Project project);
/**
* @throws IllegalStateException if root component ref has already been set
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.computation.task.projectanalysis.analysis;
+
+import javax.annotation.concurrent.Immutable;
+import org.sonar.db.component.ComponentDto;
+import org.sonar.server.computation.task.projectanalysis.component.Component;
+
+@Immutable
+public class Project {
+
+ private final String uuid;
+ private final String key;
+ private final String name;
+
+ public Project(String uuid, String key, String name) {
+ this.uuid = uuid;
+ this.key = key;
+ this.name = name;
+ }
+
+ /**
+ * Always links to a row that exists in database.
+ */
+ public String getUuid() {
+ return uuid;
+ }
+
+ /**
+ * Always links to a row that exists in database.
+ */
+ public String getKey() {
+ return key;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ Project project = (Project) o;
+ return uuid.equals(project.uuid);
+ }
+
+ @Override
+ public int hashCode() {
+ return uuid.hashCode();
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder("Project{");
+ sb.append("uuid='").append(uuid).append('\'');
+ sb.append(", key='").append(key).append('\'');
+ sb.append(", name='").append(name).append('\'');
+ sb.append('}');
+ return sb.toString();
+ }
+
+ public static Project copyOf(Component component) {
+ return new Project(component.getUuid(), component.getKey(), component.getName());
+ }
+
+ public static Project copyOf(ComponentDto component) {
+ return new Project(component.uuid(), component.getDbKey(), component.name());
+ }
+}
import org.sonar.api.ce.measure.MeasureComputer.MeasureComputerContext;
import org.sonar.api.ce.measure.MeasureComputer.MeasureComputerDefinition;
import org.sonar.api.ce.measure.Settings;
-import org.sonar.api.config.Configuration;
import org.sonar.core.issue.DefaultIssue;
import org.sonar.server.computation.task.projectanalysis.component.ConfigurationRepository;
import org.sonar.server.computation.task.projectanalysis.issue.ComponentIssuesRepository;
@Override
@CheckForNull
public String getString(String key) {
- return getComponentSettings().get(key).orElse(null);
+ return config.getConfiguration().get(key).orElse(null);
}
@Override
public String[] getStringArray(String key) {
- return getComponentSettings().getStringArray(key);
+ return config.getConfiguration().getStringArray(key);
}
};
}
- private Configuration getComponentSettings() {
- return config.getConfiguration(internalComponent);
- }
-
@Override
@CheckForNull
public Measure getMeasure(String metric) {
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.computation.task.projectanalysis.component;
+
+import javax.annotation.Nullable;
+import org.sonar.api.utils.MessageException;
+import org.sonar.scanner.protocol.output.ScannerReport;
+import org.sonar.server.computation.task.projectanalysis.analysis.MutableAnalysisMetadataHolder;
+
+import static org.apache.commons.lang.StringUtils.trimToNull;
+
+public class BranchLoader {
+
+ private final MutableAnalysisMetadataHolder metadataHolder;
+ private final BranchLoaderDelegate delegate;
+
+ public BranchLoader(MutableAnalysisMetadataHolder metadataHolder) {
+ this(metadataHolder, null);
+ }
+
+ public BranchLoader(MutableAnalysisMetadataHolder metadataHolder, @Nullable BranchLoaderDelegate delegate) {
+ this.metadataHolder = metadataHolder;
+ this.delegate = delegate;
+ }
+
+ public void load(ScannerReport.Metadata metadata) {
+ String deprecatedBranch = trimToNull(metadata.getDeprecatedBranch());
+ String branchName = trimToNull(metadata.getBranchName());
+
+ if (deprecatedBranch != null && branchName != null) {
+ throw MessageException.of("Properties sonar.branch and sonar.branch.name can't be set together");
+ }
+
+ if (delegate != null && deprecatedBranch == null) {
+ delegate.load(metadata);
+ } else {
+ metadataHolder.setBranch(new MainBranchImpl(deprecatedBranch));
+ }
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.computation.task.projectanalysis.component;
+
+import org.sonar.api.ce.ComputeEngineSide;
+import org.sonar.scanner.protocol.output.ScannerReport;
+
+@ComputeEngineSide
+public interface BranchLoaderDelegate {
+
+ void load(ScannerReport.Metadata metadata);
+
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.computation.task.projectanalysis.component;
+
+import org.sonar.api.ce.ComputeEngineSide;
+import org.sonar.db.DbSession;
+
+@ComputeEngineSide
+public interface BranchPersisterDelegate {
+
+ void persist(DbSession dbSession);
+
+}
String getUuid();
/**
- * Returns the component key
+ * Returns the component key <b>as defined in database</b>
+ * It may differ from keys listed in scanner report
+ * when analyzing a branch.
*/
String getKey();
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.computation.task.projectanalysis.component;
+
+import javax.annotation.Nullable;
+import org.sonar.scanner.protocol.output.ScannerReport;
+
+@FunctionalInterface
+public interface ComponentKeyGenerator {
+
+ String generateKey(ScannerReport.Component module, @Nullable ScannerReport.Component fileOrDir);
+
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.computation.task.projectanalysis.component;
+
+import java.util.function.Function;
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+import org.sonar.db.component.SnapshotDto;
+import org.sonar.scanner.protocol.output.ScannerReport;
+import org.sonar.scanner.protocol.output.ScannerReport.Component.FileStatus;
+import org.sonar.server.computation.task.projectanalysis.analysis.Project;
+
+import static com.google.common.base.MoreObjects.firstNonNull;
+import static com.google.common.base.Preconditions.checkArgument;
+import static java.lang.String.format;
+import static org.apache.commons.lang.StringUtils.trimToNull;
+
+public class ComponentTreeBuilder {
+
+ private static final String DEFAULT_PROJECT_VERSION = "not provided";
+
+ private final ComponentKeyGenerator keyGenerator;
+ /**
+ * Will supply the UUID for any component in the tree, given it's key.
+ * <p>
+ * The String argument of the {@link Function#apply(Object)} method is the component's key.
+ * </p>
+ */
+ private final Function<String, String> uuidSupplier;
+
+ /**
+ * Will supply the {@link ScannerReport.Component} of all the components in the component tree as we crawl it from the
+ * root.
+ * <p>
+ * The Integer argument of the {@link Function#apply(Object)} method is the component's ref.
+ * </p>
+ */
+ private final Function<Integer, ScannerReport.Component> scannerComponentSupplier;
+
+ private final Project project;
+
+ @Nullable
+ private final SnapshotDto baseAnalysis;
+
+ public ComponentTreeBuilder(
+ ComponentKeyGenerator keyGenerator,
+ Function<String, String> uuidSupplier,
+ Function<Integer, ScannerReport.Component> scannerComponentSupplier,
+ Project project,
+ @Nullable SnapshotDto baseAnalysis) {
+
+ this.keyGenerator = keyGenerator;
+ this.uuidSupplier = uuidSupplier;
+ this.scannerComponentSupplier = scannerComponentSupplier;
+ this.project = project;
+ this.baseAnalysis = baseAnalysis;
+ }
+
+ public Component buildProject(ScannerReport.Component project) {
+ return buildComponent(project, project);
+ }
+
+ private Component[] buildChildren(ScannerReport.Component component, ScannerReport.Component parentModule) {
+ return component.getChildRefList()
+ .stream()
+ .map(componentRef -> buildComponent(scannerComponentSupplier.apply(componentRef), parentModule))
+ .toArray(Component[]::new);
+ }
+
+ private ComponentImpl buildComponent(ScannerReport.Component component, ScannerReport.Component closestModule) {
+ switch (component.getType()) {
+ case PROJECT:
+ String projectKey = keyGenerator.generateKey(component, null);
+ String uuid = uuidSupplier.apply(projectKey);
+ return ComponentImpl.builder(Component.Type.PROJECT)
+ .setUuid(uuid)
+ .setKey(projectKey)
+ .setName(nameOfProject(component))
+ .setStatus(convertStatus(component.getStatus()))
+ .setDescription(trimToNull(component.getDescription()))
+ .setReportAttributes(createAttributesBuilder(component)
+ .setVersion(createProjectVersion(component))
+ .build())
+ .addChildren(buildChildren(component, component))
+ .build();
+
+ case MODULE:
+ String moduleKey = keyGenerator.generateKey(component, null);
+ return ComponentImpl.builder(Component.Type.MODULE)
+ .setUuid(uuidSupplier.apply(moduleKey))
+ .setKey(moduleKey)
+ .setName(nameOfOthers(component, moduleKey))
+ .setStatus(convertStatus(component.getStatus()))
+ .setDescription(trimToNull(component.getDescription()))
+ .setReportAttributes(createAttributesBuilder(component).build())
+ .addChildren(buildChildren(component, component))
+ .build();
+
+ case DIRECTORY:
+ case FILE:
+ String key = keyGenerator.generateKey(closestModule, component);
+ return ComponentImpl.builder(convertDirOrFileType(component.getType()))
+ .setUuid(uuidSupplier.apply(key))
+ .setKey(key)
+ .setName(nameOfOthers(component, key))
+ .setStatus(convertStatus(component.getStatus()))
+ .setDescription(trimToNull(component.getDescription()))
+ .setReportAttributes(createAttributesBuilder(component).build())
+ .setFileAttributes(createFileAttributes(component))
+ .addChildren(buildChildren(component, closestModule))
+ .build();
+
+ default:
+ throw new IllegalArgumentException(format("Unsupported component type '%s'", component.getType()));
+ }
+ }
+
+ private static Component.Status convertStatus(FileStatus status) {
+ switch(status) {
+ case ADDED:
+ return Component.Status.ADDED;
+ case SAME:
+ return Component.Status.SAME;
+ case CHANGED:
+ return Component.Status.CHANGED;
+ case UNAVAILABLE:
+ return Component.Status.UNAVAILABLE;
+ case UNRECOGNIZED:
+ default:
+ throw new IllegalArgumentException("Unsupported ComponentType value " + status);
+ }
+ }
+
+ private String nameOfProject(ScannerReport.Component component) {
+ String name = trimToNull(component.getName());
+ if (name != null) {
+ return name;
+ }
+ return project.getName();
+ }
+
+ private static String nameOfOthers(ScannerReport.Component reportComponent, String defaultName) {
+ String name = trimToNull(reportComponent.getName());
+ return name == null ? defaultName : name;
+ }
+
+ private String createProjectVersion(ScannerReport.Component component) {
+ String version = trimToNull(component.getVersion());
+ if (version != null) {
+ return version;
+ }
+ if (baseAnalysis != null) {
+ return firstNonNull(baseAnalysis.getVersion(), DEFAULT_PROJECT_VERSION);
+ }
+ return DEFAULT_PROJECT_VERSION;
+ }
+
+ private static ReportAttributes.Builder createAttributesBuilder(ScannerReport.Component component) {
+ return ReportAttributes.newBuilder(component.getRef())
+ .setVersion(trimToNull(component.getVersion()))
+ .setPath(trimToNull(component.getPath()));
+ }
+
+ @CheckForNull
+ private static FileAttributes createFileAttributes(ScannerReport.Component component) {
+ if (component.getType() != ScannerReport.Component.ComponentType.FILE) {
+ return null;
+ }
+
+ checkArgument(component.getLines() > 0, "File '%s' has no line", component.getPath());
+ return new FileAttributes(
+ component.getIsTest(),
+ trimToNull(component.getLanguage()),
+ component.getLines());
+ }
+
+ private static Component.Type convertDirOrFileType(ScannerReport.Component.ComponentType type) {
+ switch (type) {
+ case DIRECTORY:
+ return Component.Type.DIRECTORY;
+ case FILE:
+ return Component.Type.FILE;
+ default:
+ throw new IllegalArgumentException("Unsupported ComponentType value " + type);
+ }
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.computation.task.projectanalysis.component;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.sonar.core.util.Uuids;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.component.ComponentDto;
+
+public class ComponentUuidFactory {
+
+ private final Map<String, String> uuidsByKey = new HashMap<>();
+
+ public ComponentUuidFactory(DbClient dbClient, DbSession dbSession, String rootKey) {
+ List<ComponentDto> components = dbClient.componentDao().selectAllComponentsFromProjectKey(dbSession, rootKey);
+ for (ComponentDto dto : components) {
+ uuidsByKey.put(dto.getDbKey(), dto.uuid());
+ }
+ }
+
+ /**
+ * Get UUID from database if it exists, otherwise generate a new one.
+ */
+ public String getOrCreateForKey(String key) {
+ return uuidsByKey.computeIfAbsent(key, k -> Uuids.create());
+ }
+}
import org.sonar.api.config.Configuration;
-/**
- * Repository of component settings.
- */
public interface ConfigurationRepository {
- /**
- * Returns the configuration for the specified Component.
- */
- Configuration getConfiguration(Component component);
+
+ Configuration getConfiguration();
+
}
*/
package org.sonar.server.computation.task.projectanalysis.component;
-import java.util.Collection;
-import java.util.Map;
+import com.google.common.base.Supplier;
+import com.google.common.base.Suppliers;
import org.sonar.api.config.Configuration;
+import org.sonar.ce.queue.CeTask;
import org.sonar.ce.settings.ProjectConfigurationFactory;
-import org.sonar.server.util.cache.CacheLoader;
-import org.sonar.server.util.cache.MemoryCache;
/**
* Repository of component settings implementation based on a memory cache.
*/
public class ConfigurationRepositoryImpl implements ConfigurationRepository {
- private final ProjectConfigurationFactory projectConfigurationFactory;
- private final MemoryCache<String, Configuration> cache = new MemoryCache<>(new CacheLoader<String, Configuration>() {
- @Override
- public Configuration load(String key) {
- return projectConfigurationFactory.newProjectConfiguration(key);
- }
+ private final Supplier<Configuration> configuration;
- @Override
- public Map<String, Configuration> loadAll(Collection<? extends String> keys) {
- throw new UnsupportedOperationException("loadAll is not supported");
- }
- });
-
- public ConfigurationRepositoryImpl(ProjectConfigurationFactory projectSettingsFactory) {
- this.projectConfigurationFactory = projectSettingsFactory;
+ public ConfigurationRepositoryImpl(CeTask ceTask, ProjectConfigurationFactory f) {
+ // project key is loaded from task because
+ // analysisMetadataHolder.getProject() may be not set yet
+ // when the first ComputationSteps are executed.
+ this.configuration = Suppliers.memoize(() -> f.newProjectConfiguration(ceTask.getComponentKey()));
}
@Override
- public Configuration getConfiguration(Component component) {
- return cache.get(component.getKey());
+ public Configuration getConfiguration() {
+ return configuration.get();
}
-
}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.computation.task.projectanalysis.component;
+
+import java.util.Optional;
+import javax.annotation.Nullable;
+import org.sonar.api.utils.MessageException;
+import org.sonar.core.component.ComponentKeys;
+import org.sonar.db.component.BranchType;
+import org.sonar.scanner.protocol.output.ScannerReport;
+import org.sonar.server.computation.task.projectanalysis.analysis.Branch;
+
+import static java.lang.String.format;
+import static org.apache.commons.lang.StringUtils.isEmpty;
+import static org.apache.commons.lang.StringUtils.trimToNull;
+
+/**
+ * The default (and legacy) implementation of {@link Branch}. It is used
+ * when scanner is configured with parameter "sonar.branch".
+ * A legacy branch is implemented as a fork of the project, so any branch
+ * is considered as "main".
+ */
+public class MainBranchImpl implements Branch {
+
+ @Nullable
+ private final String branchName;
+
+ public MainBranchImpl(@Nullable String name) {
+ this.branchName = name;
+ if (name != null && !ComponentKeys.isValidBranch(name)) {
+ throw MessageException.of(format("\"%s\" is not a valid branch name. "
+ + "Allowed characters are alphanumeric, '-', '_', '.' and '/'.", name));
+ }
+ }
+
+ @Override
+ public BranchType getType() {
+ return BranchType.LONG;
+ }
+
+ @Override
+ public boolean isMain() {
+ return true;
+ }
+
+ @Override
+ public Optional<String> getName() {
+ return Optional.ofNullable(branchName);
+ }
+
+ @Override
+ public boolean supportsCrossProjectCpd() {
+ // only on regular project, not on branches
+ return branchName == null;
+ }
+
+ @Override
+ public String generateKey(ScannerReport.Component module, @Nullable ScannerReport.Component fileOrDir) {
+ String moduleWithBranch = ComponentKeys.createKey(module.getKey(), branchName);
+ if (fileOrDir == null || isEmpty(fileOrDir.getPath())) {
+ return moduleWithBranch;
+ }
+ return ComponentKeys.createEffectiveKey(moduleWithBranch, trimToNull(fileOrDir.getPath()));
+ }
+}
*/
public interface TreeRootHolder {
/**
- * The root of the tree of Component representing the component in the current ScannerReport.
+ * The root of the tree, for example the project or the portfolio.
*
* @throws IllegalStateException if the holder is empty (ie. there is no root yet)
*/
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2017 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.server.computation.task.projectanalysis.component;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import org.sonar.core.util.Uuids;
-import org.sonar.db.DbClient;
-import org.sonar.db.DbSession;
-import org.sonar.db.component.ComponentDto;
-
-public class UuidFactory {
- private final Map<String, String> uuidsByKey = new HashMap<>();
-
- public UuidFactory(DbClient dbClient, String rootKey) {
- try (DbSession dbSession = dbClient.openSession(false)) {
- List<ComponentDto> components = dbClient.componentDao().selectAllComponentsFromProjectKey(dbSession, rootKey);
- for (ComponentDto componentDto : components) {
- uuidsByKey.put(componentDto.getDbKey(), componentDto.uuid());
- }
- }
- }
-
- /**
- * Get UUID from database if it exists, else generate a new one
- */
- public String getOrCreateForKey(String key) {
- String uuid = uuidsByKey.get(key);
- return (uuid == null) ? Uuids.create() : uuid;
- }
-}
import org.sonar.server.computation.task.projectanalysis.api.posttask.PostProjectAnalysisTasksExecutor;
import org.sonar.server.computation.task.projectanalysis.batch.BatchReportDirectoryHolderImpl;
import org.sonar.server.computation.task.projectanalysis.batch.BatchReportReaderImpl;
+import org.sonar.server.computation.task.projectanalysis.component.BranchLoader;
+import org.sonar.server.computation.task.projectanalysis.component.ConfigurationRepositoryImpl;
import org.sonar.server.computation.task.projectanalysis.component.DbIdsRepositoryImpl;
import org.sonar.server.computation.task.projectanalysis.component.DisabledComponentsHolderImpl;
-import org.sonar.server.computation.task.projectanalysis.component.ConfigurationRepositoryImpl;
import org.sonar.server.computation.task.projectanalysis.component.TreeRootHolderImpl;
import org.sonar.server.computation.task.projectanalysis.duplication.CrossProjectDuplicationStatusHolderImpl;
import org.sonar.server.computation.task.projectanalysis.duplication.DuplicationMeasures;
ActiveRulesHolderImpl.class,
MeasureComputersHolderImpl.class,
MutableTaskResultHolderImpl.class,
-
BatchReportReaderImpl.class,
// repositories
// views
ViewIndex.class,
+ BranchLoader.class,
MeasureToMeasureDto.class,
// webhooks
*/
package org.sonar.server.computation.task.projectanalysis.duplication;
+import java.util.Optional;
import javax.annotation.CheckForNull;
import org.picocontainer.Startable;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
import org.sonar.server.computation.task.projectanalysis.analysis.AnalysisMetadataHolder;
+import org.sonar.server.computation.task.projectanalysis.analysis.Branch;
import static com.google.common.base.Preconditions.checkState;
@Override
public void start() {
- boolean crossProjectDuplicationIsEnabledInReport = analysisMetadataHolder.isCrossProjectDuplicationEnabled();
- boolean branchIsUsed = analysisMetadataHolder.getBranch() != null;
- if (crossProjectDuplicationIsEnabledInReport && !branchIsUsed) {
+ boolean enabledInReport = analysisMetadataHolder.isCrossProjectDuplicationEnabled();
+ Optional<Branch> branch = analysisMetadataHolder.getBranch();
+ boolean supportedByBranch = !branch.isPresent() || branch.get().supportsCrossProjectCpd();
+ if (enabledInReport && supportedByBranch) {
LOGGER.debug("Cross project duplication is enabled");
this.enabled = true;
} else {
- if (!crossProjectDuplicationIsEnabledInReport) {
+ if (!enabledInReport) {
LOGGER.debug("Cross project duplication is disabled because it's disabled in the analysis report");
} else {
LOGGER.debug("Cross project duplication is disabled because of a branch is used");
import org.sonar.db.user.UserDto;
import org.sonar.server.computation.task.projectanalysis.analysis.AnalysisMetadataHolder;
import org.sonar.server.computation.task.projectanalysis.component.ConfigurationRepository;
-import org.sonar.server.computation.task.projectanalysis.component.TreeRootHolder;
import static org.sonar.api.CoreProperties.DEFAULT_ISSUE_ASSIGNEE;
private static final Logger LOG = Loggers.get(DefaultAssignee.class);
private final DbClient dbClient;
- private final TreeRootHolder treeRootHolder;
private final ConfigurationRepository configRepository;
private final AnalysisMetadataHolder analysisMetadataHolder;
private boolean loaded = false;
private String login = null;
- public DefaultAssignee(DbClient dbClient, TreeRootHolder treeRootHolder, ConfigurationRepository configRepository, AnalysisMetadataHolder analysisMetadataHolder) {
+ public DefaultAssignee(DbClient dbClient, ConfigurationRepository configRepository, AnalysisMetadataHolder analysisMetadataHolder) {
this.dbClient = dbClient;
- this.treeRootHolder = treeRootHolder;
this.configRepository = configRepository;
this.analysisMetadataHolder = analysisMetadataHolder;
}
if (loaded) {
return login;
}
- String configuredLogin = configRepository.getConfiguration(treeRootHolder.getRoot()).get(DEFAULT_ISSUE_ASSIGNEE).orElse(null);
+ String configuredLogin = configRepository.getConfiguration().get(DEFAULT_ISSUE_ASSIGNEE).orElse(null);
if (!Strings.isNullOrEmpty(configuredLogin) && isValidLogin(configuredLogin)) {
this.login = configuredLogin;
}
import org.sonar.core.issue.DefaultIssue;
import org.sonar.server.computation.task.projectanalysis.component.Component;
import org.sonar.server.computation.task.projectanalysis.component.ConfigurationRepository;
-import org.sonar.server.computation.task.projectanalysis.component.TreeRootHolder;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Strings.isNullOrEmpty;
private final List<IssuePattern> exclusionPatterns;
private final List<IssuePattern> inclusionPatterns;
- public IssueFilter(TreeRootHolder treeRootHolder, ConfigurationRepository configRepository) {
- Configuration config = configRepository.getConfiguration(treeRootHolder.getRoot());
+ public IssueFilter(ConfigurationRepository configRepository) {
+ Configuration config = configRepository.getConfiguration();
this.exclusionPatterns = loadPatterns(PATTERNS_MULTICRITERIA_EXCLUSION_KEY, config);
this.inclusionPatterns = loadPatterns(PATTERNS_MULTICRITERIA_INCLUSION_KEY, config);
}
private final DbClient dbClient;
private final MetricRepository metricRepository;
- public QualityGateServiceImpl(DbClient dbClient, final MetricRepository metricRepository) {
+ public QualityGateServiceImpl(DbClient dbClient, MetricRepository metricRepository) {
this.dbClient = dbClient;
this.metricRepository = metricRepository;
}
*/
package org.sonar.server.computation.task.projectanalysis.step;
-import com.google.common.base.Optional;
-import java.util.Objects;
-import java.util.function.Function;
+import java.util.Optional;
+import java.util.stream.Stream;
import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+import org.sonar.core.component.ComponentKeys;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.component.SnapshotDto;
import org.sonar.server.computation.task.projectanalysis.analysis.MutableAnalysisMetadataHolder;
import org.sonar.server.computation.task.projectanalysis.batch.BatchReportReader;
import org.sonar.server.computation.task.projectanalysis.component.Component;
-import org.sonar.server.computation.task.projectanalysis.component.ComponentRootBuilder;
+import org.sonar.server.computation.task.projectanalysis.component.ComponentKeyGenerator;
+import org.sonar.server.computation.task.projectanalysis.component.ComponentTreeBuilder;
+import org.sonar.server.computation.task.projectanalysis.component.ComponentUuidFactory;
import org.sonar.server.computation.task.projectanalysis.component.MutableTreeRootHolder;
-import org.sonar.server.computation.task.projectanalysis.component.UuidFactory;
import org.sonar.server.computation.task.step.ComputationStep;
-import static com.google.common.base.Preconditions.checkState;
-import static org.sonar.core.component.ComponentKeys.createKey;
+import static org.apache.commons.lang.StringUtils.isEmpty;
+import static org.apache.commons.lang.StringUtils.trimToNull;
/**
* Populates the {@link MutableTreeRootHolder} and {@link MutableAnalysisMetadataHolder} from the {@link BatchReportReader}
private final MutableTreeRootHolder treeRootHolder;
private final MutableAnalysisMetadataHolder analysisMetadataHolder;
- public BuildComponentTreeStep(DbClient dbClient, BatchReportReader reportReader, MutableTreeRootHolder treeRootHolder, MutableAnalysisMetadataHolder analysisMetadataHolder) {
+ public BuildComponentTreeStep(DbClient dbClient, BatchReportReader reportReader,
+ MutableTreeRootHolder treeRootHolder, MutableAnalysisMetadataHolder analysisMetadataHolder) {
this.dbClient = dbClient;
this.reportReader = reportReader;
this.treeRootHolder = treeRootHolder;
@Override
public void execute() {
- String branch = analysisMetadataHolder.getBranch();
- ScannerReport.Component reportProject = reportReader.readComponent(analysisMetadataHolder.getRootComponentRef());
- String projectKey = createKey(reportProject.getKey(), branch);
- UuidFactory uuidFactory = new UuidFactory(dbClient, projectKey);
-
try (DbSession dbSession = dbClient.openSession(false)) {
- BaseAnalysisSupplier baseAnalysisSupplier = new BaseAnalysisSupplier(dbClient, dbSession);
- ComponentRootBuilder rootBuilder = new ComponentRootBuilder(branch,
- uuidFactory::getOrCreateForKey,
+ ScannerReport.Component reportProject = reportReader.readComponent(analysisMetadataHolder.getRootComponentRef());
+ ComponentKeyGenerator keyGenerator = loadKeyGenerator();
+
+ // root key of branch, not necessarily of project
+ String rootKey = keyGenerator.generateKey(reportProject, null);
+
+ // loads the UUIDs from database. If they don't exist, then generate new ones
+ ComponentUuidFactory componentUuidFactory = new ComponentUuidFactory(dbClient, dbSession, rootKey);
+
+ String rootUuid = componentUuidFactory.getOrCreateForKey(rootKey);
+ SnapshotDto baseAnalysis = loadBaseAnalysis(dbSession, rootUuid);
+
+ ComponentTreeBuilder builder = new ComponentTreeBuilder(keyGenerator,
+ componentUuidFactory::getOrCreateForKey,
reportReader::readComponent,
- () -> dbClient.componentDao().selectByKey(dbSession, projectKey),
- baseAnalysisSupplier);
- Component project = rootBuilder.build(reportProject, projectKey);
+ analysisMetadataHolder.getProject(),
+ baseAnalysis);
+ Component project = builder.buildProject(reportProject);
+
treeRootHolder.setRoot(project);
- analysisMetadataHolder.setBaseAnalysis(toAnalysis(baseAnalysisSupplier.apply(project.getUuid())));
+ analysisMetadataHolder.setBaseAnalysis(toAnalysis(baseAnalysis));
}
}
- /**
- * A supplier of the base analysis of the project (if it exists) that will cache the retrieved SnapshotDto and
- * implement a sanity check to ensure it is always call with the same UUID value (since it's the project's UUID, it
- * is unique for a whole task).
- */
- private static final class BaseAnalysisSupplier implements Function<String, Optional<SnapshotDto>> {
- private final DbClient dbClient;
- private final DbSession dbSession;
- private String projectUuid = null;
- private Optional<SnapshotDto> cache = null;
-
- private BaseAnalysisSupplier(DbClient dbClient, DbSession dbSession) {
- this.dbClient = dbClient;
- this.dbSession = dbSession;
- }
+ private ComponentKeyGenerator loadKeyGenerator() {
+ return Stream.of(analysisMetadataHolder.getBranch(), Optional.of(new DefaultKeyGenerator()))
+ // TODO pull request generator will be added here
+ .filter(Optional::isPresent)
+ .flatMap(x -> x.map(Stream::of).orElseGet(Stream::empty))
+ .findFirst()
+ .get();
+ }
- @Override
- public Optional<SnapshotDto> apply(String projectUuid) {
- if (this.cache == null) {
- this.cache = Optional.fromNullable(
- dbClient.snapshotDao().selectAnalysisByQuery(
- dbSession,
- new SnapshotQuery()
- .setComponentUuid(projectUuid)
- .setIsLast(true)));
- this.projectUuid = projectUuid;
- } else {
- checkState(
- Objects.equals(this.projectUuid, projectUuid),
- "BaseAnalysisSupplier called with different project uuid values. First one was %s but current one is %s",
- this.projectUuid, projectUuid);
- }
- return this.cache;
- }
+ @CheckForNull
+ private SnapshotDto loadBaseAnalysis(DbSession dbSession, String rootUuid) {
+ return dbClient.snapshotDao().selectAnalysisByQuery(
+ dbSession,
+ new SnapshotQuery()
+ .setComponentUuid(rootUuid)
+ .setIsLast(true));
}
@CheckForNull
- private static Analysis toAnalysis(Optional<SnapshotDto> snapshotDto) {
- if (snapshotDto.isPresent()) {
- SnapshotDto dto = snapshotDto.get();
+ private static Analysis toAnalysis(@Nullable SnapshotDto dto) {
+ if (dto != null) {
return new Analysis.Builder()
.setId(dto.getId())
.setUuid(dto.getUuid())
return null;
}
+ private static class DefaultKeyGenerator implements ComponentKeyGenerator {
+ @Override
+ public String generateKey(ScannerReport.Component module, @Nullable ScannerReport.Component fileOrDir) {
+ String moduleKey = module.getKey();
+ if (fileOrDir == null || isEmpty(fileOrDir.getPath())) {
+ return moduleKey;
+ }
+ return ComponentKeys.createEffectiveKey(moduleKey, trimToNull(fileOrDir.getPath()));
+ }
+ }
}
PeriodResolver periodResolver = new PeriodResolver(dbClient, session, projectDto.get().uuid(), analysisMetadataHolder.getAnalysisDate(),
isReportType ? projectOrView.getReportAttributes().getVersion() : null);
- Configuration config = configRepository.getConfiguration(projectOrView);
+ Configuration config = configRepository.getConfiguration();
Period period = periodResolver.resolve(config);
// SONAR-4700 Add a past snapshot only if it exists
if (period != null) {
package org.sonar.server.computation.task.projectanalysis.step;
import com.google.common.base.Optional;
-import org.apache.commons.lang.StringUtils;
import org.sonar.api.config.Configuration;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
-import org.sonar.server.computation.task.projectanalysis.component.Component;
import org.sonar.server.computation.task.projectanalysis.component.ConfigurationRepository;
-import org.sonar.server.computation.task.projectanalysis.component.CrawlerDepthLimit;
-import org.sonar.server.computation.task.projectanalysis.component.DepthTraversalTypeAwareCrawler;
-import org.sonar.server.computation.task.projectanalysis.component.TreeRootHolder;
-import org.sonar.server.computation.task.projectanalysis.component.TypeAwareVisitorAdapter;
import org.sonar.server.computation.task.projectanalysis.qualitygate.MutableQualityGateHolder;
import org.sonar.server.computation.task.projectanalysis.qualitygate.QualityGate;
import org.sonar.server.computation.task.projectanalysis.qualitygate.QualityGateService;
import org.sonar.server.computation.task.step.ComputationStep;
-import static org.sonar.server.computation.task.projectanalysis.component.ComponentVisitor.Order.PRE_ORDER;
+import static org.apache.commons.lang.StringUtils.isBlank;
/**
* This step retrieves the QualityGate and stores it in
private static final String PROPERTY_QUALITY_GATE = "sonar.qualitygate";
- private final TreeRootHolder treeRootHolder;
private final ConfigurationRepository configRepository;
private final QualityGateService qualityGateService;
private final MutableQualityGateHolder qualityGateHolder;
- public LoadQualityGateStep(TreeRootHolder treeRootHolder, ConfigurationRepository settingsRepository,
+ public LoadQualityGateStep(ConfigurationRepository settingsRepository,
QualityGateService qualityGateService, MutableQualityGateHolder qualityGateHolder) {
- this.treeRootHolder = treeRootHolder;
this.configRepository = settingsRepository;
this.qualityGateService = qualityGateService;
this.qualityGateHolder = qualityGateHolder;
@Override
public void execute() {
- new DepthTraversalTypeAwareCrawler(
- new TypeAwareVisitorAdapter(CrawlerDepthLimit.PROJECT, PRE_ORDER) {
- @Override
- public void visitProject(Component project) {
- executeForProject(project);
- }
- }).visit(treeRootHolder.getRoot());
- }
-
- private void executeForProject(Component project) {
- String projectKey = project.getKey();
- Configuration config = configRepository.getConfiguration(project);
+ Configuration config = configRepository.getConfiguration();
String qualityGateSetting = config.get(PROPERTY_QUALITY_GATE).orElse(null);
- if (StringUtils.isBlank(qualityGateSetting)) {
- LOGGER.debug("No quality gate is configured for project " + projectKey);
+ if (isBlank(qualityGateSetting)) {
+ LOGGER.debug("No quality gate is configured");
qualityGateHolder.setNoQualityGate();
return;
}
import java.util.Optional;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
+import org.apache.commons.lang.StringUtils;
import org.sonar.api.utils.MessageException;
import org.sonar.ce.queue.CeTask;
+import org.sonar.core.component.ComponentKeys;
import org.sonar.core.platform.PluginInfo;
import org.sonar.core.platform.PluginRepository;
import org.sonar.core.util.stream.MoreCollectors;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
+import org.sonar.db.component.ComponentDto;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.qualityprofile.QProfileDto;
import org.sonar.scanner.protocol.output.ScannerReport;
import org.sonar.scanner.protocol.output.ScannerReport.Metadata.QProfile;
import org.sonar.server.computation.task.projectanalysis.analysis.MutableAnalysisMetadataHolder;
import org.sonar.server.computation.task.projectanalysis.analysis.Organization;
+import org.sonar.server.computation.task.projectanalysis.analysis.Project;
import org.sonar.server.computation.task.projectanalysis.analysis.ScannerPlugin;
import org.sonar.server.computation.task.projectanalysis.batch.BatchReportReader;
+import org.sonar.server.computation.task.projectanalysis.component.BranchLoader;
import org.sonar.server.computation.task.step.ComputationStep;
-import org.sonar.server.organization.BillingValidations;
-import org.sonar.server.organization.BillingValidations.BillingValidationsException;
-import org.sonar.server.organization.BillingValidationsProxy;
import org.sonar.server.organization.DefaultOrganizationProvider;
import org.sonar.server.qualityprofile.QualityProfile;
+import static java.util.stream.Collectors.toMap;
import static com.google.common.base.Preconditions.checkState;
+import static com.google.common.collect.Maps.transformValues;
import static java.lang.String.format;
-import static java.util.stream.Collectors.toMap;
import static org.apache.commons.lang.StringUtils.isNotEmpty;
import static org.sonar.core.util.stream.MoreCollectors.toList;
* Feed analysis metadata holder with metadata from the analysis report.
*/
public class LoadReportAnalysisMetadataHolderStep implements ComputationStep {
-
private final CeTask ceTask;
private final BatchReportReader reportReader;
- private final MutableAnalysisMetadataHolder mutableAnalysisMetadataHolder;
+ private final MutableAnalysisMetadataHolder analysisMetadata;
private final DefaultOrganizationProvider defaultOrganizationProvider;
private final DbClient dbClient;
- private final BillingValidations billingValidations;
+ private final BranchLoader branchLoader;
private final PluginRepository pluginRepository;
- public LoadReportAnalysisMetadataHolderStep(CeTask ceTask, BatchReportReader reportReader, MutableAnalysisMetadataHolder mutableAnalysisMetadataHolder,
- DefaultOrganizationProvider defaultOrganizationProvider, DbClient dbClient, BillingValidationsProxy billingValidations, PluginRepository pluginRepository) {
+ public LoadReportAnalysisMetadataHolderStep(CeTask ceTask, BatchReportReader reportReader, MutableAnalysisMetadataHolder analysisMetadata,
+ DefaultOrganizationProvider defaultOrganizationProvider, DbClient dbClient, BranchLoader branchLoader, PluginRepository pluginRepository) {
this.ceTask = ceTask;
this.reportReader = reportReader;
- this.mutableAnalysisMetadataHolder = mutableAnalysisMetadataHolder;
+ this.analysisMetadata = analysisMetadata;
this.defaultOrganizationProvider = defaultOrganizationProvider;
this.dbClient = dbClient;
- this.billingValidations = billingValidations;
+ this.branchLoader = branchLoader;
this.pluginRepository = pluginRepository;
}
@Override
public void execute() {
ScannerReport.Metadata reportMetadata = reportReader.readMetadata();
- mutableAnalysisMetadataHolder.setAnalysisDate(reportMetadata.getAnalysisDate());
- checkProjectKeyConsistency(reportMetadata);
+ loadMetadata(reportMetadata);
+ Organization organization = loadOrganization(reportMetadata);
+ loadProject(reportMetadata, organization);
+ loadIncrementalMode(reportMetadata);
+ loadQualityProfiles(reportMetadata, organization);
+ branchLoader.load(reportMetadata);
+ }
+
+ private void loadMetadata(ScannerReport.Metadata reportMetadata) {
+ analysisMetadata.setAnalysisDate(reportMetadata.getAnalysisDate());
+ analysisMetadata.setRootComponentRef(reportMetadata.getRootComponentRef());
+ analysisMetadata.setCrossProjectDuplicationEnabled(reportMetadata.getCrossProjectDuplicationActivated());
+ }
+
+ private void loadProject(ScannerReport.Metadata reportMetadata, Organization organization) {
+ String reportProjectKey = projectKeyFromReport(reportMetadata);
+ checkProjectKeyConsistency(reportProjectKey);
+ ComponentDto dto = toProject(reportProjectKey);
+ if (!dto.getOrganizationUuid().equals(organization.getUuid())) {
+ throw MessageException.of(format("Project is not in the expected organization: %s", organization.getKey()));
+ }
+ if (dto.getMainBranchProjectUuid() != null) {
+ throw MessageException.of("Project should not reference a branch");
+ }
+ analysisMetadata.setProject(new Project(dto.uuid(), dto.getDbKey(), dto.name()));
+ }
+
+ private Organization loadOrganization(ScannerReport.Metadata reportMetadata) {
Organization organization = toOrganization(ceTask.getOrganizationUuid());
checkOrganizationKeyConsistency(reportMetadata, organization);
- checkOrganizationCanExecuteAnalysis(organization);
- checkQualityProfilesConsistency(reportMetadata, organization);
+ analysisMetadata.setOrganization(organization);
+ return organization;
+ }
- mutableAnalysisMetadataHolder.setRootComponentRef(reportMetadata.getRootComponentRef());
- mutableAnalysisMetadataHolder.setBranch(isNotEmpty(reportMetadata.getBranch()) ? reportMetadata.getBranch() : null);
- mutableAnalysisMetadataHolder.setCrossProjectDuplicationEnabled(reportMetadata.getCrossProjectDuplicationActivated());
- mutableAnalysisMetadataHolder.setIncrementalAnalysis(reportMetadata.getIncremental());
- mutableAnalysisMetadataHolder.setQProfilesByLanguage(reportMetadata.getQprofilesPerLanguage().values().stream()
+ private void loadQualityProfiles(ScannerReport.Metadata reportMetadata, Organization organization) {
+ checkQualityProfilesConsistency(reportMetadata, organization);
+ analysisMetadata.setQProfilesByLanguage(reportMetadata.getQprofilesPerLanguage().values().stream()
.collect(toMap(
QProfile::getLanguage,
qp -> new QualityProfile(qp.getKey(), qp.getName(), qp.getLanguage(), new Date(qp.getRulesUpdatedAt())))));
- mutableAnalysisMetadataHolder.setScannerPluginsByKey(reportMetadata.getPluginsByKey().values().stream()
+ analysisMetadata.setScannerPluginsByKey(reportMetadata.getPluginsByKey().values().stream()
.collect(toMap(
Plugin::getKey,
p -> new ScannerPlugin(p.getKey(), getBasePluginKey(p), p.getUpdatedAt()))));
- mutableAnalysisMetadataHolder.setOrganization(organization);
}
@CheckForNull
return pluginInfo.getBasePlugin();
}
+ private void loadIncrementalMode(ScannerReport.Metadata reportMetadata) {
+ analysisMetadata.setIncrementalAnalysis(reportMetadata.getIncremental());
+ }
+
/**
* Check that the Quality profiles sent by scanner correctly relate to the project organization.
*/
}
}
- private void checkProjectKeyConsistency(ScannerReport.Metadata reportMetadata) {
- String reportProjectKey = projectKeyFromReport(reportMetadata);
+ private void checkProjectKeyConsistency(String reportProjectKey) {
String componentKey = ceTask.getComponentKey();
if (componentKey == null) {
throw MessageException.of(format(
}
}
- private void checkOrganizationCanExecuteAnalysis(Organization organization) {
- try {
- billingValidations.checkOnProjectAnalysis(new BillingValidations.Organization(organization.getKey(), organization.getUuid()));
- } catch (BillingValidationsException e) {
- throw MessageException.of(e.getMessage());
- }
- }
-
private String resolveReportOrganizationKey(@Nullable String organizationKey) {
if (reportBelongsToDefaultOrganization(organizationKey)) {
return defaultOrganizationProvider.get().getKey();
private Organization toOrganization(String organizationUuid) {
try (DbSession dbSession = dbClient.openSession(false)) {
Optional<OrganizationDto> organizationDto = dbClient.organizationDao().selectByUuid(dbSession, organizationUuid);
- checkState(organizationDto.isPresent(), "Organization with uuid '{}' can't be found", organizationUuid);
+ checkState(organizationDto.isPresent(), "Organization with uuid '%s' can't be found", organizationUuid);
return Organization.from(organizationDto.get());
}
}
+ private ComponentDto toProject(String projectKey) {
+ try (DbSession dbSession = dbClient.openSession(false)) {
+ com.google.common.base.Optional<ComponentDto> opt = dbClient.componentDao().selectByKey(dbSession, projectKey);
+ checkState(opt.isPresent(), "Project with key '%s' can't be found", projectKey);
+ return opt.get();
+ }
+ }
+
private static String projectKeyFromReport(ScannerReport.Metadata reportMetadata) {
- if (isNotEmpty(reportMetadata.getBranch())) {
- return reportMetadata.getProjectKey() + ":" + reportMetadata.getBranch();
+ String deprecatedBranch = reportMetadata.getDeprecatedBranch();
+ if (StringUtils.isNotEmpty(deprecatedBranch)) {
+ return ComponentKeys.createKey(reportMetadata.getProjectKey(), deprecatedBranch);
}
return reportMetadata.getProjectKey();
}
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;
+import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang.StringUtils;
import org.sonar.api.resources.Qualifiers;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.component.ComponentUpdateDto;
import org.sonar.server.computation.task.projectanalysis.analysis.AnalysisMetadataHolder;
+import org.sonar.server.computation.task.projectanalysis.analysis.Branch;
+import org.sonar.server.computation.task.projectanalysis.component.BranchPersisterDelegate;
import org.sonar.server.computation.task.projectanalysis.component.Component;
import org.sonar.server.computation.task.projectanalysis.component.CrawlerDepthLimit;
import org.sonar.server.computation.task.projectanalysis.component.DbIdsRepositoryImpl;
import org.sonar.server.computation.task.step.ComputationStep;
import static com.google.common.collect.FluentIterable.from;
+import static java.util.Optional.ofNullable;
import static org.sonar.db.component.ComponentDto.UUID_PATH_OF_ROOT;
import static org.sonar.db.component.ComponentDto.UUID_PATH_SEPARATOR;
import static org.sonar.db.component.ComponentDto.formatUuidPathFromParent;
private final System2 system2;
private final MutableDisabledComponentsHolder disabledComponentsHolder;
private final AnalysisMetadataHolder analysisMetadataHolder;
+ @Nullable
+ private final BranchPersisterDelegate branchPersister;
public PersistComponentsStep(DbClient dbClient, TreeRootHolder treeRootHolder,
MutableDbIdsRepository dbIdsRepository, System2 system2,
MutableDisabledComponentsHolder disabledComponentsHolder, AnalysisMetadataHolder analysisMetadataHolder) {
+ this(dbClient, treeRootHolder, dbIdsRepository, system2, disabledComponentsHolder, analysisMetadataHolder, null);
+ }
+
+ public PersistComponentsStep(DbClient dbClient, TreeRootHolder treeRootHolder,
+ MutableDbIdsRepository dbIdsRepository, System2 system2,
+ MutableDisabledComponentsHolder disabledComponentsHolder, AnalysisMetadataHolder analysisMetadataHolder,
+ @Nullable BranchPersisterDelegate branchPersister) {
this.dbClient = dbClient;
this.treeRootHolder = treeRootHolder;
this.dbIdsRepository = dbIdsRepository;
this.system2 = system2;
this.disabledComponentsHolder = disabledComponentsHolder;
this.analysisMetadataHolder = analysisMetadataHolder;
+ this.branchPersister = branchPersister;
}
@Override
@Override
public void execute() {
try (DbSession dbSession = dbClient.openSession(false)) {
+ ofNullable(branchPersister).ifPresent(p -> p.persist(dbSession));
+
String projectUuid = treeRootHolder.getRoot().getUuid();
// safeguard, reset all rows to b-changed=false
Map<String, ComponentDto> existingDtosByKeys = indexExistingDtosByKey(dbSession);
boolean isRootPrivate = isRootPrivate(treeRootHolder.getRoot(), existingDtosByKeys);
+ String mainBranchProjectUuid = loadProjectUuidOfMainBranch();
+
// Insert or update the components in database. They are removed from existingDtosByKeys
// at the same time.
- new PathAwareCrawler<>(new PersistComponentStepsVisitor(existingDtosByKeys, dbSession))
+ new PathAwareCrawler<>(new PersistComponentStepsVisitor(existingDtosByKeys, dbSession, mainBranchProjectUuid))
.visit(treeRootHolder.getRoot());
disableRemainingComponents(dbSession, existingDtosByKeys.values());
}
}
+ /**
+ * See {@link ComponentDto#mainBranchProjectUuid} : value is null on main branches, otherwise it is
+ * the uuid of the main branch.
+ */
+ @CheckForNull
+ private String loadProjectUuidOfMainBranch() {
+ Optional<Branch> branch = analysisMetadataHolder.getBranch();
+ if (branch.isPresent() && !branch.get().isMain()) {
+ return analysisMetadataHolder.getProject().getUuid();
+ }
+ return null;
+ }
+
private void disableRemainingComponents(DbSession dbSession, Collection<ComponentDto> dtos) {
Set<String> uuids = dtos.stream()
.filter(ComponentDto::isEnabled)
private final Map<String, ComponentDto> existingComponentDtosByKey;
private final DbSession dbSession;
+ @Nullable
+ private final String mainBranchProjectUuid;
- public PersistComponentStepsVisitor(Map<String, ComponentDto> existingComponentDtosByKey, DbSession dbSession) {
+ PersistComponentStepsVisitor(Map<String, ComponentDto> existingComponentDtosByKey, DbSession dbSession, @Nullable String mainBranchProjectUuid) {
super(
CrawlerDepthLimit.LEAVES,
PRE_ORDER,
});
this.existingComponentDtosByKey = existingComponentDtosByKey;
this.dbSession = dbSession;
+ this.mainBranchProjectUuid = mainBranchProjectUuid;
}
@Override
private void addToCache(Component component, ComponentDto componentDto) {
dbIdsRepository.setComponentId(component, componentDto.getId());
}
- }
- public ComponentDto createForProject(Component project) {
- ComponentDto res = createBase(project);
+ public ComponentDto createForProject(Component project) {
+ ComponentDto res = createBase(project);
- res.setScope(Scopes.PROJECT);
- res.setQualifier(Qualifiers.PROJECT);
- res.setName(project.getName());
- res.setLongName(res.name());
- res.setDescription(project.getDescription());
+ res.setScope(Scopes.PROJECT);
+ res.setQualifier(Qualifiers.PROJECT);
+ res.setName(project.getName());
+ res.setLongName(res.name());
+ res.setDescription(project.getDescription());
- res.setProjectUuid(res.uuid());
- res.setRootUuid(res.uuid());
- res.setUuidPath(UUID_PATH_OF_ROOT);
- res.setModuleUuidPath(UUID_PATH_SEPARATOR + res.uuid() + UUID_PATH_SEPARATOR);
+ res.setProjectUuid(res.uuid());
+ res.setRootUuid(res.uuid());
+ res.setUuidPath(UUID_PATH_OF_ROOT);
+ res.setModuleUuidPath(UUID_PATH_SEPARATOR + res.uuid() + UUID_PATH_SEPARATOR);
- return res;
- }
+ return res;
+ }
- public ComponentDto createForModule(Component module, PathAwareVisitor.Path<ComponentDtoHolder> path) {
- ComponentDto res = createBase(module);
+ public ComponentDto createForModule(Component module, PathAwareVisitor.Path<ComponentDtoHolder> path) {
+ ComponentDto res = createBase(module);
- res.setScope(Scopes.PROJECT);
- res.setQualifier(Qualifiers.MODULE);
- res.setName(module.getName());
- res.setLongName(res.name());
- res.setPath(module.getReportAttributes().getPath());
- res.setDescription(module.getDescription());
+ res.setScope(Scopes.PROJECT);
+ res.setQualifier(Qualifiers.MODULE);
+ res.setName(module.getName());
+ res.setLongName(res.name());
+ res.setPath(module.getReportAttributes().getPath());
+ res.setDescription(module.getDescription());
- setRootAndParentModule(res, path);
+ setRootAndParentModule(res, path);
- return res;
- }
+ return res;
+ }
- public ComponentDto createForDirectory(Component directory, PathAwareVisitor.Path<ComponentDtoHolder> path) {
- ComponentDto res = createBase(directory);
+ public ComponentDto createForDirectory(Component directory, PathAwareVisitor.Path<ComponentDtoHolder> path) {
+ ComponentDto res = createBase(directory);
- res.setScope(Scopes.DIRECTORY);
- res.setQualifier(Qualifiers.DIRECTORY);
- res.setName(directory.getReportAttributes().getPath());
- res.setLongName(directory.getReportAttributes().getPath());
- res.setPath(directory.getReportAttributes().getPath());
+ res.setScope(Scopes.DIRECTORY);
+ res.setQualifier(Qualifiers.DIRECTORY);
+ res.setName(directory.getReportAttributes().getPath());
+ res.setLongName(directory.getReportAttributes().getPath());
+ res.setPath(directory.getReportAttributes().getPath());
- setParentModuleProperties(res, path);
+ setParentModuleProperties(res, path);
- return res;
- }
+ return res;
+ }
- public ComponentDto createForFile(Component file, PathAwareVisitor.Path<ComponentDtoHolder> path) {
- ComponentDto res = createBase(file);
+ public ComponentDto createForFile(Component file, PathAwareVisitor.Path<ComponentDtoHolder> path) {
+ ComponentDto res = createBase(file);
- res.setScope(Scopes.FILE);
- res.setQualifier(getFileQualifier(file));
- res.setName(FilenameUtils.getName(file.getReportAttributes().getPath()));
- res.setLongName(file.getReportAttributes().getPath());
- res.setPath(file.getReportAttributes().getPath());
- res.setLanguage(file.getFileAttributes().getLanguageKey());
+ res.setScope(Scopes.FILE);
+ res.setQualifier(getFileQualifier(file));
+ res.setName(FilenameUtils.getName(file.getReportAttributes().getPath()));
+ res.setLongName(file.getReportAttributes().getPath());
+ res.setPath(file.getReportAttributes().getPath());
+ res.setLanguage(file.getFileAttributes().getLanguageKey());
- setParentModuleProperties(res, path);
+ setParentModuleProperties(res, path);
- return res;
- }
+ return res;
+ }
- private ComponentDto createForView(Component view) {
- ComponentDto res = createBase(view);
+ private ComponentDto createForView(Component view) {
+ ComponentDto res = createBase(view);
- res.setScope(Scopes.PROJECT);
- res.setQualifier(view.getViewAttributes().getType().getQualifier());
- res.setName(view.getName());
- res.setDescription(view.getDescription());
- res.setLongName(res.name());
+ res.setScope(Scopes.PROJECT);
+ res.setQualifier(view.getViewAttributes().getType().getQualifier());
+ res.setName(view.getName());
+ res.setDescription(view.getDescription());
+ res.setLongName(res.name());
- res.setProjectUuid(res.uuid());
- res.setRootUuid(res.uuid());
- res.setUuidPath(UUID_PATH_OF_ROOT);
- res.setModuleUuidPath(UUID_PATH_SEPARATOR + res.uuid() + UUID_PATH_SEPARATOR);
+ res.setProjectUuid(res.uuid());
+ res.setRootUuid(res.uuid());
+ res.setUuidPath(UUID_PATH_OF_ROOT);
+ res.setModuleUuidPath(UUID_PATH_SEPARATOR + res.uuid() + UUID_PATH_SEPARATOR);
- return res;
- }
+ return res;
+ }
- private ComponentDto createForSubView(Component subView, PathAwareVisitor.Path<ComponentDtoHolder> path) {
- ComponentDto res = createBase(subView);
+ private ComponentDto createForSubView(Component subView, PathAwareVisitor.Path<ComponentDtoHolder> path) {
+ ComponentDto res = createBase(subView);
- res.setScope(Scopes.PROJECT);
- res.setQualifier(Qualifiers.SUBVIEW);
- res.setName(subView.getName());
- res.setDescription(subView.getDescription());
- res.setLongName(res.name());
- res.setCopyComponentUuid(subView.getSubViewAttributes().getOriginalViewUuid());
+ res.setScope(Scopes.PROJECT);
+ res.setQualifier(Qualifiers.SUBVIEW);
+ res.setName(subView.getName());
+ res.setDescription(subView.getDescription());
+ res.setLongName(res.name());
+ res.setCopyComponentUuid(subView.getSubViewAttributes().getOriginalViewUuid());
- setRootAndParentModule(res, path);
+ setRootAndParentModule(res, path);
- return res;
- }
+ return res;
+ }
- private ComponentDto createForProjectView(Component projectView, PathAwareVisitor.Path<ComponentDtoHolder> path) {
- ComponentDto res = createBase(projectView);
+ private ComponentDto createForProjectView(Component projectView, PathAwareVisitor.Path<ComponentDtoHolder> path) {
+ ComponentDto res = createBase(projectView);
- res.setScope(Scopes.FILE);
- res.setQualifier(Qualifiers.PROJECT);
- res.setName(projectView.getName());
- res.setLongName(res.name());
- res.setCopyComponentUuid(projectView.getProjectViewAttributes().getProjectUuid());
+ res.setScope(Scopes.FILE);
+ res.setQualifier(Qualifiers.PROJECT);
+ res.setName(projectView.getName());
+ res.setLongName(res.name());
+ res.setCopyComponentUuid(projectView.getProjectViewAttributes().getProjectUuid());
- setRootAndParentModule(res, path);
+ setRootAndParentModule(res, path);
- return res;
- }
+ return res;
+ }
- private ComponentDto createBase(Component component) {
- String componentKey = component.getKey();
- String componentUuid = component.getUuid();
-
- ComponentDto componentDto = new ComponentDto();
- componentDto.setOrganizationUuid(analysisMetadataHolder.getOrganization().getUuid());
- componentDto.setUuid(componentUuid);
- componentDto.setDbKey(componentKey);
- componentDto.setDeprecatedKey(componentKey);
- componentDto.setEnabled(true);
- componentDto.setCreatedAt(new Date(system2.now()));
- return componentDto;
- }
+ private ComponentDto createBase(Component component) {
+ String componentKey = component.getKey();
+ String componentUuid = component.getUuid();
- /**
- * Applies to a node of type either MODULE, SUBVIEW, PROJECT_VIEW
- */
- private static void setRootAndParentModule(ComponentDto res, PathAwareVisitor.Path<ComponentDtoHolder> path) {
- ComponentDto rootDto = path.root().getDto();
- res.setRootUuid(rootDto.uuid());
- res.setProjectUuid(rootDto.uuid());
-
- ComponentDto parentModule = path.parent().getDto();
- res.setUuidPath(formatUuidPathFromParent(parentModule));
- res.setModuleUuid(parentModule.uuid());
- res.setModuleUuidPath(parentModule.moduleUuidPath() + res.uuid() + UUID_PATH_SEPARATOR);
+ ComponentDto componentDto = new ComponentDto();
+ componentDto.setOrganizationUuid(analysisMetadataHolder.getOrganization().getUuid());
+ componentDto.setUuid(componentUuid);
+ componentDto.setDbKey(componentKey);
+ componentDto.setDeprecatedKey(componentKey);
+ componentDto.setMainBranchProjectUuid(mainBranchProjectUuid);
+ componentDto.setEnabled(true);
+ componentDto.setCreatedAt(new Date(system2.now()));
+
+ return componentDto;
+ }
+
+ /**
+ * Applies to a node of type either MODULE, SUBVIEW, PROJECT_VIEW
+ */
+ private void setRootAndParentModule(ComponentDto res, PathAwareVisitor.Path<ComponentDtoHolder> path) {
+ ComponentDto rootDto = path.root().getDto();
+ res.setRootUuid(rootDto.uuid());
+ res.setProjectUuid(rootDto.uuid());
+
+ ComponentDto parentModule = path.parent().getDto();
+ res.setUuidPath(formatUuidPathFromParent(parentModule));
+ res.setModuleUuid(parentModule.uuid());
+ res.setModuleUuidPath(parentModule.moduleUuidPath() + res.uuid() + UUID_PATH_SEPARATOR);
+ }
}
/**
.copyFrom(target)
.setBChanged(true);
}
- return Optional.ofNullable(update);
+ return ofNullable(update);
}
private static String getFileQualifier(Component component) {
private void execute(Component root) {
try (DbSession dbSession = dbClient.openSession(true)) {
IdUuidPair idUuidPair = new IdUuidPair(dbIdsRepository.getComponentId(root), root.getUuid());
- projectCleaner.purge(dbSession, idUuidPair, configRepository.getConfiguration(root), disabledComponentsHolder.getUuids());
+ projectCleaner.purge(dbSession, idUuidPair, configRepository.getConfiguration(), disabledComponentsHolder.getUuids());
dbSession.commit();
}
}
}
if (!baseMeasure.get().hasQualityGateStatus()) {
- LOGGER.warn(String.format("Previous alterStatus for project %s is not a supported value. Can not compute Quality Gate event", project.getKey()));
+ LOGGER.warn(String.format("Previous Quality gate status for project %s is not a supported value. Can not compute Quality Gate event", project.getKey()));
checkNewQualityGate(project, rawStatus);
return;
}
// Builds Component tree
LoadReportAnalysisMetadataHolderStep.class,
+ VerifyBillingStep.class,
BuildComponentTreeStep.class,
ValidateProjectStep.class,
public void visitProject(Component rawProject) {
this.rawProject = rawProject;
String rawProjectKey = rawProject.getKey();
- validateBranch();
validateIncremental(rawProjectKey);
validateNotIncrementalAndFirstAnalysis(rawProjectKey);
validateBatchKey(rawProject);
private void validateRootIsProject(Optional<ComponentDto> baseProject) {
if (baseProject.isPresent()) {
ComponentDto componentDto = baseProject.get();
+ // the scope field is verified for excluding the project copies generated by portfolios
if (!Qualifiers.PROJECT.equals(componentDto.qualifier()) || !Scopes.PROJECT.equals(componentDto.scope())) {
validationMessages.add(format("Component (uuid=%s, key=%s) is not a project", rawProject.getUuid(), rawProject.getKey()));
}
}
}
- private void validateBranch() {
- String branch = analysisMetadataHolder.getBranch();
- if (branch == null) {
- return;
- }
- if (!ComponentKeys.isValidBranch(branch)) {
- validationMessages.add(format("\"%s\" is not a valid branch name. "
- + "Allowed characters are alphanumeric, '-', '_', '.' and '/'.", branch));
- }
- }
-
private Optional<ComponentDto> loadBaseComponent(String rawComponentKey) {
ComponentDto baseComponent = baseModulesByKey.get(rawComponentKey);
if (baseComponent == null) {
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.computation.task.projectanalysis.step;
+
+import org.sonar.api.utils.MessageException;
+import org.sonar.server.computation.task.projectanalysis.analysis.AnalysisMetadataHolder;
+import org.sonar.server.computation.task.projectanalysis.analysis.Organization;
+import org.sonar.server.computation.task.step.ComputationStep;
+import org.sonar.server.organization.BillingValidations;
+import org.sonar.server.organization.BillingValidationsProxy;
+
+/**
+ * Verify that organization can execute analysis
+ */
+public class VerifyBillingStep implements ComputationStep {
+
+ private final AnalysisMetadataHolder analysisMetadata;
+ private final BillingValidations billingValidations;
+
+ public VerifyBillingStep(AnalysisMetadataHolder analysisMetadata, BillingValidationsProxy billingValidations) {
+ this.analysisMetadata = analysisMetadata;
+ this.billingValidations = billingValidations;
+ }
+
+ @Override
+ public void execute() {
+ try {
+ Organization organization = analysisMetadata.getOrganization();
+ BillingValidations.Organization billingOrganization = new BillingValidations.Organization(organization.getKey(), organization.getUuid());
+ billingValidations.checkOnProjectAnalysis(billingOrganization);
+ } catch (BillingValidations.BillingValidationsException e) {
+ throw MessageException.of(e.getMessage());
+ }
+ }
+
+ @Override
+ public String getDescription() {
+ return "Verify billing";
+ }
+}
import org.sonar.core.config.WebhookProperties;
import org.sonar.core.util.stream.MoreCollectors;
import org.sonar.server.computation.task.projectanalysis.component.ConfigurationRepository;
-import org.sonar.server.computation.task.projectanalysis.component.TreeRootHolder;
import static java.lang.String.format;
import static org.sonar.core.config.WebhookProperties.MAX_WEBHOOKS_PER_TYPE;
private static final Logger LOGGER = Loggers.get(WebhookPostTask.class);
- private final TreeRootHolder rootHolder;
private final ConfigurationRepository configRepository;
private final WebhookPayloadFactory payloadFactory;
private final WebhookCaller caller;
private final WebhookDeliveryStorage deliveryStorage;
- public WebhookPostTask(TreeRootHolder rootHolder, ConfigurationRepository settingsRepository, WebhookPayloadFactory payloadFactory,
+ public WebhookPostTask(ConfigurationRepository configRepository, WebhookPayloadFactory payloadFactory,
WebhookCaller caller, WebhookDeliveryStorage deliveryStorage) {
- this.rootHolder = rootHolder;
- this.configRepository = settingsRepository;
+ this.configRepository = configRepository;
this.payloadFactory = payloadFactory;
this.caller = caller;
this.deliveryStorage = deliveryStorage;
@Override
public void finished(ProjectAnalysis analysis) {
- Configuration config = configRepository.getConfiguration(rootHolder.getRoot());
+ Configuration config = configRepository.getConfiguration();
Iterable<String> webhookProps = Iterables.concat(
getWebhookProperties(config, WebhookProperties.GLOBAL_KEY),
package org.sonar.server.organization;
+import javax.annotation.Nullable;
+
public class BillingValidationsProxyImpl implements BillingValidationsProxy {
+ @Nullable
private final BillingValidationsExtension billingValidationsExtension;
- public BillingValidationsProxyImpl(BillingValidationsExtension billingValidationsExtension) {
- this.billingValidationsExtension = billingValidationsExtension;
+ public BillingValidationsProxyImpl(BillingValidationsExtension e) {
+ this.billingValidationsExtension = e;
}
// Used when no plugin is providing the extension
import org.apache.commons.lang.StringUtils;
import org.sonar.api.resources.Qualifiers;
import org.sonar.api.server.ServerSide;
-import org.sonar.core.component.ComponentKeys;
import org.sonar.core.permission.ProjectPermissions;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
public boolean wouldUserHaveScanPermissionWithDefaultTemplate(DbSession dbSession,
String organizationUuid, @Nullable Integer userId,
- @Nullable String branch, String projectKey,
- String qualifier) {
+ String projectKey, String qualifier) {
if (userSession.hasPermission(OrganizationPermission.SCAN, organizationUuid)) {
return true;
}
- String effectiveKey = ComponentKeys.createKey(projectKey, branch);
- ComponentDto dto = new ComponentDto().setOrganizationUuid(organizationUuid).setDbKey(effectiveKey).setQualifier(qualifier);
+ ComponentDto dto = new ComponentDto().setOrganizationUuid(organizationUuid).setDbKey(projectKey).setQualifier(qualifier);
PermissionTemplateDto template = findTemplate(dbSession, organizationUuid, dto);
if (template == null) {
return false;
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.project.ws;
+
+import java.util.Collection;
+import org.sonar.api.server.ws.Request;
+import org.sonar.api.server.ws.Response;
+import org.sonar.api.server.ws.WebService;
+import org.sonar.api.web.UserRole;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.component.BranchDto;
+import org.sonar.db.component.BranchKeyType;
+import org.sonar.db.component.ComponentDto;
+import org.sonar.server.user.UserSession;
+import org.sonar.server.ws.WsUtils;
+import org.sonarqube.ws.WsProjects;
+
+import static org.sonar.core.util.Protobuf.setNullable;
+
+public class BranchesAction implements ProjectsWsAction {
+
+ private static final String PROJECT_PARAM = "project";
+
+ private final DbClient dbClient;
+ private final UserSession userSession;
+
+ public BranchesAction(DbClient dbClient, UserSession userSession) {
+ this.dbClient = dbClient;
+ this.userSession = userSession;
+ }
+
+ @Override
+ public void define(WebService.NewController context) {
+ WebService.NewAction action = context.createAction("branches")
+ .setSince("6.6")
+ .setHandler(this);
+
+ action
+ .createParam(PROJECT_PARAM)
+ .setRequired(true);
+ }
+
+ @Override
+ public void handle(Request request, Response response) throws Exception {
+ String projectKey = request.mandatoryParam(PROJECT_PARAM);
+
+ try (DbSession dbSession = dbClient.openSession(false)) {
+ ComponentDto project = dbClient.componentDao().selectOrFailByKey(dbSession, projectKey);
+ userSession.checkComponentPermission(UserRole.USER, project);
+ Collection<BranchDto> branches = dbClient.branchDao().selectByComponent(dbSession, project);
+
+ WsProjects.BranchesWsResponse.Builder protobufResponse = WsProjects.BranchesWsResponse.newBuilder();
+ branches.stream()
+ .filter(b -> b.getKeeType().equals(BranchKeyType.BRANCH))
+ .forEach(b -> addToProtobuf(protobufResponse, b));
+ WsUtils.writeProtobuf(protobufResponse.build(), request, response);
+ }
+ }
+
+ private static void addToProtobuf(WsProjects.BranchesWsResponse.Builder response, BranchDto branch) {
+ WsProjects.BranchesWsResponse.Branch.Builder builder = response.addBranchesBuilder();
+ setNullable(branch.getKey(), builder::setName);
+ builder.setIsMain(branch.isMain());
+ builder.setType(WsProjects.BranchesWsResponse.BranchType.valueOf(branch.getBranchType().name()));
+ builder.build();
+ }
+}
ProjectsWs.class,
CreateAction.class,
IndexAction.class,
+ BranchesAction.class,
BulkDeleteAction.class,
DeleteAction.class,
UpdateKeyAction.class,
import static org.assertj.core.api.Assertions.tuple;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.argThat;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
mockSuccessfulPrepareSubmitCall();
ComponentDto project = newPrivateProjectDto(db.getDefaultOrganization(), PROJECT_UUID).setDbKey(PROJECT_KEY);
when(componentUpdater.create(any(DbSession.class), any(NewComponent.class), eq(null))).thenReturn(project);
- when(permissionTemplateService.wouldUserHaveScanPermissionWithDefaultTemplate(any(DbSession.class), eq(defaultOrganizationUuid), anyInt(), anyString(),
- eq(PROJECT_KEY), eq(Qualifiers.PROJECT)))
- .thenReturn(true);
+ when(permissionTemplateService.wouldUserHaveScanPermissionWithDefaultTemplate(any(DbSession.class), eq(defaultOrganizationUuid), anyInt(), eq(PROJECT_KEY),
+ eq(Qualifiers.PROJECT)))
+ .thenReturn(true);
Map<String, String> taskCharacteristics = new HashMap<>();
taskCharacteristics.put("incremental", "true");
mockSuccessfulPrepareSubmitCall();
ComponentDto createdProject = newPrivateProjectDto(organization, PROJECT_UUID).setDbKey(PROJECT_KEY);
when(componentUpdater.create(any(DbSession.class), any(NewComponent.class), eq(null))).thenReturn(createdProject);
- when(permissionTemplateService.wouldUserHaveScanPermissionWithDefaultTemplate(any(DbSession.class), eq(organization.getUuid()), anyInt(), anyString(),
- eq(PROJECT_KEY), eq(Qualifiers.PROJECT)))
- .thenReturn(true);
+ when(
+ permissionTemplateService.wouldUserHaveScanPermissionWithDefaultTemplate(any(DbSession.class), eq(organization.getUuid()), anyInt(), eq(PROJECT_KEY), eq(Qualifiers.PROJECT)))
+ .thenReturn(true);
when(permissionTemplateService.hasDefaultTemplateWithPermissionOnProjectCreator(any(DbSession.class), eq(organization.getUuid()), any(ComponentDto.class))).thenReturn(true);
underTest.submit(organization.getKey(), PROJECT_KEY, null, PROJECT_NAME, IOUtils.toInputStream("{binary}"));
mockSuccessfulPrepareSubmitCall();
ComponentDto createdProject = newPrivateProjectDto(db.getDefaultOrganization(), PROJECT_UUID).setDbKey(PROJECT_KEY);
when(componentUpdater.create(any(DbSession.class), any(NewComponent.class), eq(null))).thenReturn(createdProject);
- when(permissionTemplateService.wouldUserHaveScanPermissionWithDefaultTemplate(any(DbSession.class), eq(defaultOrganizationUuid), anyInt(), anyString(),
+ when(permissionTemplateService.wouldUserHaveScanPermissionWithDefaultTemplate(any(DbSession.class), eq(defaultOrganizationUuid), anyInt(),
eq(PROJECT_KEY), eq(Qualifiers.PROJECT)))
- .thenReturn(true);
+ .thenReturn(true);
when(permissionTemplateService.hasDefaultTemplateWithPermissionOnProjectCreator(any(DbSession.class), eq(defaultOrganizationUuid), any(ComponentDto.class))).thenReturn(false);
underTest.submit(defaultOrganizationKey, PROJECT_KEY, null, PROJECT_NAME, IOUtils.toInputStream("{binary}"));
mockSuccessfulPrepareSubmitCall();
ComponentDto project = newPrivateProjectDto(db.getDefaultOrganization(), PROJECT_UUID).setDbKey(PROJECT_KEY);
when(componentUpdater.create(any(DbSession.class), any(NewComponent.class), eq(null))).thenReturn(project);
- when(permissionTemplateService.wouldUserHaveScanPermissionWithDefaultTemplate(any(DbSession.class), eq(defaultOrganizationUuid), anyInt(), anyString(),
+ when(permissionTemplateService.wouldUserHaveScanPermissionWithDefaultTemplate(any(DbSession.class), eq(defaultOrganizationUuid), anyInt(),
eq(PROJECT_KEY), eq(Qualifiers.PROJECT)))
- .thenReturn(true);
+ .thenReturn(true);
underTest.submit(defaultOrganizationKey, PROJECT_KEY, null, PROJECT_NAME, IOUtils.toInputStream("{binary}"));
@Rule
public ExpectedException thrown = ExpectedException.none();
- static final long ID = 10;
- static final String UUID = "uuid ";
- static final long CREATED_AT = 123456789L;
+ private static final long ID = 10;
+ private static final String UUID = "uuid ";
+ private static final long CREATED_AT = 123456789L;
@Test
public void build_snapshot() throws Exception {
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.sonar.db.organization.OrganizationDto;
+import org.sonar.server.computation.task.projectanalysis.component.MainBranchImpl;
import static org.assertj.core.api.Assertions.assertThat;
public void set_branch() {
AnalysisMetadataHolderImpl underTest = new AnalysisMetadataHolderImpl();
- underTest.setBranch("origin/master");
+ underTest.setBranch(new MainBranchImpl("master"));
- assertThat(underTest.getBranch()).isEqualTo("origin/master");
+ assertThat(underTest.getBranch().get().getName()).hasValue("master");
}
@Test
- public void set_no_branch() {
+ public void getBranch_throws_ISE_when_holder_is_not_initialized() {
+ expectedException.expect(IllegalStateException.class);
+ expectedException.expectMessage("Branch has not been set");
+
+ new AnalysisMetadataHolderImpl().getBranch();
+ }
+
+ @Test
+ public void setBranch_throws_ISE_when_called_twice() {
AnalysisMetadataHolderImpl underTest = new AnalysisMetadataHolderImpl();
+ underTest.setBranch(new MainBranchImpl("master"));
- underTest.setBranch(null);
+ expectedException.expect(IllegalStateException.class);
+ expectedException.expectMessage("Branch has already been set");
+ underTest.setBranch(new MainBranchImpl("master"));
+ }
+
+ @Test
+ public void set_and_get_project() {
+ AnalysisMetadataHolderImpl underTest = new AnalysisMetadataHolderImpl();
+
+ Project project = new Project("U", "K", "N");
+ underTest.setProject(project);
- assertThat(underTest.getBranch()).isNull();
+ assertThat(underTest.getProject()).isSameAs(project);
}
@Test
- public void getBranch_throws_ISE_when_holder_is_not_initialized() {
+ public void getProject_throws_ISE_when_holder_is_not_initialized() {
expectedException.expect(IllegalStateException.class);
- expectedException.expectMessage("Branch has not been set");
+ expectedException.expectMessage("Project has not been set");
- new AnalysisMetadataHolderImpl().getBranch();
+ new AnalysisMetadataHolderImpl().getProject();
}
@Test
- public void setBranch_throws_ISE_when_called_twice() {
+ public void setProject_throws_ISE_when_called_twice() {
AnalysisMetadataHolderImpl underTest = new AnalysisMetadataHolderImpl();
- underTest.setBranch("origin/master");
+ underTest.setProject(new Project("U", "K", "N"));
expectedException.expect(IllegalStateException.class);
- expectedException.expectMessage("Branch has already been set");
- underTest.setBranch("origin/master");
+ expectedException.expectMessage("Project has already been set");
+ underTest.setProject(new Project("U", "K", "N"));
}
@Test
import java.util.Date;
import java.util.Map;
+import java.util.Optional;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import org.junit.rules.ExternalResource;
private final InitializedProperty<Boolean> crossProjectDuplicationEnabled = new InitializedProperty<>();
- private final InitializedProperty<String> branch = new InitializedProperty<>();
+ private final InitializedProperty<Branch> branch = new InitializedProperty<>();
+
+ private final InitializedProperty<Project> project = new InitializedProperty<>();
private final InitializedProperty<Integer> rootComponentRef = new InitializedProperty<>();
}
@Override
- public AnalysisMetadataHolderRule setBranch(@Nullable String branch) {
+ public AnalysisMetadataHolderRule setBranch(@Nullable Branch branch) {
this.branch.setProperty(branch);
return this;
}
@Override
- public String getBranch() {
+ public Optional<Branch> getBranch() {
checkState(branch.isInitialized(), "Branch has not been set");
- return branch.getProperty();
+ return Optional.ofNullable(branch.getProperty());
+ }
+
+ @Override
+ public AnalysisMetadataHolderRule setProject(Project p) {
+ this.project.setProperty(p);
+ return this;
+ }
+
+ @Override
+ public Project getProject() {
+ checkState(project.isInitialized(), "Project has not been set");
+ return project.getProperty();
}
@Override
package org.sonar.server.computation.task.projectanalysis.analysis;
import java.util.Map;
+import java.util.Optional;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import org.junit.rules.ExternalResource;
}
@Override
- public MutableAnalysisMetadataHolder setOrganization(Organization organization) {
- return delegate.setOrganization(organization);
+ public MutableAnalysisMetadataHolderRule setOrganization(Organization organization) {
+ delegate.setOrganization(organization);
+ return this;
}
@Override
}
@Override
- public String getBranch() {
+ public Optional<Branch> getBranch() {
return delegate.getBranch();
}
@Override
- public MutableAnalysisMetadataHolderRule setBranch(@Nullable String branch) {
+ public MutableAnalysisMetadataHolderRule setBranch(Branch branch) {
delegate.setBranch(branch);
return this;
}
+ @Override
+ public MutableAnalysisMetadataHolderRule setProject(@Nullable Project project) {
+ delegate.setProject(project);
+ return this;
+ }
+
+ @Override
+ public Project getProject() {
+ return delegate.getProject();
+ }
+
@Override
public MutableAnalysisMetadataHolderRule setRootComponentRef(int rootComponentRef) {
delegate.setRootComponentRef(rootComponentRef);
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.computation.task.projectanalysis.analysis;
+
+import org.junit.Test;
+import org.sonar.server.computation.task.projectanalysis.component.Component;
+import org.sonar.server.computation.task.projectanalysis.component.ReportComponent;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.sonar.server.computation.task.projectanalysis.component.Component.Type.PROJECT;
+
+public class ProjectTest {
+ @Test
+ public void test_bean() {
+ Project project = new Project("U1", "K1", "N1");
+
+ assertThat(project.getUuid()).isEqualTo("U1");
+ assertThat(project.getKey()).isEqualTo("K1");
+ assertThat(project.getName()).isEqualTo("N1");
+
+ assertThat(project.toString()).isEqualTo("Project{uuid='U1', key='K1', name='N1'}");
+ }
+
+ @Test
+ public void test_equals_and_hashCode() {
+ Project project1 = new Project("U1", "K1", "N1");
+ Project project1bis = new Project("U1", "K1", "N1");
+ Project project2 = new Project("U2", "K2", project1.getName() /* same name */);
+
+ assertThat(project1.equals(project1)).isTrue();
+ assertThat(project1.equals(project1bis)).isTrue();
+ assertThat(project1.equals(project2)).isFalse();
+ assertThat(project1.equals("U1")).isFalse();
+
+ assertThat(project1.hashCode()).isEqualTo(project1.hashCode());
+ assertThat(project1.hashCode()).isEqualTo(project1bis.hashCode());
+ }
+
+ @Test
+ public void test_copyOf() {
+ Component root = ReportComponent.builder(PROJECT, 1).setKey("ROOT").build();
+
+ Project project = Project.copyOf(root);
+ assertThat(project.getUuid()).isEqualTo(root.getUuid()).isNotNull();
+ assertThat(project.getKey()).isEqualTo(root.getKey()).isNotNull();
+ assertThat(project.getName()).isEqualTo(root.getName()).isNotNull();
+ }
+}
public void get_string_settings() throws Exception {
MapSettings serverSettings = new MapSettings();
serverSettings.setProperty("prop", "value");
- when(settingsRepository.getConfiguration(FILE_1)).thenReturn(serverSettings.asConfig());
+ when(settingsRepository.getConfiguration()).thenReturn(serverSettings.asConfig());
MeasureComputerContextImpl underTest = newContext(FILE_1_REF);
assertThat(underTest.getSettings().getString("prop")).isEqualTo("value");
public void get_string_array_settings() throws Exception {
MapSettings serverSettings = new MapSettings();
serverSettings.setProperty("prop", "1,3.4,8,50");
- when(settingsRepository.getConfiguration(FILE_1)).thenReturn(serverSettings.asConfig());
+ when(settingsRepository.getConfiguration()).thenReturn(serverSettings.asConfig());
MeasureComputerContextImpl underTest = newContext(FILE_1_REF);
assertThat(underTest.getSettings().getStringArray("prop")).containsExactly("1", "3.4", "8", "50");
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.computation.task.projectanalysis.component;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.api.utils.MessageException;
+import org.sonar.scanner.protocol.output.ScannerReport;
+import org.sonar.server.computation.task.projectanalysis.analysis.AnalysisMetadataHolderRule;
+import org.sonar.server.computation.task.projectanalysis.analysis.Branch;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+
+
+public class BranchLoaderTest {
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
+ @Rule
+ public AnalysisMetadataHolderRule metadataHolder = new AnalysisMetadataHolderRule();
+
+ @Test
+ public void throw_ME_if_both_branch_properties_are_set() {
+ ScannerReport.Metadata metadata = ScannerReport.Metadata.newBuilder()
+ .setDeprecatedBranch("foo")
+ .setBranchName("bar")
+ .build();
+
+ expectedException.expect(MessageException.class);
+ expectedException.expectMessage("Properties sonar.branch and sonar.branch.name can't be set together");
+
+ new BranchLoader(metadataHolder).load(metadata);
+ }
+
+ @Test
+ public void regular_analysis_of_project_is_enabled_if_delegate_is_absent() {
+ ScannerReport.Metadata metadata = ScannerReport.Metadata.newBuilder()
+ .build();
+
+ new BranchLoader(metadataHolder).load(metadata);
+
+ assertThat(metadataHolder.getBranch()).isPresent();
+
+ Branch branch = metadataHolder.getBranch().get();
+ assertThat(branch.isMain()).isTrue();
+ assertThat(branch.getName()).isEmpty();
+ }
+
+ @Test
+ public void default_support_of_branches_is_enabled_if_delegate_is_absent() {
+ ScannerReport.Metadata metadata = ScannerReport.Metadata.newBuilder()
+ .setDeprecatedBranch("foo")
+ .build();
+
+ new BranchLoader(metadataHolder).load(metadata);
+
+ assertThat(metadataHolder.getBranch()).isPresent();
+
+ Branch branch = metadataHolder.getBranch().get();
+ assertThat(branch.isMain()).isTrue();
+ assertThat(branch.getName()).hasValue("foo");
+ }
+
+ @Test
+ public void default_support_of_branches_is_enabled_if_delegate_is_present() {
+ ScannerReport.Metadata metadata = ScannerReport.Metadata.newBuilder()
+ .setDeprecatedBranch("foo")
+ .build();
+
+ FakeDelegate delegate = new FakeDelegate();
+ new BranchLoader(metadataHolder, delegate).load(metadata);
+
+ assertThat(metadataHolder.getBranch()).isPresent();
+
+ Branch branch = metadataHolder.getBranch().get();
+ assertThat(branch.isMain()).isTrue();
+ assertThat(branch.getName()).hasValue("foo");
+ }
+
+ private class FakeDelegate implements BranchLoaderDelegate {
+ Branch branch = mock(Branch.class);
+
+ @Override
+ public void load(ScannerReport.Metadata metadata) {
+ metadataHolder.setBranch(branch);
+ }
+ }
+}
public class ComponentFunctionsTest {
- public static final int SOME_INT = new Random().nextInt();
-
- @Test(expected = NullPointerException.class)
- public void toReportRef_throws_NPE_if_Component_is_null() {
- toReportRef().apply(null);
- }
+ private static final int SOME_INT = new Random().nextInt();
@Test(expected = IllegalStateException.class)
public void toReportRef_throws_ISE_if_Component_has_no_ReportAttributes() {
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2017 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.server.computation.task.projectanalysis.component;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Supplier;
-import java.util.Arrays;
-import java.util.EnumSet;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.function.Function;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.junit.rules.ExternalResource;
-import org.sonar.db.component.ComponentDto;
-import org.sonar.db.component.SnapshotDto;
-import org.sonar.scanner.protocol.output.ScannerReport;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.fail;
-import static org.sonar.scanner.protocol.output.ScannerReport.Component.newBuilder;
-import static org.sonar.scanner.protocol.output.ScannerReport.Component.ComponentType.DIRECTORY;
-import static org.sonar.scanner.protocol.output.ScannerReport.Component.ComponentType.FILE;
-import static org.sonar.scanner.protocol.output.ScannerReport.Component.ComponentType.MODULE;
-import static org.sonar.scanner.protocol.output.ScannerReport.Component.ComponentType.PROJECT;
-import static org.sonar.scanner.protocol.output.ScannerReport.Component.ComponentType.UNRECOGNIZED;
-import static org.sonar.scanner.protocol.output.ScannerReport.Component.ComponentType.UNSET;
-import static org.sonar.server.computation.task.projectanalysis.component.ComponentRootBuilder.createFileAttributes;
-import static org.sonar.server.computation.task.projectanalysis.component.ComponentRootBuilder.createOtherReportAttributes;
-import static org.sonar.server.computation.task.projectanalysis.component.ComponentRootBuilder.createProjectReportAttributes;
-import static org.sonar.server.computation.task.projectanalysis.component.ComponentVisitor.Order.PRE_ORDER;
-
-public class ComponentRootBuilderTest {
-
- private static final Function<String, String> SIMPLE_UUID_GENERATOR = (componentKey) -> componentKey + "_uuid";
- private static final String NO_BRANCH = null;
- private static final String PROJECT_KEY = "this is the key";
- private static final String MODULE_KEY = "module key";
- private static final String DIRECTORY_PATH = "directory path";
- private static final String DIRECTORY_KEY = MODULE_KEY + ":" + DIRECTORY_PATH;
- private static final String FILE_PATH = "file path";
- private static final String FILE_KEY = MODULE_KEY + ":" + FILE_PATH;
- private static final ComponentDto PROJECT_DTO = new ComponentDto().setName("name in db");
- private static final Supplier<Optional<ComponentDto>> NO_COMPONENT_DTO_FOR_PROJECT = Optional::absent;
- private static final Function<String, Optional<SnapshotDto>> NO_BASEANALYSIS = (projectUuid) -> Optional.absent();
- private static final Supplier<Optional<ComponentDto>> COMPONENT_DTO_FOR_PROJECT = () -> Optional.of(PROJECT_DTO);
- private static final EnumSet<ScannerReport.Component.ComponentType> REPORT_TYPES = EnumSet.of(
- PROJECT, MODULE, DIRECTORY, FILE);
- private static final String PROJECT_UUID = "project uuid";
- private static final String DEFAULT_VERSION = "not provided";
-
- @Rule
- public ExpectedException expectedException = ExpectedException.none();
-
- @Rule
- public ScannerComponentProvider scannerComponentProvider = new ScannerComponentProvider();
-
- private ComponentRootBuilder underTest = new ComponentRootBuilder(NO_BRANCH, SIMPLE_UUID_GENERATOR, scannerComponentProvider, NO_COMPONENT_DTO_FOR_PROJECT, NO_BASEANALYSIS);
-
- @Test
- public void build_throws_IAE_for_all_types_but_PROJECT_MODULE_DIRECTORY_FILE() {
- Arrays.stream(ScannerReport.Component.ComponentType.values())
- .filter((type) -> type != UNRECOGNIZED)
- .filter((type) -> !REPORT_TYPES.contains(type))
- .forEach(
- (type) -> {
- ScannerReport.Component component = newBuilder().setType(type).build();
- try {
- underTest.build(component, "don't care");
- fail("Should have thrown a IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- assertThat(e).hasMessage("Unsupported component type '" + type + "'");
- }
- });
- }
-
- @Test
- public void name_of_project_is_name_in_Scanner_Component_when_set() {
- String expected = "the name";
- Component root = underTest.build(newBuilder().setType(PROJECT).setName(expected).build(), PROJECT_KEY);
- assertThat(root.getName()).isEqualTo(expected);
- }
-
- @Test
- public void name_of_project_is_name_in_Scanner_Component_when_set_even_if_there_is_a_ComponentDto() {
- String expected = "the name";
- Component root = new ComponentRootBuilder(NO_BRANCH, SIMPLE_UUID_GENERATOR, scannerComponentProvider, COMPONENT_DTO_FOR_PROJECT, NO_BASEANALYSIS)
- .build(newBuilder().setType(PROJECT).setName(expected).build(), PROJECT_KEY);
- assertThat(root.getName()).isEqualTo(expected);
- }
-
- @Test
- public void name_of_project_is_specified_key_when_name_is_unset_in_Scanner_Component_and_there_is_no_ComponentDto() {
- Component root = underTest.build(newBuilder().setType(PROJECT).build(), PROJECT_KEY);
- assertThat(root.getName()).isEqualTo(PROJECT_KEY);
- }
-
- @Test
- public void name_of_project_is_specified_key_when_name_is_empty_in_Scanner_Component_and_there_is_no_ComponentDto() {
- Component root = underTest.build(newBuilder().setType(PROJECT).setName("").build(), PROJECT_KEY);
-
- assertThat(root.getName()).isEqualTo(PROJECT_KEY);
- }
-
- @Test
- public void name_of_project_is_name_of_ComponentDto_when_name_is_unset_in_Scanner_Component_and_there_is_a_ComponentDto() {
- Component root = new ComponentRootBuilder(NO_BRANCH, SIMPLE_UUID_GENERATOR, scannerComponentProvider, COMPONENT_DTO_FOR_PROJECT, NO_BASEANALYSIS)
- .build(newBuilder().setType(PROJECT).build(), PROJECT_KEY);
-
- assertThat(root.getName()).isEqualTo(PROJECT_DTO.name());
- }
-
- @Test
- public void name_of_project_is_name_of_ComponentDto_when_name_is_empty_in_Scanner_Component_and_there_is_a_ComponentDto() {
- Component root = new ComponentRootBuilder(NO_BRANCH, SIMPLE_UUID_GENERATOR, scannerComponentProvider, COMPONENT_DTO_FOR_PROJECT, NO_BASEANALYSIS)
- .build(newBuilder().setType(PROJECT).setName("").build(), PROJECT_KEY);
-
- assertThat(root.getName()).isEqualTo(PROJECT_DTO.name());
- }
-
- @Test
- public void name_of_module_directory_and_file_contains_branch_when_non_empty() {
- ScannerReport.Component project = newBuilder().setType(PROJECT).setRef(1).addChildRef(2).build();
- scannerComponentProvider.add(newBuilder().setRef(2).setType(MODULE).setKey(MODULE_KEY).addChildRef(3));
- scannerComponentProvider.add(newBuilder().setRef(3).setType(DIRECTORY).setPath(DIRECTORY_PATH).addChildRef(4));
- scannerComponentProvider.add(newBuilder().setRef(4).setType(FILE).setPath(FILE_PATH).setLines(1));
-
- String branch = "BRANCH";
- ComponentRootBuilder builder = new ComponentRootBuilder(branch, SIMPLE_UUID_GENERATOR, scannerComponentProvider, NO_COMPONENT_DTO_FOR_PROJECT, NO_BASEANALYSIS);
-
- Component root = builder.build(project, PROJECT_KEY);
- assertThat(root.getKey()).isEqualTo(PROJECT_KEY);
- assertThat(root.getChildren()).hasSize(1);
- Component module = root.getChildren().iterator().next();
- assertThat(module.getKey()).isEqualTo(MODULE_KEY + ":" + branch);
- assertThat(module.getChildren()).hasSize(1);
- Component directory = module.getChildren().iterator().next();
- assertThat(directory.getKey()).isEqualTo(module.getKey() + ":" + DIRECTORY_PATH);
- assertThat(directory.getChildren()).hasSize(1);
- Component file = directory.getChildren().iterator().next();
- assertThat(file.getKey()).isEqualTo(module.getKey() + ":" + FILE_PATH);
- assertThat(file.getChildren()).isEmpty();
- }
-
- @Test
- public void name_of_module_directory_and_file_is_key_of_Scanner_Component_when_name_is_unset() {
- ScannerReport.Component project = newBuilder().setType(PROJECT).setRef(1).addChildRef(2).build();
- scannerComponentProvider.add(newBuilder().setRef(2).setType(MODULE).setKey(MODULE_KEY).addChildRef(3));
- scannerComponentProvider.add(newBuilder().setRef(3).setType(DIRECTORY).setPath(DIRECTORY_PATH).addChildRef(4));
- scannerComponentProvider.add(newBuilder().setRef(4).setType(FILE).setPath(FILE_PATH).setLines(1));
-
- Component root = underTest.build(project, PROJECT_KEY);
- assertThat(root.getKey()).isEqualTo(PROJECT_KEY);
- Component module = root.getChildren().iterator().next();
- assertThat(module.getName()).isEqualTo(MODULE_KEY);
- Component directory = module.getChildren().iterator().next();
- assertThat(directory.getName()).isEqualTo(module.getKey() + ":" + DIRECTORY_PATH);
- Component file = directory.getChildren().iterator().next();
- assertThat(file.getName()).isEqualTo(module.getKey() + ":" + FILE_PATH);
- }
-
- @Test
- public void name_of_module_directory_and_file_is_key_of_Scanner_Component_when_name_is_empty() {
- ScannerReport.Component project = newBuilder().setType(PROJECT).setRef(1).setName("").addChildRef(2).build();
- scannerComponentProvider.add(newBuilder().setRef(2).setType(MODULE).setKey(MODULE_KEY).setName("").addChildRef(3));
- scannerComponentProvider.add(newBuilder().setRef(3).setType(DIRECTORY).setPath(DIRECTORY_PATH).setName("").addChildRef(4));
- scannerComponentProvider.add(newBuilder().setRef(4).setType(FILE).setPath(FILE_PATH).setName("").setLines(1));
-
- Component root = underTest.build(project, PROJECT_KEY);
- assertThat(root.getKey()).isEqualTo(PROJECT_KEY);
- Component module = root.getChildren().iterator().next();
- assertThat(module.getName()).isEqualTo(MODULE_KEY);
- Component directory = module.getChildren().iterator().next();
- assertThat(directory.getName()).isEqualTo(module.getKey() + ":" + DIRECTORY_PATH);
- Component file = directory.getChildren().iterator().next();
- assertThat(file.getName()).isEqualTo(module.getKey() + ":" + FILE_PATH);
- }
-
- @Test
- public void name_of_module_directory_and_files_includes_name_of_closest_module() {
- ScannerReport.Component project = newBuilder().setType(PROJECT).setRef(1).addChildRef(11).addChildRef(21).addChildRef(31).build();
- scannerComponentProvider.add(newBuilder().setRef(11).setType(MODULE).setKey("module 1").addChildRef(12).addChildRef(22).addChildRef(32));
- scannerComponentProvider.add(newBuilder().setRef(12).setType(MODULE).setKey("module 2").addChildRef(13).addChildRef(23).addChildRef(33));
- scannerComponentProvider.add(newBuilder().setRef(13).setType(MODULE).setKey("module 3").addChildRef(24).addChildRef(34));
- scannerComponentProvider.add(newBuilder().setRef(21).setType(DIRECTORY).setPath("directory in project").addChildRef(35));
- scannerComponentProvider.add(newBuilder().setRef(22).setType(DIRECTORY).setPath("directory in module 1").addChildRef(36));
- scannerComponentProvider.add(newBuilder().setRef(23).setType(DIRECTORY).setPath("directory in module 2").addChildRef(37));
- scannerComponentProvider.add(newBuilder().setRef(24).setType(DIRECTORY).setPath("directory in module 3").addChildRef(38));
- scannerComponentProvider.add(newBuilder().setRef(31).setType(FILE).setPath("file in project").setLines(1));
- scannerComponentProvider.add(newBuilder().setRef(32).setType(FILE).setPath("file in module 1").setLines(1));
- scannerComponentProvider.add(newBuilder().setRef(33).setType(FILE).setPath("file in module 2").setLines(1));
- scannerComponentProvider.add(newBuilder().setRef(34).setType(FILE).setPath("file in module 3").setLines(1));
- scannerComponentProvider.add(newBuilder().setRef(35).setType(FILE).setPath("file in directory in project").setLines(1));
- scannerComponentProvider.add(newBuilder().setRef(36).setType(FILE).setPath("file in directory in module 1").setLines(1));
- scannerComponentProvider.add(newBuilder().setRef(37).setType(FILE).setPath("file in directory in module 2").setLines(1));
- scannerComponentProvider.add(newBuilder().setRef(38).setType(FILE).setPath("file in directory in module 3").setLines(1));
-
- Component root = underTest.build(project, PROJECT_KEY);
- Map<Integer, Component> componentsByRef = indexComponentByRef(root);
- assertThat(componentsByRef.get(11).getKey()).isEqualTo("module 1");
- assertThat(componentsByRef.get(12).getKey()).isEqualTo("module 2");
- assertThat(componentsByRef.get(13).getKey()).isEqualTo("module 3");
- assertThat(componentsByRef.get(21).getKey()).startsWith(PROJECT_KEY + ":");
- assertThat(componentsByRef.get(22).getKey()).startsWith("module 1" + ":");
- assertThat(componentsByRef.get(23).getKey()).startsWith("module 2" + ":");
- assertThat(componentsByRef.get(24).getKey()).startsWith("module 3" + ":");
- assertThat(componentsByRef.get(31).getKey()).startsWith(PROJECT_KEY + ":");
- assertThat(componentsByRef.get(32).getKey()).startsWith("module 1" + ":");
- assertThat(componentsByRef.get(33).getKey()).startsWith("module 2" + ":");
- assertThat(componentsByRef.get(34).getKey()).startsWith("module 3" + ":");
- assertThat(componentsByRef.get(35).getKey()).startsWith(PROJECT_KEY + ":");
- assertThat(componentsByRef.get(36).getKey()).startsWith("module 1" + ":");
- assertThat(componentsByRef.get(37).getKey()).startsWith("module 2" + ":");
- assertThat(componentsByRef.get(38).getKey()).startsWith("module 3" + ":");
- }
-
- @Test
- public void version_of_project_is_set_to_default_value_when_unset_in_Scanner_Component_and_no_base_analysis() {
- ScannerReport.Component project = newBuilder().setType(PROJECT).build();
-
- ComponentRootBuilder builder = new ComponentRootBuilder(NO_BRANCH, SIMPLE_UUID_GENERATOR, scannerComponentProvider,
- NO_COMPONENT_DTO_FOR_PROJECT, this::noBaseAnalysisButValidateProjectUuidArgument);
-
- Component root = builder.build(project, PROJECT_KEY);
- assertThat(root.getReportAttributes().getVersion()).isEqualTo(DEFAULT_VERSION);
- }
-
- @Test
- public void version_of_project_is_set_to_default_value_when_empty_in_Scanner_Component_and_no_base_analysis() {
- ScannerReport.Component project = newBuilder().setType(PROJECT).setVersion("").build();
-
- ComponentRootBuilder builder = new ComponentRootBuilder(NO_BRANCH, SIMPLE_UUID_GENERATOR, scannerComponentProvider,
- NO_COMPONENT_DTO_FOR_PROJECT, this::noBaseAnalysisButValidateProjectUuidArgument);
-
- Component root = builder.build(project, PROJECT_KEY);
- assertThat(root.getReportAttributes().getVersion()).isEqualTo(DEFAULT_VERSION);
- }
-
- private Optional<SnapshotDto> noBaseAnalysisButValidateProjectUuidArgument(String projectUuid) {
- assertThat(projectUuid).isEqualTo(SIMPLE_UUID_GENERATOR.apply(PROJECT_KEY));
- return Optional.absent();
- }
-
- @Test
- public void version_of_project_is_set_to_base_analysis_version_when_unset_in_Scanner_Component_and_base_analysis_has_a_version() {
- ScannerReport.Component project = newBuilder().setType(PROJECT).build();
-
- String expected = "some version";
- ComponentRootBuilder builder = new ComponentRootBuilder(NO_BRANCH, SIMPLE_UUID_GENERATOR, scannerComponentProvider,
- NO_COMPONENT_DTO_FOR_PROJECT,
- (projectUuid) -> {
- assertThat(projectUuid).isEqualTo(SIMPLE_UUID_GENERATOR.apply(PROJECT_KEY));
- return Optional.of(new SnapshotDto().setVersion(expected));
- });
-
- Component root = builder.build(project, PROJECT_KEY);
- assertThat(root.getReportAttributes().getVersion()).isEqualTo(expected);
- }
-
- @Test
- public void version_of_project_is_set_to_base_analysis_version_when_empty_in_Scanner_Component_and_base_analysis_has_a_version() {
- ScannerReport.Component project = newBuilder().setType(PROJECT).setVersion("").build();
-
- String expected = "some version";
- ComponentRootBuilder builder = new ComponentRootBuilder(NO_BRANCH, SIMPLE_UUID_GENERATOR, scannerComponentProvider, NO_COMPONENT_DTO_FOR_PROJECT,
- (projectUuid) -> {
- assertThat(projectUuid).isEqualTo(SIMPLE_UUID_GENERATOR.apply(PROJECT_KEY));
- return Optional.of(new SnapshotDto().setVersion(expected));
- });
-
- Component root = builder.build(project, PROJECT_KEY);
- assertThat(root.getReportAttributes().getVersion()).isEqualTo(expected);
- }
-
- @Test
- public void version_of_project_is_set_to_default_value_when_unset_in_Scanner_Component_and_base_analysis_has_no_version() {
- ScannerReport.Component project = newBuilder().setType(PROJECT).build();
-
- ComponentRootBuilder builder = new ComponentRootBuilder(NO_BRANCH, SIMPLE_UUID_GENERATOR, scannerComponentProvider,
- NO_COMPONENT_DTO_FOR_PROJECT,
- (projectUuid) -> {
- assertThat(projectUuid).isEqualTo(SIMPLE_UUID_GENERATOR.apply(PROJECT_KEY));
- return Optional.of(new SnapshotDto());
- });
-
- Component root = builder.build(project, PROJECT_KEY);
- assertThat(root.getReportAttributes().getVersion()).isEqualTo(DEFAULT_VERSION);
- }
-
- @Test
- public void version_of_project_is_set_to_default_value_when_empty_in_Scanner_Component_and_base_analysis_has_no_version() {
- ScannerReport.Component project = newBuilder().setType(PROJECT).setVersion("").build();
-
- ComponentRootBuilder builder = new ComponentRootBuilder(NO_BRANCH, SIMPLE_UUID_GENERATOR, scannerComponentProvider, NO_COMPONENT_DTO_FOR_PROJECT,
- (projectUuid) -> {
- assertThat(projectUuid).isEqualTo(SIMPLE_UUID_GENERATOR.apply(PROJECT_KEY));
- return Optional.of(new SnapshotDto());
- });
-
- Component root = builder.build(project, PROJECT_KEY);
- assertThat(root.getReportAttributes().getVersion()).isEqualTo(DEFAULT_VERSION);
- }
-
- @Test
- public void version_of_project_is_set_to_value_in_Scanner_Component_when_set() {
- String expected = "some version";
- ScannerReport.Component project = newBuilder().setType(PROJECT).setVersion(expected).build();
- ComponentRootBuilder builder = new ComponentRootBuilder(NO_BRANCH, SIMPLE_UUID_GENERATOR, scannerComponentProvider, NO_COMPONENT_DTO_FOR_PROJECT,
- this::noBaseAnalysisButEnsureIsNotCalled);
-
- assertThat(builder.build(project, PROJECT_KEY).getReportAttributes().getVersion()).isEqualTo(expected);
- }
-
- private Optional<SnapshotDto> noBaseAnalysisButEnsureIsNotCalled(String projectUuid) {
- fail("baseAnalysis provider should not have been called");
- return Optional.absent();
- }
-
- @Test
- public void uuid_is_value_from_uuid_supplier_for_project_module_directory_and_file() {
- ScannerReport.Component project = newBuilder().setType(PROJECT).setRef(1).addChildRef(2).build();
- scannerComponentProvider.add(newBuilder().setRef(2).setType(MODULE).setKey(MODULE_KEY).addChildRef(3));
- scannerComponentProvider.add(newBuilder().setRef(3).setType(DIRECTORY).setPath(DIRECTORY_PATH).addChildRef(4));
- scannerComponentProvider.add(newBuilder().setRef(4).setType(FILE).setPath(FILE_PATH).setLines(1));
-
- Component root = underTest.build(project, PROJECT_KEY);
- Map<Integer, Component> componentByRef = indexComponentByRef(root);
- assertThat(componentByRef.get(1).getUuid()).isEqualTo(SIMPLE_UUID_GENERATOR.apply(PROJECT_KEY));
- assertThat(componentByRef.get(2).getUuid()).isEqualTo(SIMPLE_UUID_GENERATOR.apply(MODULE_KEY));
- assertThat(componentByRef.get(3).getUuid()).isEqualTo(SIMPLE_UUID_GENERATOR.apply(DIRECTORY_KEY));
- assertThat(componentByRef.get(4).getUuid()).isEqualTo(SIMPLE_UUID_GENERATOR.apply(FILE_KEY));
-
- }
-
- @Test
- public void description_of_project_module_directory_and_file_is_null_when_unset_in_Scanner_Component() {
- ScannerReport.Component project = newBuilder().setType(PROJECT).setRef(1).addChildRef(2).build();
- scannerComponentProvider.add(newBuilder().setRef(2).setType(MODULE).addChildRef(3));
- scannerComponentProvider.add(newBuilder().setRef(3).setType(DIRECTORY).addChildRef(4));
- scannerComponentProvider.add(newBuilder().setRef(4).setType(FILE).setLines(1));
-
- Component root = underTest.build(project, PROJECT_KEY);
- Map<Integer, Component> componentByRef = indexComponentByRef(root);
- assertThat(componentByRef.get(1).getDescription()).isNull();
- assertThat(componentByRef.get(2).getDescription()).isNull();
- assertThat(componentByRef.get(3).getDescription()).isNull();
- assertThat(componentByRef.get(4).getDescription()).isNull();
- }
-
- @Test
- public void description_of_project_module_directory_and_file_is_null_when_empty_in_Scanner_Component() {
- ScannerReport.Component project = newBuilder().setType(PROJECT).setRef(1).setDescription("").addChildRef(2).build();
- scannerComponentProvider.add(newBuilder().setRef(2).setType(MODULE).setDescription("").addChildRef(3));
- scannerComponentProvider.add(newBuilder().setRef(3).setType(DIRECTORY).setDescription("").addChildRef(4));
- scannerComponentProvider.add(newBuilder().setRef(4).setType(FILE).setLines(1).setDescription(""));
-
- Component root = underTest.build(project, PROJECT_KEY);
- Map<Integer, Component> componentByRef = indexComponentByRef(root);
- assertThat(componentByRef.get(1).getDescription()).isNull();
- assertThat(componentByRef.get(2).getDescription()).isNull();
- assertThat(componentByRef.get(3).getDescription()).isNull();
- assertThat(componentByRef.get(4).getDescription()).isNull();
- }
-
- @Test
- public void description_of_project_module_directory_and_file_is_description_of_Scanner_Component_when_set() {
- ScannerReport.Component project = newBuilder().setType(PROJECT).setRef(1).setDescription("desc of project").addChildRef(2).build();
- scannerComponentProvider.add(newBuilder().setRef(2).setType(MODULE).setDescription("desc of module").addChildRef(3));
- scannerComponentProvider.add(newBuilder().setRef(3).setType(DIRECTORY).setDescription("desc of directory").addChildRef(4));
- scannerComponentProvider.add(newBuilder().setRef(4).setType(FILE).setLines(1).setDescription("desc of file"));
-
- Component root = underTest.build(project, PROJECT_KEY);
- Map<Integer, Component> componentByRef = indexComponentByRef(root);
- assertThat(componentByRef.get(1).getDescription()).isEqualTo("desc of project");
- assertThat(componentByRef.get(2).getDescription()).isEqualTo("desc of module");
- assertThat(componentByRef.get(3).getDescription()).isEqualTo("desc of directory");
- assertThat(componentByRef.get(4).getDescription()).isEqualTo("desc of file");
- }
-
- @Test
- public void all_types_but_UNSET_and_UNRECOGNIZED_are_converted() {
- Arrays.stream(ScannerReport.Component.ComponentType.values())
- .filter((type) -> type != UNRECOGNIZED)
- .filter((type) -> type != UNSET)
- .forEach((type) -> assertThat(ComponentRootBuilder.convertType(type)).isEqualTo(Component.Type.valueOf(type.name())));
- }
-
- @Test
- public void createOtherReportAttributes_takes_ref_version_and_path_from_Scanner_Component() {
- int ref = 123;
- String version = "1.0";
- String path = "some path";
-
- ReportAttributes reportAttributes = createOtherReportAttributes(newBuilder()
- .setRef(ref)
- .setVersion(version)
- .setPath(path)
- .build());
- assertThat(reportAttributes.getRef()).isEqualTo(ref);
- assertThat(reportAttributes.getPath()).isEqualTo(path);
- assertThat(reportAttributes.getVersion()).isEqualTo(version);
- }
-
- @Test
- public void createOtherReportAttributes_sets_null_version_when_unset_in_Scanner_Component() {
- ReportAttributes reportAttributes = createOtherReportAttributes(newBuilder().build());
- assertThat(reportAttributes.getVersion()).isNull();
- }
-
- @Test
- public void createOtherReportAttributes_sets_null_version_when_empty_in_Scanner_Component() {
- ReportAttributes reportAttributes = createOtherReportAttributes(newBuilder().setVersion("").build());
- assertThat(reportAttributes.getVersion()).isNull();
- }
-
- @Test
- public void createOtherReportAttributes_sets_null_path_when_unset_in_Scanner_Component() {
- ReportAttributes reportAttributes = createOtherReportAttributes(newBuilder().build());
- assertThat(reportAttributes.getPath()).isNull();
- }
-
- @Test
- public void createOtherReportAttributes_sets_null_path_when_empty_in_Scanner_Component() {
- ReportAttributes reportAttributes = createOtherReportAttributes(newBuilder().setPath("").build());
- assertThat(reportAttributes.getPath()).isNull();
- }
-
- @Test
- public void createProjectReportAttributes_sets_null_path_when_unset_in_Scanner_Component() {
- ReportAttributes reportAttributes = createProjectReportAttributes(newBuilder().build(), PROJECT_UUID, NO_BASEANALYSIS);
- assertThat(reportAttributes.getPath()).isNull();
- }
-
- @Test
- public void createProjectReportAttributes_sets_null_path_when_empty_in_Scanner_Component() {
- ReportAttributes reportAttributes = createProjectReportAttributes(newBuilder().setPath("").build(), PROJECT_UUID, NO_BASEANALYSIS);
- assertThat(reportAttributes.getPath()).isNull();
- }
-
- @Test
- public void createFileAttributes_returns_null_when_type_is_not_FILE() {
- Arrays.stream(ScannerReport.Component.ComponentType.values())
- .filter((type) -> type != UNRECOGNIZED)
- .filter((type) -> type != FILE)
- .map(
- (type) -> newBuilder().setType(type).build())
- .forEach(
- (component) -> assertThat(createFileAttributes(component)).isNull());
- }
-
- @Test
- public void createFileAttributes_sets_language_to_null_when_unset_in_Scanner_Component() {
- assertThat(createFileAttributes(newBuilder().setType(FILE).setLines(1).build()).getLanguageKey()).isNull();
- }
-
- @Test
- public void createFileAttributes_sets_language_to_null_when_empty_in_Scanner_Component() {
- assertThat(createFileAttributes(newBuilder().setType(FILE).setLanguage("").setLines(1).build()).getLanguageKey()).isNull();
- }
-
- @Test
- public void createFileAttributes_sets_unitTest_from_Scanner_Component() {
- assertThat(createFileAttributes(newBuilder().setType(FILE).setLines(1).build()).isUnitTest()).isFalse();
- assertThat(createFileAttributes(newBuilder().setType(FILE).setIsTest(true).setLines(1).build()).isUnitTest()).isTrue();
- }
-
- @Test
- public void createFileAttributes_sets_lines_in_Scanner_Component() {
- assertThat(createFileAttributes(newBuilder().setType(FILE).setLines(10).build()).getLines()).isEqualTo(10);
- }
-
- @Test
- public void fail_with_IAE_when_createFileAttributes_lines_is_not_set() throws Exception {
- expectedException.expect(IllegalArgumentException.class);
- expectedException.expectMessage("File 'src/main/java/Main.java' has no line");
- createFileAttributes(newBuilder().setType(FILE).setPath("src/main/java/Main.java").build());
- }
-
- @Test
- public void fail_with_IAE_when_createFileAttributes_sets_lines_to_0() throws Exception {
- expectedException.expect(IllegalArgumentException.class);
- expectedException.expectMessage("File 'src/main/java/Main.java' has no line");
- createFileAttributes(newBuilder().setType(FILE).setPath("src/main/java/Main.java").setLines(0).build());
- }
-
- @Test
- public void fail_with_IAE_when_createFileAttributes_sets_lines_to_less_than_0() throws Exception {
- expectedException.expect(IllegalArgumentException.class);
- expectedException.expectMessage("File 'src/main/java/Main.java' has no line");
- createFileAttributes(newBuilder().setType(FILE).setPath("src/main/java/Main.java").setLines(-10).build());
- }
-
- private static class ScannerComponentProvider extends ExternalResource implements Function<Integer, ScannerReport.Component> {
- private final Map<Integer, ScannerReport.Component> components = new HashMap<>();
-
- @Override
- protected void before() throws Throwable {
- components.clear();
- }
-
- @Override
- public ScannerReport.Component apply(Integer componentRef) {
- return checkNotNull(components.get(componentRef), "No Component for componentRef %s", componentRef);
- }
-
- public ScannerReport.Component add(ScannerReport.Component.Builder builder) {
- ScannerReport.Component component = builder.build();
- ScannerReport.Component existing = components.put(component.getRef(), component);
- checkArgument(existing == null, "Component %s already set for ref %s", existing, component.getRef());
- return component;
- }
- }
-
- private static Map<Integer, Component> indexComponentByRef(Component root) {
- Map<Integer, Component> componentsByRef = new HashMap<>();
- new DepthTraversalTypeAwareCrawler(
- new TypeAwareVisitorAdapter(CrawlerDepthLimit.FILE, PRE_ORDER) {
- @Override
- public void visitAny(Component any) {
- componentsByRef.put(any.getReportAttributes().getRef(), any);
- }
- }).visit(root);
- return componentsByRef;
- }
-}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.computation.task.projectanalysis.component;
+
+import java.util.Arrays;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+import java.util.function.Function;
+import javax.annotation.Nullable;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.rules.ExternalResource;
+import org.sonar.core.component.ComponentKeys;
+import org.sonar.db.component.SnapshotDto;
+import org.sonar.scanner.protocol.output.ScannerReport;
+import org.sonar.server.computation.task.projectanalysis.analysis.Project;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.Assert.fail;
+import static org.sonar.scanner.protocol.output.ScannerReport.Component.ComponentType.DIRECTORY;
+import static org.sonar.scanner.protocol.output.ScannerReport.Component.ComponentType.FILE;
+import static org.sonar.scanner.protocol.output.ScannerReport.Component.ComponentType.MODULE;
+import static org.sonar.scanner.protocol.output.ScannerReport.Component.ComponentType.PROJECT;
+import static org.sonar.scanner.protocol.output.ScannerReport.Component.ComponentType.UNRECOGNIZED;
+import static org.sonar.scanner.protocol.output.ScannerReport.Component.newBuilder;
+import static org.sonar.server.computation.task.projectanalysis.component.ComponentVisitor.Order.PRE_ORDER;
+
+public class ComponentTreeBuilderTest {
+
+ private static final ComponentKeyGenerator KEY_GENERATOR = (module, component) -> "generated_"
+ + ComponentKeys.createEffectiveKey(module.getKey(), component != null ? component.getPath() : null);
+ private static final Function<String, String> UUID_SUPPLIER = (componentKey) -> componentKey + "_uuid";
+ private static final EnumSet<ScannerReport.Component.ComponentType> REPORT_TYPES = EnumSet.of(PROJECT, MODULE, DIRECTORY, FILE);
+
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
+ @Rule
+ public ScannerComponentProvider scannerComponentProvider = new ScannerComponentProvider();
+
+ private Project projectInDb = new Project(UUID_SUPPLIER.apply("K1"), "K1", "theProjectName");
+
+ @Test
+ public void build_throws_IAE_for_all_types_but_PROJECT_MODULE_DIRECTORY_FILE() {
+ Arrays.stream(ScannerReport.Component.ComponentType.values())
+ .filter((type) -> type != UNRECOGNIZED)
+ .filter((type) -> !REPORT_TYPES.contains(type))
+ .forEach(
+ (type) -> {
+ ScannerReport.Component component = newBuilder().setType(type).build();
+ try {
+ call(component);
+ fail("Should have thrown a IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ assertThat(e).hasMessage("Unsupported component type '" + type + "'");
+ }
+ });
+ }
+
+ @Test
+ public void by_default_project_is_loaded_from_report() {
+ String nameInReport = "the name";
+ String descriptionInReport = "the desc";
+ Component root = call(newBuilder()
+ .setType(PROJECT)
+ .setKey(projectInDb.getKey())
+ .setRef(42)
+ .setName(nameInReport)
+ .setDescription(descriptionInReport)
+ .setVersion("6.5")
+ .build());
+
+ assertThat(root.getUuid()).isEqualTo("generated_K1_uuid");
+ assertThat(root.getKey()).isEqualTo("generated_K1");
+ assertThat(root.getType()).isEqualTo(Component.Type.PROJECT);
+ assertThat(root.getName()).isEqualTo(nameInReport);
+ assertThat(root.getDescription()).isEqualTo(descriptionInReport);
+ assertThat(root.getReportAttributes().getRef()).isEqualTo(42);
+ assertThat(root.getReportAttributes().getPath()).isNull();
+ assertThat(root.getReportAttributes().getVersion()).isEqualTo("6.5");
+ assertThatFileAttributesAreNotSet(root);
+ }
+
+ @Test
+ public void project_name_is_loaded_from_db_if_absent_from_report() {
+ Component root = call(newBuilder()
+ .setType(PROJECT)
+ .build());
+
+ assertThat(root.getName()).isEqualTo(projectInDb.getName());
+ }
+
+ @Test
+ public void project_version_is_loaded_from_db_if_absent_from_report() {
+ SnapshotDto baseAnalysis = new SnapshotDto().setVersion("6.5");
+ Component root = call(newBuilder()
+ .setType(PROJECT)
+ .build(), baseAnalysis);
+
+ assertThat(root.getReportAttributes().getVersion()).isEqualTo("6.5");
+ }
+
+ @Test
+ public void project_version_is_loaded_from_db_if_empty_report() {
+ SnapshotDto baseAnalysis = new SnapshotDto().setVersion("6.5");
+ Component root = call(newBuilder()
+ .setType(PROJECT)
+ .setVersion("")
+ .build(), baseAnalysis);
+
+ assertThat(root.getReportAttributes().getVersion()).isEqualTo("6.5");
+ }
+
+ @Test
+ public void project_version_is_hardcoded_if_absent_from_report_and_db() {
+ Component root = call(newBuilder()
+ .setType(PROJECT)
+ .build());
+
+ assertThat(root.getReportAttributes().getVersion()).isEqualTo("not provided");
+ }
+
+ @Test
+ public void project_description_is_null_if_absent_from_report() {
+ Component root = call(newBuilder()
+ .setType(PROJECT)
+ .build());
+
+ assertThat(root.getDescription()).isNull();
+ }
+
+ @Test
+ public void keys_of_module_directory_and_file_are_generated() {
+ ScannerReport.Component project = newBuilder()
+ .setType(PROJECT)
+ .setKey(projectInDb.getKey())
+ .setRef(1)
+ .addChildRef(2)
+ .build();
+ scannerComponentProvider.add(newBuilder()
+ .setRef(2)
+ .setType(MODULE)
+ .setKey("M")
+ .addChildRef(3));
+ scannerComponentProvider.add(newBuilder()
+ .setRef(3)
+ .setType(DIRECTORY)
+ .setPath("src/js")
+ .addChildRef(4));
+ scannerComponentProvider.add(newBuilder()
+ .setRef(4)
+ .setType(FILE)
+ .setPath("src/js/Foo.js")
+ .setLines(1));
+
+ Component root = call(project);
+ assertThat(root.getKey()).isEqualTo("generated_" + projectInDb.getKey());
+ assertThat(root.getChildren()).hasSize(1);
+
+ Component module = root.getChildren().iterator().next();
+ assertThat(module.getKey()).isEqualTo("generated_M");
+ assertThat(module.getChildren()).hasSize(1);
+
+ Component directory = module.getChildren().iterator().next();
+ assertThat(directory.getKey()).isEqualTo("generated_M:src/js");
+ assertThat(directory.getChildren()).hasSize(1);
+
+ Component file = directory.getChildren().iterator().next();
+ assertThat(file.getKey()).isEqualTo("generated_M:src/js/Foo.js");
+ assertThat(file.getChildren()).isEmpty();
+ }
+
+ @Test
+ public void names_of_module_directory_and_file_are_keys_if_names_are_absent_from_report() {
+ ScannerReport.Component project = newBuilder()
+ .setType(PROJECT)
+ .setKey(projectInDb.getKey())
+ .setRef(1)
+ .addChildRef(2)
+ .build();
+ scannerComponentProvider.add(newBuilder()
+ .setRef(2)
+ .setType(MODULE)
+ .setKey("M")
+ .addChildRef(3));
+ scannerComponentProvider.add(newBuilder()
+ .setRef(3)
+ .setType(DIRECTORY)
+ .setPath("src/js")
+ .addChildRef(4));
+ scannerComponentProvider.add(newBuilder()
+ .setRef(4)
+ .setType(FILE)
+ .setPath("src/js/Foo.js")
+ .setLines(1));
+
+ Component root = call(project);
+
+ Component module = root.getChildren().iterator().next();
+ assertThat(module.getName()).isEqualTo("generated_M");
+
+ Component directory = module.getChildren().iterator().next();
+ assertThat(directory.getName()).isEqualTo("generated_M:src/js");
+
+ Component file = directory.getChildren().iterator().next();
+ assertThat(file.getName()).isEqualTo("generated_M:src/js/Foo.js");
+ }
+
+ @Test
+ public void names_of_module_directory_and_file_are_keys_if_names_are_empty_in_report() {
+ ScannerReport.Component project = newBuilder()
+ .setType(PROJECT)
+ .setKey(projectInDb.getKey())
+ .setRef(1)
+ .addChildRef(2)
+ .build();
+ scannerComponentProvider.add(newBuilder()
+ .setRef(2)
+ .setType(MODULE)
+ .setKey("M")
+ .setName("")
+ .addChildRef(3));
+ scannerComponentProvider.add(newBuilder()
+ .setRef(3)
+ .setType(DIRECTORY)
+ .setPath("src/js")
+ .setName("")
+ .addChildRef(4));
+ scannerComponentProvider.add(newBuilder()
+ .setRef(4)
+ .setType(FILE)
+ .setPath("src/js/Foo.js")
+ .setName("")
+ .setLines(1));
+
+ Component root = call(project);
+
+ Component module = root.getChildren().iterator().next();
+ assertThat(module.getName()).isEqualTo("generated_M");
+
+ Component directory = module.getChildren().iterator().next();
+ assertThat(directory.getName()).isEqualTo("generated_M:src/js");
+
+ Component file = directory.getChildren().iterator().next();
+ assertThat(file.getName()).isEqualTo("generated_M:src/js/Foo.js");
+ }
+
+ private void assertThatFileAttributesAreNotSet(Component root) {
+ try {
+ root.getFileAttributes();
+ fail();
+ } catch (IllegalStateException e) {
+ assertThat(e).hasMessage("Only component of type FILE have a FileAttributes object");
+ }
+ }
+
+ @Test
+ public void name_of_module_directory_and_files_includes_name_of_closest_module() {
+ ScannerReport.Component project = newBuilder()
+ .setType(PROJECT)
+ .setKey("project 1")
+ .setRef(1)
+ .addChildRef(11).addChildRef(21).addChildRef(31).build();
+ scannerComponentProvider.add(newBuilder().setRef(11).setType(MODULE).setKey("module 1").addChildRef(12).addChildRef(22).addChildRef(32));
+ scannerComponentProvider.add(newBuilder().setRef(12).setType(MODULE).setKey("module 2").addChildRef(13).addChildRef(23).addChildRef(33));
+ scannerComponentProvider.add(newBuilder().setRef(13).setType(MODULE).setKey("module 3").addChildRef(24).addChildRef(34));
+ scannerComponentProvider.add(newBuilder().setRef(21).setType(DIRECTORY).setPath("directory in project").addChildRef(35));
+ scannerComponentProvider.add(newBuilder().setRef(22).setType(DIRECTORY).setPath("directory in module 1").addChildRef(36));
+ scannerComponentProvider.add(newBuilder().setRef(23).setType(DIRECTORY).setPath("directory in module 2").addChildRef(37));
+ scannerComponentProvider.add(newBuilder().setRef(24).setType(DIRECTORY).setPath("directory in module 3").addChildRef(38));
+ scannerComponentProvider.add(newBuilder().setRef(31).setType(FILE).setPath("file in project").setLines(1));
+ scannerComponentProvider.add(newBuilder().setRef(32).setType(FILE).setPath("file in module 1").setLines(1));
+ scannerComponentProvider.add(newBuilder().setRef(33).setType(FILE).setPath("file in module 2").setLines(1));
+ scannerComponentProvider.add(newBuilder().setRef(34).setType(FILE).setPath("file in module 3").setLines(1));
+ scannerComponentProvider.add(newBuilder().setRef(35).setType(FILE).setPath("file in directory in project").setLines(1));
+ scannerComponentProvider.add(newBuilder().setRef(36).setType(FILE).setPath("file in directory in module 1").setLines(1));
+ scannerComponentProvider.add(newBuilder().setRef(37).setType(FILE).setPath("file in directory in module 2").setLines(1));
+ scannerComponentProvider.add(newBuilder().setRef(38).setType(FILE).setPath("file in directory in module 3").setLines(1));
+
+ Component root = call(project);
+ Map<Integer, Component> componentsByRef = indexComponentByRef(root);
+ assertThat(componentsByRef.get(11).getKey()).isEqualTo("generated_module 1");
+ assertThat(componentsByRef.get(12).getKey()).isEqualTo("generated_module 2");
+ assertThat(componentsByRef.get(13).getKey()).isEqualTo("generated_module 3");
+ assertThat(componentsByRef.get(21).getKey()).startsWith("generated_project 1:");
+ assertThat(componentsByRef.get(22).getKey()).startsWith("generated_module 1:");
+ assertThat(componentsByRef.get(23).getKey()).startsWith("generated_module 2:");
+ assertThat(componentsByRef.get(24).getKey()).startsWith("generated_module 3:");
+ assertThat(componentsByRef.get(31).getKey()).startsWith("generated_project 1:");
+ assertThat(componentsByRef.get(32).getKey()).startsWith("generated_module 1:");
+ assertThat(componentsByRef.get(33).getKey()).startsWith("generated_module 2:");
+ assertThat(componentsByRef.get(34).getKey()).startsWith("generated_module 3:");
+ assertThat(componentsByRef.get(35).getKey()).startsWith("generated_project 1:");
+ assertThat(componentsByRef.get(36).getKey()).startsWith("generated_module 1:");
+ assertThat(componentsByRef.get(37).getKey()).startsWith("generated_module 2:");
+ assertThat(componentsByRef.get(38).getKey()).startsWith("generated_module 3:");
+ }
+
+ @Test
+ public void uuids_are_provided_by_supplier() {
+ ScannerReport.Component project = newBuilder()
+ .setType(PROJECT)
+ .setKey("c1")
+ .setRef(1)
+ .addChildRef(2)
+ .build();
+ scannerComponentProvider.add(newBuilder()
+ .setRef(2)
+ .setType(MODULE)
+ .setKey("c2")
+ .addChildRef(3));
+ scannerComponentProvider.add(newBuilder()
+ .setRef(3)
+ .setType(DIRECTORY)
+ .setPath("src/js")
+ .addChildRef(4));
+ scannerComponentProvider.add(newBuilder()
+ .setRef(4)
+ .setType(FILE)
+ .setPath("src/js/Foo.js")
+ .setLines(1));
+
+ Component root = call(project);
+ assertThat(root.getUuid()).isEqualTo("generated_c1_uuid");
+
+ Component module = root.getChildren().iterator().next();
+ assertThat(module.getUuid()).isEqualTo("generated_c2_uuid");
+
+ Component directory = module.getChildren().iterator().next();
+ assertThat(directory.getUuid()).isEqualTo("generated_c2:src/js_uuid");
+
+ Component file = directory.getChildren().iterator().next();
+ assertThat(file.getUuid()).isEqualTo("generated_c2:src/js/Foo.js_uuid");
+ }
+
+ @Test
+ public void descriptions_of_module_directory_and_file_are_null_if_absent_from_report() {
+ ScannerReport.Component project = newBuilder()
+ .setType(PROJECT)
+ .setRef(1)
+ .addChildRef(2)
+ .build();
+ scannerComponentProvider.add(newBuilder()
+ .setRef(2)
+ .setType(MODULE)
+ .addChildRef(3));
+ scannerComponentProvider.add(newBuilder()
+ .setRef(3)
+ .setType(DIRECTORY)
+ .setPath("src/js")
+ .addChildRef(4));
+ scannerComponentProvider.add(newBuilder()
+ .setRef(4)
+ .setType(FILE)
+ .setPath("src/js/Foo.js")
+ .setLines(1));
+
+ Component root = call(project);
+
+ Component module = root.getChildren().iterator().next();
+ assertThat(module.getDescription()).isNull();
+
+ Component directory = module.getChildren().iterator().next();
+ assertThat(directory.getDescription()).isNull();
+
+ Component file = directory.getChildren().iterator().next();
+ assertThat(file.getDescription()).isNull();
+ }
+
+ @Test
+ public void descriptions_of_module_directory_and_file_are_null_if_empty_in_report() {
+ ScannerReport.Component project = newBuilder()
+ .setType(PROJECT)
+ .setRef(1)
+ .setDescription("")
+ .addChildRef(2)
+ .build();
+ scannerComponentProvider.add(newBuilder()
+ .setRef(2)
+ .setType(MODULE)
+ .setDescription("")
+ .addChildRef(3));
+ scannerComponentProvider.add(newBuilder()
+ .setRef(3)
+ .setType(DIRECTORY)
+ .setDescription("")
+ .setPath("src/js")
+ .addChildRef(4));
+ scannerComponentProvider.add(newBuilder()
+ .setRef(4)
+ .setType(FILE)
+ .setDescription("")
+ .setPath("src/js/Foo.js")
+ .setLines(1));
+
+ Component root = call(project);
+
+ Component module = root.getChildren().iterator().next();
+ assertThat(module.getDescription()).isNull();
+
+ Component directory = module.getChildren().iterator().next();
+ assertThat(directory.getDescription()).isNull();
+
+ Component file = directory.getChildren().iterator().next();
+ assertThat(file.getDescription()).isNull();
+ }
+
+ @Test
+ public void descriptions_of_module_directory_and_file_are_set_from_report_if_present() {
+ ScannerReport.Component project = newBuilder()
+ .setType(PROJECT)
+ .setRef(1)
+ .addChildRef(2)
+ .build();
+ scannerComponentProvider.add(newBuilder()
+ .setRef(2)
+ .setType(MODULE)
+ .setDescription("b")
+ .addChildRef(3));
+ scannerComponentProvider.add(newBuilder()
+ .setRef(3)
+ .setType(DIRECTORY)
+ .setDescription("c")
+ .setPath("src/js")
+ .addChildRef(4));
+ scannerComponentProvider.add(newBuilder()
+ .setRef(4)
+ .setType(FILE)
+ .setDescription("d")
+ .setPath("src/js/Foo.js")
+ .setLines(1));
+
+ Component root = call(project);
+
+ Component module = root.getChildren().iterator().next();
+ assertThat(module.getDescription()).isEqualTo("b");
+
+ Component directory = module.getChildren().iterator().next();
+ assertThat(directory.getDescription()).isEqualTo("c");
+
+ Component file = directory.getChildren().iterator().next();
+ assertThat(file.getDescription()).isEqualTo("d");
+ }
+
+ @Test
+ public void versions_of_module_directory_and_file_are_set_from_report_if_present() {
+ ScannerReport.Component project = newBuilder()
+ .setType(PROJECT)
+ .setRef(1)
+ .addChildRef(2)
+ .build();
+ scannerComponentProvider.add(newBuilder()
+ .setRef(2)
+ .setType(MODULE)
+ .setVersion("v1")
+ .addChildRef(3));
+ scannerComponentProvider.add(newBuilder()
+ .setRef(3)
+ .setType(DIRECTORY)
+ .setVersion("v2")
+ .setPath("src/js")
+ .addChildRef(4));
+ scannerComponentProvider.add(newBuilder()
+ .setRef(4)
+ .setType(FILE)
+ .setVersion("v3")
+ .setPath("src/js/Foo.js")
+ .setLines(1));
+
+ Component root = call(project);
+
+ Component module = root.getChildren().iterator().next();
+ assertThat(module.getReportAttributes().getVersion()).isEqualTo("v1");
+
+ Component directory = module.getChildren().iterator().next();
+ assertThat(directory.getReportAttributes().getVersion()).isEqualTo("v2");
+
+ Component file = directory.getChildren().iterator().next();
+ assertThat(file.getReportAttributes().getVersion()).isEqualTo("v3");
+ }
+
+ @Test
+ public void versions_of_module_directory_and_file_are_null_if_absent_from_report() {
+ ScannerReport.Component project = newBuilder()
+ .setType(PROJECT)
+ .setRef(1)
+ .addChildRef(2)
+ .build();
+ scannerComponentProvider.add(newBuilder()
+ .setRef(2)
+ .setType(MODULE)
+ .addChildRef(3));
+ scannerComponentProvider.add(newBuilder()
+ .setRef(3)
+ .setType(DIRECTORY)
+ .setPath("src/js")
+ .addChildRef(4));
+ scannerComponentProvider.add(newBuilder()
+ .setRef(4)
+ .setType(FILE)
+ .setPath("src/js/Foo.js")
+ .setLines(1));
+
+ Component root = call(project);
+
+ Component module = root.getChildren().iterator().next();
+ assertThat(module.getReportAttributes().getVersion()).isNull();
+
+ Component directory = module.getChildren().iterator().next();
+ assertThat(directory.getReportAttributes().getVersion()).isNull();
+
+ Component file = directory.getChildren().iterator().next();
+ assertThat(file.getReportAttributes().getVersion()).isNull();
+ }
+
+ @Test
+ public void versions_of_module_directory_and_file_are_null_if_empty_in_report() {
+ ScannerReport.Component project = newBuilder()
+ .setType(PROJECT)
+ .setRef(1)
+ .addChildRef(2)
+ .build();
+ scannerComponentProvider.add(newBuilder()
+ .setRef(2)
+ .setType(MODULE)
+ .setVersion("")
+ .addChildRef(3));
+ scannerComponentProvider.add(newBuilder()
+ .setRef(3)
+ .setType(DIRECTORY)
+ .setVersion("")
+ .setPath("src/js")
+ .addChildRef(4));
+ scannerComponentProvider.add(newBuilder()
+ .setRef(4)
+ .setType(FILE)
+ .setVersion("")
+ .setPath("src/js/Foo.js")
+ .setLines(1));
+
+ Component root = call(project);
+
+ Component module = root.getChildren().iterator().next();
+ assertThat(module.getReportAttributes().getVersion()).isNull();
+
+ Component directory = module.getChildren().iterator().next();
+ assertThat(directory.getReportAttributes().getVersion()).isNull();
+
+ Component file = directory.getChildren().iterator().next();
+ assertThat(file.getReportAttributes().getVersion()).isNull();
+ }
+
+ @Test
+ public void only_nb_of_lines_is_mandatory_on_file_attributes() {
+ ScannerReport.Component project = newBuilder()
+ .setType(PROJECT)
+ .setRef(1)
+ .addChildRef(2)
+ .build();
+ scannerComponentProvider.add(newBuilder()
+ .setRef(2)
+ .setType(FILE)
+ .setPath("src/js/Foo.js")
+ .setLines(1));
+
+ Component root = call(project);
+ Component file = root.getChildren().iterator().next();
+ assertThat(file.getFileAttributes().getLines()).isEqualTo(1);
+ assertThat(file.getFileAttributes().getLanguageKey()).isNull();
+ assertThat(file.getFileAttributes().isUnitTest()).isFalse();
+ }
+
+ @Test
+ public void language_file_attributes_is_null_if_empty_in_report() {
+ ScannerReport.Component project = newBuilder()
+ .setType(PROJECT)
+ .setRef(1)
+ .addChildRef(2)
+ .build();
+ scannerComponentProvider.add(newBuilder()
+ .setRef(2)
+ .setType(FILE)
+ .setPath("src/js/Foo.js")
+ .setLines(1)
+ .setLanguage(""));
+
+ Component root = call(project);
+ Component file = root.getChildren().iterator().next();
+ assertThat(file.getFileAttributes().getLanguageKey()).isNull();
+ }
+
+ @Test
+ public void file_attributes_are_fully_loaded_from_report() {
+ ScannerReport.Component project = newBuilder()
+ .setType(PROJECT)
+ .setRef(1)
+ .addChildRef(2)
+ .build();
+ scannerComponentProvider.add(newBuilder()
+ .setRef(2)
+ .setType(FILE)
+ .setPath("src/js/Foo.js")
+ .setLines(1)
+ .setLanguage("js")
+ .setIsTest(true));
+
+ Component root = call(project);
+ Component file = root.getChildren().iterator().next();
+ assertThat(file.getFileAttributes().getLines()).isEqualTo(1);
+ assertThat(file.getFileAttributes().getLanguageKey()).isEqualTo("js");
+ assertThat(file.getFileAttributes().isUnitTest()).isTrue();
+ }
+
+ @Test
+ public void throw_IAE_if_lines_is_absent_from_report() {
+ ScannerReport.Component project = newBuilder()
+ .setType(PROJECT)
+ .setRef(1)
+ .addChildRef(2)
+ .build();
+ scannerComponentProvider.add(newBuilder()
+ .setRef(2)
+ .setType(FILE)
+ .setPath("src/js/Foo.js"));
+
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("File 'src/js/Foo.js' has no line");
+
+ call(project);
+ }
+
+ @Test
+ public void throw_IAE_if_lines_is_zero_in_report() {
+ ScannerReport.Component project = newBuilder()
+ .setType(PROJECT)
+ .setRef(1)
+ .addChildRef(2)
+ .build();
+ scannerComponentProvider.add(newBuilder()
+ .setRef(2)
+ .setType(FILE)
+ .setPath("src/js/Foo.js")
+ .setLines(0));
+
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("File 'src/js/Foo.js' has no line");
+
+ call(project);
+ }
+
+ @Test
+ public void throw_IAE_if_lines_is_negative_in_report() {
+ ScannerReport.Component project = newBuilder()
+ .setType(PROJECT)
+ .setRef(1)
+ .addChildRef(2)
+ .build();
+ scannerComponentProvider.add(newBuilder()
+ .setRef(2)
+ .setType(FILE)
+ .setPath("src/js/Foo.js")
+ .setLines(-10));
+
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("File 'src/js/Foo.js' has no line");
+
+ call(project);
+ }
+
+ private static class ScannerComponentProvider extends ExternalResource implements Function<Integer, ScannerReport.Component> {
+ private final Map<Integer, ScannerReport.Component> components = new HashMap<>();
+
+ @Override
+ protected void before() throws Throwable {
+ components.clear();
+ }
+
+ @Override
+ public ScannerReport.Component apply(Integer componentRef) {
+ return Objects.requireNonNull(components.get(componentRef), "No Component for componentRef " + componentRef);
+ }
+
+ public ScannerReport.Component add(ScannerReport.Component.Builder builder) {
+ ScannerReport.Component component = builder.build();
+ ScannerReport.Component existing = components.put(component.getRef(), component);
+ checkArgument(existing == null, "Component %s already set for ref %s", existing, component.getRef());
+ return component;
+ }
+ }
+
+ private Component call(ScannerReport.Component project) {
+ return newUnderTest(null).buildProject(project);
+ }
+
+ private Component call(ScannerReport.Component project, @Nullable SnapshotDto baseAnalysis) {
+ return newUnderTest(baseAnalysis).buildProject(project);
+ }
+
+ private ComponentTreeBuilder newUnderTest(@Nullable SnapshotDto baseAnalysis) {
+ return new ComponentTreeBuilder(KEY_GENERATOR, UUID_SUPPLIER, scannerComponentProvider, projectInDb, baseAnalysis);
+ }
+
+ private static Map<Integer, Component> indexComponentByRef(Component root) {
+ Map<Integer, Component> componentsByRef = new HashMap<>();
+ new DepthTraversalTypeAwareCrawler(
+ new TypeAwareVisitorAdapter(CrawlerDepthLimit.FILE, PRE_ORDER) {
+ @Override
+ public void visitAny(Component any) {
+ componentsByRef.put(any.getReportAttributes().getRef(), any);
+ }
+ }).visit(root);
+ return componentsByRef;
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.computation.task.projectanalysis.component;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.utils.System2;
+import org.sonar.db.DbTester;
+import org.sonar.db.component.ComponentDto;
+import org.sonar.db.component.ComponentTesting;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class ComponentUuidFactoryTest {
+
+ @Rule
+ public DbTester db = DbTester.create(System2.INSTANCE);
+
+ @Test
+ public void load_uuids_from_existing_components_in_db() {
+ ComponentDto project = db.components().insertPrivateProject();
+ ComponentDto module = db.components().insertComponent(ComponentTesting.newModuleDto(project));
+
+ ComponentUuidFactory underTest = new ComponentUuidFactory(db.getDbClient(), db.getSession(), project.getDbKey());
+ assertThat(underTest.getOrCreateForKey(project.getDbKey())).isEqualTo(project.uuid());
+ assertThat(underTest.getOrCreateForKey(module.getDbKey())).isEqualTo(module.uuid());
+ }
+
+ @Test
+ public void generate_uuid_if_it_does_not_exist_in_db() {
+ ComponentUuidFactory underTest = new ComponentUuidFactory(db.getDbClient(), db.getSession(), "theProjectKey");
+
+ String generatedKey = underTest.getOrCreateForKey("foo");
+ assertThat(generatedKey).isNotEmpty();
+
+ // uuid is kept in memory for further calls with same key
+ assertThat(underTest.getOrCreateForKey("foo")).isEqualTo(generatedKey);
+ }
+
+}
*/
package org.sonar.server.computation.task.projectanalysis.component;
-import org.junit.After;
-import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.sonar.api.config.Configuration;
import org.sonar.api.config.internal.MapSettings;
import org.sonar.api.utils.System2;
+import org.sonar.ce.queue.CeTask;
import org.sonar.ce.settings.ProjectConfigurationFactory;
import org.sonar.db.DbClient;
-import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
+import org.sonar.db.ce.CeTaskTypes;
import org.sonar.db.component.ComponentDto;
-import org.sonar.db.component.ComponentTesting;
import org.sonar.db.property.PropertyDto;
import static org.assertj.core.api.Assertions.assertThat;
public class ConfigurationRepositoryTest {
private static final Component ROOT = ReportComponent.builder(PROJECT, 1).setKey("ROOT").build();
+ private static final CeTask TASK = new CeTask.Builder()
+ .setOrganizationUuid("foo")
+ .setUuid("bar")
+ .setType(CeTaskTypes.REPORT)
+ .setComponentUuid(ROOT.getUuid())
+ .setComponentKey(ROOT.getKey())
+ .build();
@Rule
- public final DbTester dbTester = DbTester.create(System2.INSTANCE);
+ public final DbTester db = DbTester.create(System2.INSTANCE);
- DbClient dbClient = dbTester.getDbClient();
-
- DbSession session;
-
- MapSettings globalSettings;
-
- ConfigurationRepository underTest;
-
- @Before
- public void createDao() {
- globalSettings = new MapSettings();
- session = dbClient.openSession(false);
- underTest = new ConfigurationRepositoryImpl(new ProjectConfigurationFactory(globalSettings, dbClient));
- }
-
- @After
- public void tearDown() {
- session.close();
- }
+ private DbClient dbClient = db.getDbClient();
+ private MapSettings globalSettings = new MapSettings();
+ private ConfigurationRepository underTest = new ConfigurationRepositoryImpl(TASK, new ProjectConfigurationFactory(globalSettings, dbClient));
@Test
public void get_project_settings_from_global_settings() {
globalSettings.setProperty("key", "value");
- Configuration config = underTest.getConfiguration(ROOT);
+ Configuration config = underTest.getConfiguration();
assertThat(config.get("key")).hasValue("value");
}
@Test
public void get_project_settings_from_db() {
- ComponentDto project = ComponentTesting.newPrivateProjectDto(dbTester.organizations().insert()).setDbKey(ROOT.getKey());
- dbClient.componentDao().insert(session, project);
- dbClient.propertiesDao().saveProperty(session, new PropertyDto().setResourceId(project.getId()).setKey("key").setValue("value"));
- session.commit();
+ ComponentDto project = db.components().insertPrivateProject(p -> p.setDbKey(ROOT.getKey()));
+ insertProjectProperty(project, "key", "value");
- Configuration config = underTest.getConfiguration(ROOT);
+ Configuration config = underTest.getConfiguration();
assertThat(config.get("key")).hasValue("value");
}
public void call_twice_get_project_settings() {
globalSettings.setProperty("key", "value");
- Configuration config = underTest.getConfiguration(ROOT);
+ Configuration config = underTest.getConfiguration();
assertThat(config.get("key")).hasValue("value");
- config = underTest.getConfiguration(ROOT);
+ config = underTest.getConfiguration();
assertThat(config.get("key")).hasValue("value");
}
+
+ @Test
+ public void project_settings_override_global_settings() {
+ globalSettings.setProperty("key", "value1");
+ ComponentDto project = db.components().insertPrivateProject(p -> p.setDbKey(ROOT.getKey()));
+ insertProjectProperty(project, "key", "value2");
+
+ Configuration config = underTest.getConfiguration();
+ assertThat(config.get("key")).hasValue("value2");
+ }
+
+ @Test
+ public void project_settings_are_cached_to_avoid_db_access() {
+ ComponentDto project = db.components().insertPrivateProject(p -> p.setDbKey(ROOT.getKey()));
+ insertProjectProperty(project, "key", "value");
+
+ Configuration config = underTest.getConfiguration();
+ assertThat(config.get("key")).hasValue("value");
+
+ db.executeUpdateSql("delete from properties");
+ db.commit();
+
+ assertThat(config.get("key")).hasValue("value");
+ }
+
+ private void insertProjectProperty(ComponentDto project, String propertyKey, String propertyValue) {
+ db.properties().insertProperties(new PropertyDto().setKey(propertyKey).setValue(propertyValue).setResourceId(project.getId()));
+ }
}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.computation.task.projectanalysis.component;
+
+import javax.annotation.Nullable;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.api.utils.MessageException;
+import org.sonar.db.component.BranchType;
+import org.sonar.scanner.protocol.output.ScannerReport;
+import org.sonar.scanner.protocol.output.ScannerReport.Component.ComponentType;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class MainBranchImplTest {
+
+ private static final ScannerReport.Component PROJECT = ScannerReport.Component.newBuilder().setType(ComponentType.PROJECT).setKey("P").build();
+ private static final ScannerReport.Component MODULE = ScannerReport.Component.newBuilder().setType(ComponentType.MODULE).setKey("M").build();
+ private static final ScannerReport.Component FILE = ScannerReport.Component.newBuilder().setType(ComponentType.FILE).setPath("src/Foo.js").build();
+
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
+ @Test
+ public void throw_ME_if_name_contains_invalid_characters() {
+ assertThatNameIsCorrect("master");
+ assertThatNameIsCorrect("feature/foo");
+ assertThatNameIsCorrect("feature_foo");
+
+ assertThatNameIsNotCorrect("feature foo");
+ assertThatNameIsNotCorrect("feature#foo");
+ }
+
+ @Test
+ public void default_branch_represents_the_project() {
+ MainBranchImpl branch = new MainBranchImpl(null);
+
+ assertThat(branch.isMain()).isTrue();
+ assertThat(branch.getType()).isEqualTo(BranchType.LONG);
+ assertThat(branch.getName()).isEmpty();
+ assertThat(branch.supportsCrossProjectCpd()).isTrue();
+
+ assertThat(branch.generateKey(PROJECT, null)).isEqualTo("P");
+ assertThat(branch.generateKey(MODULE, null)).isEqualTo("M");
+ assertThat(branch.generateKey(MODULE, FILE)).isEqualTo("M:src/Foo.js");
+ }
+
+ @Test
+ public void branch_represents_a_forked_project_with_different_key() {
+ MainBranchImpl branch = new MainBranchImpl("bar");
+
+ // not a real branch. Parameter sonar.branch forks project.
+ assertThat(branch.isMain()).isTrue();
+ assertThat(branch.getType()).isEqualTo(BranchType.LONG);
+ assertThat(branch.getName()).hasValue("bar");
+ assertThat(branch.supportsCrossProjectCpd()).isFalse();
+
+ assertThat(branch.generateKey(PROJECT, null)).isEqualTo("P:bar");
+ assertThat(branch.generateKey(MODULE, null)).isEqualTo("M:bar");
+ assertThat(branch.generateKey(MODULE, FILE)).isEqualTo("M:bar:src/Foo.js");
+ }
+
+ private void assertThatNameIsCorrect(@Nullable String name) {
+ MainBranchImpl branch = new MainBranchImpl(name);
+ assertThat(branch.getName()).hasValue(name);
+ }
+
+ private void assertThatNameIsNotCorrect(String name) {
+ expectedException.expect(MessageException.class);
+ expectedException.expectMessage("\"" + name + "\" is not a valid branch name. Allowed characters are alphanumeric, '-', '_', '.' and '/'.");
+
+ new MainBranchImpl(name);
+ }
+}
}
@Override
- public Configuration getConfiguration(Component component) {
+ public Configuration getConfiguration() {
return config;
}
}
import org.sonar.api.utils.log.LogTester;
import org.sonar.api.utils.log.LoggerLevel;
import org.sonar.server.computation.task.projectanalysis.analysis.AnalysisMetadataHolderRule;
+import org.sonar.server.computation.task.projectanalysis.analysis.Branch;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
public class CrossProjectDuplicationStatusHolderImplTest {
- private static String BRANCH = "origin/master";
-
@Rule
public ExpectedException thrown = ExpectedException.none();
@Rule
public void cross_project_duplication_is_enabled_when_enabled_in_report_and_no_branch() throws Exception {
analysisMetadataHolder
.setCrossProjectDuplicationEnabled(true)
- .setBranch(null);
+ .setBranch(newBranch(true));
underTest.start();
assertThat(underTest.isEnabled()).isTrue();
public void cross_project_duplication_is_disabled_when_not_enabled_in_report() throws Exception {
analysisMetadataHolder
.setCrossProjectDuplicationEnabled(false)
- .setBranch(null);
+ .setBranch(newBranch(true));
underTest.start();
assertThat(underTest.isEnabled()).isFalse();
public void cross_project_duplication_is_disabled_when_branch_is_used() throws Exception {
analysisMetadataHolder
.setCrossProjectDuplicationEnabled(true)
- .setBranch(BRANCH);
+ .setBranch(newBranch(false));
underTest.start();
assertThat(underTest.isEnabled()).isFalse();
public void cross_project_duplication_is_disabled_when_not_enabled_in_report_and_when_branch_is_used() throws Exception {
analysisMetadataHolder
.setCrossProjectDuplicationEnabled(false)
- .setBranch(BRANCH);
+ .setBranch(newBranch(false));
underTest.start();
assertThat(underTest.isEnabled()).isFalse();
public void flag_is_build_in_start() throws Exception {
analysisMetadataHolder
.setCrossProjectDuplicationEnabled(true)
- .setBranch(null);
+ .setBranch(newBranch(true));
underTest.start();
assertThat(underTest.isEnabled()).isTrue();
underTest.isEnabled();
}
+
+ private static Branch newBranch(boolean supportsCrossProjectCpd) {
+ Branch branch = mock(Branch.class);
+ when(branch.supportsCrossProjectCpd()).thenReturn(supportsCrossProjectCpd);
+ return branch;
+ }
}
import org.sonar.server.computation.task.projectanalysis.analysis.Organization;
import org.sonar.server.computation.task.projectanalysis.component.ConfigurationRepository;
import org.sonar.server.computation.task.projectanalysis.component.TestSettingsRepository;
-import org.sonar.server.computation.task.projectanalysis.component.TreeRootHolderRule;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.sonar.server.computation.task.projectanalysis.component.ReportComponent.DUMB_PROJECT;
public class DefaultAssigneeTest {
@Rule
public DbTester db = DbTester.create();
- @Rule
- public TreeRootHolderRule rootHolder = new TreeRootHolderRule().setRoot(DUMB_PROJECT);
-
private MapSettings settings = new MapSettings();
private ConfigurationRepository settingsRepository = new TestSettingsRepository(settings.asConfig());
private AnalysisMetadataHolderImpl analysisMetadataHolder = new AnalysisMetadataHolderImpl();
private OrganizationDto organizationDto;
- private DefaultAssignee underTest = new DefaultAssignee(db.getDbClient(), rootHolder, settingsRepository, analysisMetadataHolder);
+ private DefaultAssignee underTest = new DefaultAssignee(db.getDbClient(), settingsRepository, analysisMetadataHolder);
@Before
public void setUp() throws Exception {
@Test
public void ignore_all() throws Exception {
- IssueFilter underTest = newIssueFilter(newSettings(asList("*", "**"), Collections.<String>emptyList()));
+ IssueFilter underTest = newIssueFilter(newSettings(asList("*", "**"), Collections.emptyList()));
assertThat(underTest.accept(ISSUE_1, COMPONENT_1)).isFalse();
assertThat(underTest.accept(ISSUE_2, COMPONENT_1)).isFalse();
@Test
public void ignore_some_rule_and_component() throws Exception {
- IssueFilter underTest = newIssueFilter(newSettings(asList("xoo:x1", "**/xoo/File1*"), Collections.<String>emptyList()));
+ IssueFilter underTest = newIssueFilter(newSettings(asList("xoo:x1", "**/xoo/File1*"), Collections.emptyList()));
assertThat(underTest.accept(ISSUE_1, COMPONENT_1)).isFalse();
assertThat(underTest.accept(ISSUE_1, COMPONENT_2)).isTrue();
public void ignore_many_rules() throws Exception {
IssueFilter underTest = newIssueFilter(newSettings(
asList("xoo:x1", "**/xoo/File1*", "xoo:x2", "**/xoo/File1*"),
- Collections.<String>emptyList()));
+ Collections.emptyList()));
assertThat(underTest.accept(ISSUE_1, COMPONENT_1)).isFalse();
assertThat(underTest.accept(ISSUE_1, COMPONENT_2)).isTrue();
@Test
public void include_all() throws Exception {
- IssueFilter underTest = newIssueFilter(newSettings(Collections.<String>emptyList(), asList("*", "**")));
+ IssueFilter underTest = newIssueFilter(newSettings(Collections.emptyList(), asList("*", "**")));
assertThat(underTest.accept(ISSUE_1, COMPONENT_1)).isTrue();
assertThat(underTest.accept(ISSUE_2, COMPONENT_1)).isTrue();
@Test
public void include_some_rule_and_component() throws Exception {
- IssueFilter underTest = newIssueFilter(newSettings(Collections.<String>emptyList(), asList("xoo:x1", "**/xoo/File1*")));
+ IssueFilter underTest = newIssueFilter(newSettings(Collections.emptyList(), asList("xoo:x1", "**/xoo/File1*")));
assertThat(underTest.accept(ISSUE_1, COMPONENT_1)).isTrue();
assertThat(underTest.accept(ISSUE_1, COMPONENT_2)).isFalse();
@Test
public void include_many_rules() throws Exception {
IssueFilter underTest = newIssueFilter(newSettings(
- Collections.<String>emptyList(),
+ Collections.emptyList(),
asList("xoo:x1", "**/xoo/File1*", "xoo:x2", "**/xoo/File1*")));
assertThat(underTest.accept(ISSUE_1, COMPONENT_1)).isTrue();
expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("File path pattern cannot be empty. Please check 'sonar.issue.ignore.multicriteria' settings");
- newIssueFilter(newSettings(asList("xoo:x1", ""), Collections.<String>emptyList()));
+ newIssueFilter(newSettings(asList("xoo:x1", ""), Collections.emptyList()));
}
@Test
expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("Rule key pattern cannot be empty. Please check 'sonar.issue.enforce.multicriteria' settings");
- newIssueFilter(newSettings(Collections.<String>emptyList(), asList("", "**")));
+ newIssueFilter(newSettings(Collections.emptyList(), asList("", "**")));
}
private IssueFilter newIssueFilter(MapSettings settings) {
- when(settingsRepository.getConfiguration(PROJECT)).thenReturn(settings.asConfig());
- return new IssueFilter(treeRootHolder, settingsRepository);
+ when(settingsRepository.getConfiguration()).thenReturn(settings.asConfig());
+ return new IssueFilter(settingsRepository);
}
private static MapSettings newSettings(List<String> exclusionsProperties, List<String> inclusionsProperties) {
import org.sonar.scanner.protocol.output.ScannerReport;
import org.sonar.scanner.protocol.output.ScannerReport.Component.ComponentType;
import org.sonar.scanner.protocol.output.ScannerReport.Component.FileStatus;
-import org.sonar.server.computation.task.projectanalysis.analysis.AnalysisMetadataHolderImpl;
-import org.sonar.server.computation.task.projectanalysis.analysis.MutableAnalysisMetadataHolder;
import org.sonar.server.computation.task.projectanalysis.analysis.MutableAnalysisMetadataHolderRule;
+import org.sonar.server.computation.task.projectanalysis.analysis.Project;
import org.sonar.server.computation.task.projectanalysis.batch.BatchReportReaderRule;
import org.sonar.server.computation.task.projectanalysis.component.Component;
import org.sonar.server.computation.task.projectanalysis.component.MutableTreeRootHolderRule;
public MutableAnalysisMetadataHolderRule analysisMetadataHolder = new MutableAnalysisMetadataHolderRule()
.setRootComponentRef(ROOT_REF)
.setAnalysisDate(ANALYSIS_DATE)
- .setBranch(null);
+ .setBranch(null)
+ .setProject(new Project("U1", REPORT_PROJECT_KEY, REPORT_PROJECT_KEY));
private DbClient dbClient = dbTester.getDbClient();
private BuildComponentTreeStep underTest = new BuildComponentTreeStep(dbClient, reportReader, treeRootHolder, analysisMetadataHolder);
verifyComponent(FILE_1_REF, REPORT_MODULE_KEY + ":" + REPORT_FILE_KEY_1, "DEFG");
}
- @Test
- public void use_branch_to_generate_keys() {
- MutableAnalysisMetadataHolder analysisMetadataHolder = new AnalysisMetadataHolderImpl()
- .setRootComponentRef(ROOT_REF)
- .setAnalysisDate(ANALYSIS_DATE)
- .setBranch("origin/master");
-
- BuildComponentTreeStep underTest = new BuildComponentTreeStep(dbClient, reportReader, treeRootHolder, analysisMetadataHolder);
-
- reportReader.putComponent(componentWithKey(ROOT_REF, PROJECT, REPORT_PROJECT_KEY, MODULE_REF));
- reportReader.putComponent(componentWithKey(MODULE_REF, MODULE, REPORT_MODULE_KEY, DIR_REF_1));
- reportReader.putComponent(componentWithPath(DIR_REF_1, DIRECTORY, REPORT_DIR_KEY_1, FILE_1_REF));
- reportReader.putComponent(componentWithPath(FILE_1_REF, FILE, REPORT_FILE_KEY_1));
-
- underTest.execute();
-
- verifyComponent(ROOT_REF, REPORT_PROJECT_KEY + ":origin/master");
- verifyComponent(MODULE_REF, REPORT_MODULE_KEY + ":origin/master");
- verifyComponent(DIR_REF_1, REPORT_MODULE_KEY + ":origin/master:" + REPORT_DIR_KEY_1);
- verifyComponent(FILE_1_REF, REPORT_MODULE_KEY + ":origin/master:" + REPORT_FILE_KEY_1);
- }
+// @Test
+// public void use_branch_to_generate_keys() {
+// MutableAnalysisMetadataHolder analysisMetadataHolder = new AnalysisMetadataHolderImpl()
+// .setRootComponentRef(ROOT_REF)
+// .setAnalysisDate(ANALYSIS_DATE)
+// .setBranch("origin/master");
+//
+// BuildComponentTreeStep underTest = new BuildComponentTreeStep(dbClient, reportReader, treeRootHolder, analysisMetadataHolder);
+//
+// reportReader.putComponent(componentWithKey(ROOT_REF, PROJECT, REPORT_PROJECT_KEY, MODULE_REF));
+// reportReader.putComponent(componentWithKey(MODULE_REF, MODULE, REPORT_MODULE_KEY, DIR_REF_1));
+// reportReader.putComponent(componentWithPath(DIR_REF_1, DIRECTORY, REPORT_DIR_KEY_1, FILE_1_REF));
+// reportReader.putComponent(componentWithPath(FILE_1_REF, FILE, REPORT_FILE_KEY_1));
+//
+// underTest.execute();
+//
+// verifyComponent(ROOT_REF, REPORT_PROJECT_KEY + ":origin/master");
+// verifyComponent(MODULE_REF, REPORT_MODULE_KEY + ":origin/master");
+// verifyComponent(DIR_REF_1, REPORT_MODULE_KEY + ":origin/master:" + REPORT_DIR_KEY_1);
+// verifyComponent(FILE_1_REF, REPORT_MODULE_KEY + ":origin/master:" + REPORT_FILE_KEY_1);
+// }
@Test
public void compute_keys_and_uuids_on_project_having_module_and_directory() {
private void setupRoot(Component root) {
treeRootHolder.setRoot(root);
- when(settingsRepository.getConfiguration(root)).thenReturn(settings.asConfig());
+ when(settingsRepository.getConfiguration()).thenReturn(settings.asConfig());
}
@Test
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.computation.task.projectanalysis.step;
+
+import com.google.common.base.Optional;
+import java.util.Collections;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.api.config.internal.MapSettings;
+import org.sonar.server.computation.task.projectanalysis.component.ConfigurationRepository;
+import org.sonar.server.computation.task.projectanalysis.qualitygate.MutableQualityGateHolderRule;
+import org.sonar.server.computation.task.projectanalysis.qualitygate.QualityGate;
+import org.sonar.server.computation.task.projectanalysis.qualitygate.QualityGateService;
+
+import static java.lang.String.format;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.guava.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+public class LoadQualityGateStepTest {
+
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+ @Rule
+ public MutableQualityGateHolderRule mutableQualityGateHolder = new MutableQualityGateHolderRule();
+
+ private ConfigurationRepository settingsRepository = mock(ConfigurationRepository.class);
+ private QualityGateService qualityGateService = mock(QualityGateService.class);
+
+ private LoadQualityGateStep underTest = new LoadQualityGateStep(settingsRepository, qualityGateService, mutableQualityGateHolder);
+
+ @Test
+ public void execute_sets_default_QualityGate_when_project_has_no_settings() {
+ when(settingsRepository.getConfiguration()).thenReturn(new MapSettings().asConfig());
+
+ underTest.execute();
+
+ verifyNoQualityGate();
+
+ // verify only project is processed
+ verify(settingsRepository).getConfiguration();
+ verifyNoMoreInteractions(settingsRepository);
+ }
+
+ @Test
+ public void execute_sets_default_QualityGate_when_property_value_is_not_a_long() {
+ expectedException.expect(IllegalStateException.class);
+ expectedException.expectMessage(format("Unsupported value (%s) in property sonar.qualitygate", "10 sds"));
+
+ when(settingsRepository.getConfiguration()).thenReturn(new MapSettings().setProperty("sonar.qualitygate", "10 sds").asConfig());
+
+ underTest.execute();
+ }
+
+ @Test
+ public void execute_sets_default_QualityGate_if_it_can_not_be_found_by_service() {
+ when(settingsRepository.getConfiguration()).thenReturn(new MapSettings().setProperty("sonar.qualitygate", 10).asConfig());
+ when(qualityGateService.findById(10)).thenReturn(Optional.absent());
+
+ underTest.execute();
+
+ verifyNoQualityGate();
+ }
+
+ @Test
+ public void execute_sets_QualityGate_if_it_can_be_found_by_service() {
+ QualityGate qualityGate = new QualityGate(465, "name", Collections.emptyList());
+
+ when(settingsRepository.getConfiguration()).thenReturn(new MapSettings().setProperty("sonar.qualitygate", 10).asConfig());
+ when(qualityGateService.findById(10)).thenReturn(Optional.of(qualityGate));
+
+ underTest.execute();
+
+ assertThat(mutableQualityGateHolder.getQualityGate().get()).isSameAs(qualityGate);
+ }
+
+ private void verifyNoQualityGate() {
+ assertThat(mutableQualityGateHolder.getQualityGate()).isAbsent();
+ }
+
+}
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
-import org.mockito.ArgumentCaptor;
import org.sonar.api.utils.MessageException;
import org.sonar.api.utils.System2;
import org.sonar.ce.queue.CeTask;
import org.sonar.core.platform.PluginRepository;
import org.sonar.db.DbClient;
import org.sonar.db.DbTester;
+import org.sonar.db.component.ComponentDto;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.scanner.protocol.output.ScannerReport;
import org.sonar.server.computation.task.projectanalysis.analysis.MutableAnalysisMetadataHolderRule;
import org.sonar.server.computation.task.projectanalysis.analysis.Organization;
import org.sonar.server.computation.task.projectanalysis.analysis.ScannerPlugin;
import org.sonar.server.computation.task.projectanalysis.batch.BatchReportReaderRule;
+import org.sonar.server.computation.task.projectanalysis.component.BranchLoader;
import org.sonar.server.computation.task.step.ComputationStep;
-import org.sonar.server.organization.BillingValidations;
-import org.sonar.server.organization.BillingValidations.BillingValidationsException;
-import org.sonar.server.organization.BillingValidationsProxy;
import org.sonar.server.organization.DefaultOrganizationProvider;
import org.sonar.server.organization.TestDefaultOrganizationProvider;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.tuple;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
public class LoadReportAnalysisMetadataHolderStepTest {
private static final String PROJECT_KEY = "project_key";
- private static final String BRANCH = "origin/master";
private static final long ANALYSIS_DATE = 123456789L;
@Rule
- public DbTester dbTester = DbTester.create(System2.INSTANCE);
+ public DbTester db = DbTester.create(System2.INSTANCE);
@Rule
public BatchReportReaderRule reportReader = new BatchReportReaderRule();
@Rule
@Rule
public ExpectedException expectedException = ExpectedException.none();
- private DbClient dbClient = dbTester.getDbClient();
- private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(dbTester);
- private BillingValidationsProxy billingValidations = mock(BillingValidationsProxy.class);
+ private DbClient dbClient = db.getDbClient();
+ private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(db);
private PluginRepository pluginRepository = mock(PluginRepository.class);
private ComputationStep underTest;
@Before
public void setUp() {
- CeTask defaultOrgCeTask = createCeTask(PROJECT_KEY, dbTester.getDefaultOrganization().getUuid());
+ CeTask defaultOrgCeTask = createCeTask(PROJECT_KEY, db.getDefaultOrganization().getUuid());
underTest = createStep(defaultOrgCeTask);
+ db.components().insertPublicProject(db.getDefaultOrganization(), p -> p.setDbKey(PROJECT_KEY));
}
@Test
assertThat(analysisMetadataHolder.getAnalysisDate()).isEqualTo(ANALYSIS_DATE);
}
- @Test
- public void set_branch() {
- reportReader.setMetadata(
- newBatchReportBuilder()
- .setBranch(BRANCH)
- .build());
-
- CeTask ceTask = createCeTask(PROJECT_KEY + ":" + BRANCH, dbTester.getDefaultOrganization().getUuid());
- ComputationStep underTest = createStep(ceTask);
-
- underTest.execute();
-
- assertThat(analysisMetadataHolder.getBranch()).isEqualTo(BRANCH);
- }
-
- @Test
- public void set_null_branch_when_nothing_in_the_report() {
- reportReader.setMetadata(
- newBatchReportBuilder()
- .build());
-
- underTest.execute();
-
- assertThat(analysisMetadataHolder.getBranch()).isNull();
- }
-
@Test
public void set_cross_project_duplication_to_true() {
reportReader.setMetadata(
public void execute_fails_with_MessageException_if_projectKey_is_null_in_CE_task() {
CeTask res = mock(CeTask.class);
when(res.getComponentUuid()).thenReturn("prj_uuid");
+ when(res.getOrganizationUuid()).thenReturn(defaultOrganizationProvider.get().getUuid());
reportReader.setMetadata(ScannerReport.Metadata.newBuilder().build());
ComputationStep underTest = createStep(res);
reportReader.setMetadata(
newBatchReportBuilder()
.build());
- OrganizationDto nonDefaultOrganizationDto = dbTester.organizations().insert();
+ OrganizationDto nonDefaultOrganizationDto = db.organizations().insert();
ComputationStep underTest = createStep(createCeTask(PROJECT_KEY, nonDefaultOrganizationDto.getUuid()));
expectedException.expect(MessageException.class);
expectedException.expectMessage("Report does not specify an OrganizationKey but it has been submitted to another organization (" +
- nonDefaultOrganizationDto.getKey() + ") than the default one (" + dbTester.getDefaultOrganization().getKey() + ")");
+ nonDefaultOrganizationDto.getKey() + ") than the default one (" + db.getDefaultOrganization().getKey() + ")");
underTest.execute();
}
underTest.execute();
Organization organization = analysisMetadataHolder.getOrganization();
- OrganizationDto defaultOrganization = dbTester.getDefaultOrganization();
+ OrganizationDto defaultOrganization = db.getDefaultOrganization();
assertThat(organization.getUuid()).isEqualTo(defaultOrganization.getUuid());
assertThat(organization.getKey()).isEqualTo(defaultOrganization.getKey());
assertThat(organization.getName()).isEqualTo(defaultOrganization.getName());
public void execute_set_organization_from_ce_task_when_organizationKey_is_set_in_report() {
reportReader.setMetadata(
newBatchReportBuilder()
- .setOrganizationKey(dbTester.getDefaultOrganization().getKey())
+ .setOrganizationKey(db.getDefaultOrganization().getKey())
.build());
underTest.execute();
Organization organization = analysisMetadataHolder.getOrganization();
- OrganizationDto defaultOrganization = dbTester.getDefaultOrganization();
+ OrganizationDto defaultOrganization = db.getDefaultOrganization();
assertThat(organization.getUuid()).isEqualTo(defaultOrganization.getUuid());
assertThat(organization.getKey()).isEqualTo(defaultOrganization.getKey());
assertThat(organization.getName()).isEqualTo(defaultOrganization.getName());
@Test
public void execute_set_non_default_organization_from_ce_task() {
- OrganizationDto nonDefaultOrganizationDto = dbTester.organizations().insert();
+ OrganizationDto nonDefaultOrganizationDto = db.organizations().insert();
+ ComponentDto project = db.components().insertPublicProject(nonDefaultOrganizationDto);
reportReader.setMetadata(
newBatchReportBuilder()
.setOrganizationKey(nonDefaultOrganizationDto.getKey())
+ .setProjectKey(project.getDbKey())
.build());
- ComputationStep underTest = createStep(createCeTask(PROJECT_KEY, nonDefaultOrganizationDto.getUuid()));
+ ComputationStep underTest = createStep(createCeTask(project.getDbKey(), nonDefaultOrganizationDto.getUuid()));
underTest.execute();
@Test
public void execute_ensures_that_report_has_quality_profiles_matching_the_project_organization() {
- OrganizationDto organization = dbTester.organizations().insert();
+ OrganizationDto organization = db.organizations().insert();
+ ComponentDto project = db.components().insertPublicProject(organization);
ScannerReport.Metadata.Builder metadataBuilder = newBatchReportBuilder();
- metadataBuilder.setOrganizationKey(organization.getKey());
+ metadataBuilder
+ .setOrganizationKey(organization.getKey())
+ .setProjectKey(project.getDbKey());
metadataBuilder.getMutableQprofilesPerLanguage().put("js", ScannerReport.Metadata.QProfile.newBuilder().setKey("p1").setName("Sonar way").setLanguage("js").build());
reportReader.setMetadata(metadataBuilder.build());
- dbTester.qualityProfiles().insert(organization, p -> p.setLanguage("js").setKee("p1"));
+ db.qualityProfiles().insert(organization, p -> p.setLanguage("js").setKee("p1"));
- ComputationStep underTest = createStep(createCeTask(PROJECT_KEY, organization.getUuid()));
+ ComputationStep underTest = createStep(createCeTask(project.getDbKey(), organization.getUuid()));
// no errors
underTest.execute();
@Test
public void execute_fails_with_MessageException_when_report_has_quality_profiles_on_other_organizations() {
- OrganizationDto organization1 = dbTester.organizations().insert();
- OrganizationDto organization2 = dbTester.organizations().insert();
+ OrganizationDto organization1 = db.organizations().insert();
+ OrganizationDto organization2 = db.organizations().insert();
+ ComponentDto projectInOrg1 = db.components().insertPublicProject(organization1);
ScannerReport.Metadata.Builder metadataBuilder = newBatchReportBuilder();
- metadataBuilder.setOrganizationKey(organization1.getKey());
+ metadataBuilder
+ .setOrganizationKey(organization1.getKey())
+ .setProjectKey(projectInOrg1.getDbKey());
metadataBuilder.getMutableQprofilesPerLanguage().put("js", ScannerReport.Metadata.QProfile.newBuilder().setKey("jsInOrg1").setName("Sonar way").setLanguage("js").build());
metadataBuilder.getMutableQprofilesPerLanguage().put("php", ScannerReport.Metadata.QProfile.newBuilder().setKey("phpInOrg2").setName("PHP way").setLanguage("php").build());
reportReader.setMetadata(metadataBuilder.build());
- dbTester.qualityProfiles().insert(organization1, p -> p.setLanguage("js").setKee("jsInOrg1"));
- dbTester.qualityProfiles().insert(organization2, p -> p.setLanguage("php").setKee("phpInOrg2"));
+ db.qualityProfiles().insert(organization1, p -> p.setLanguage("js").setKee("jsInOrg1"));
+ db.qualityProfiles().insert(organization2, p -> p.setLanguage("php").setKee("phpInOrg2"));
- ComputationStep underTest = createStep(createCeTask(PROJECT_KEY, organization1.getUuid()));
+ ComputationStep underTest = createStep(createCeTask(projectInOrg1.getDbKey(), organization1.getUuid()));
expectedException.expect(MessageException.class);
expectedException.expectMessage("Quality profiles with following keys don't exist in organization [" + organization1.getKey() + "]: phpInOrg2");
@Test
public void execute_does_not_fail_when_report_has_a_quality_profile_that_does_not_exist_anymore() {
- OrganizationDto organization = dbTester.organizations().insert();
+ OrganizationDto organization = db.organizations().insert();
+ ComponentDto project = db.components().insertPublicProject(organization);
ScannerReport.Metadata.Builder metadataBuilder = newBatchReportBuilder();
- metadataBuilder.setOrganizationKey(organization.getKey());
+ metadataBuilder
+ .setOrganizationKey(organization.getKey())
+ .setProjectKey(project.getDbKey());
metadataBuilder.getMutableQprofilesPerLanguage().put("js", ScannerReport.Metadata.QProfile.newBuilder().setKey("p1").setName("Sonar way").setLanguage("js").build());
reportReader.setMetadata(metadataBuilder.build());
- ComputationStep underTest = createStep(createCeTask(PROJECT_KEY, organization.getUuid()));
-
- underTest.execute();
- }
-
- @Test
- public void execute_fails_with_MessageException_when_organization_is_not_allowed_to_execute_analysis() {
- OrganizationDto organization = dbTester.organizations().insert();
- reportReader.setMetadata(newBatchReportBuilder()
- .setOrganizationKey(organization.getKey())
- .build());
- ComputationStep underTest = createStep(createCeTask(PROJECT_KEY, organization.getUuid()));
- doThrow(new BillingValidationsException("This organization cannot execute project analysis")).when(billingValidations)
- .checkOnProjectAnalysis(any(BillingValidations.Organization.class));
-
- expectedException.expect(MessageException.class);
- expectedException.expectMessage("This organization cannot execute project analysis");
+ ComputationStep underTest = createStep(createCeTask(project.getDbKey(), organization.getUuid()));
underTest.execute();
}
- @Test
- public void execute_does_no_fails_when_organization_is_allowed_to_execute_analysis() {
- OrganizationDto organization = dbTester.organizations().insert();
- reportReader.setMetadata(newBatchReportBuilder()
- .setOrganizationKey(organization.getKey())
- .build());
- ComputationStep underTest = createStep(createCeTask(PROJECT_KEY, organization.getUuid()));
-
- underTest.execute();
-
- ArgumentCaptor<BillingValidations.Organization> argumentCaptor = ArgumentCaptor.forClass(BillingValidations.Organization.class);
- verify(billingValidations).checkOnProjectAnalysis(argumentCaptor.capture());
- assertThat(argumentCaptor.getValue().getKey()).isEqualTo(organization.getKey());
- assertThat(argumentCaptor.getValue().getUuid()).isEqualTo(organization.getUuid());
- }
-
@Test
public void execute_read_plugins_from_report() {
ScannerReport.Metadata.Builder metadataBuilder = newBatchReportBuilder();
}
private LoadReportAnalysisMetadataHolderStep createStep(CeTask ceTask) {
- return new LoadReportAnalysisMetadataHolderStep(ceTask, reportReader, analysisMetadataHolder, defaultOrganizationProvider, dbClient, billingValidations, pluginRepository);
+ return new LoadReportAnalysisMetadataHolderStep(ceTask, reportReader, analysisMetadataHolder,
+ defaultOrganizationProvider, dbClient, new BranchLoader(analysisMetadataHolder), pluginRepository);
}
private static ScannerReport.Metadata.Builder newBatchReportBuilder() {
import org.sonar.db.DbSession;
import org.sonar.db.component.ComponentDao;
import org.sonar.server.computation.task.projectanalysis.analysis.AnalysisMetadataHolder;
+import org.sonar.server.computation.task.projectanalysis.component.BranchPersisterDelegate;
import org.sonar.server.computation.task.projectanalysis.component.Component;
import org.sonar.server.computation.task.projectanalysis.component.MutableDbIdsRepository;
import org.sonar.server.computation.task.projectanalysis.component.MutableDisabledComponentsHolder;
mock(MutableDbIdsRepository.class),
System2.INSTANCE,
mock(MutableDisabledComponentsHolder.class),
- mock(AnalysisMetadataHolder.class)).execute();
+ mock(AnalysisMetadataHolder.class),
+ mock(BranchPersisterDelegate.class)).execute();
}
}
private void verify_call_purge_method_of_the_purge_task(Component project) {
treeRootHolder.setRoot(project);
- when(settingsRepository.getConfiguration(project)).thenReturn(new MapSettings().asConfig());
+ when(settingsRepository.getConfiguration()).thenReturn(new MapSettings().asConfig());
dbIdsRepository.setComponentId(project, PROJECT_ID);
underTest.execute();
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2017 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.server.computation.task.projectanalysis.step;
-
-import com.google.common.base.Optional;
-import java.util.Collections;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.sonar.api.config.internal.MapSettings;
-import org.sonar.server.computation.task.projectanalysis.component.Component;
-import org.sonar.server.computation.task.projectanalysis.component.ConfigurationRepository;
-import org.sonar.server.computation.task.projectanalysis.component.ReportComponent;
-import org.sonar.server.computation.task.projectanalysis.component.TreeRootHolderRule;
-import org.sonar.server.computation.task.projectanalysis.component.VisitException;
-import org.sonar.server.computation.task.projectanalysis.qualitygate.Condition;
-import org.sonar.server.computation.task.projectanalysis.qualitygate.MutableQualityGateHolderRule;
-import org.sonar.server.computation.task.projectanalysis.qualitygate.QualityGate;
-import org.sonar.server.computation.task.projectanalysis.qualitygate.QualityGateService;
-
-import static java.lang.String.format;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.guava.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-import static org.sonar.test.ExceptionCauseMatcher.hasType;
-
-public class QualityGateLoadingStepTest {
- private static final String PROJECT_KEY = "project key";
- private static final ReportComponent PROJECT_ALONE = ReportComponent.builder(Component.Type.PROJECT, 1).setKey(PROJECT_KEY).build();
-
- @Rule
- public ExpectedException expectedException = ExpectedException.none();
- @Rule
- public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();
- @Rule
- public MutableQualityGateHolderRule mutableQualityGateHolder = new MutableQualityGateHolderRule();
-
- private ConfigurationRepository settingsRepository = mock(ConfigurationRepository.class);
- private QualityGateService qualityGateService = mock(QualityGateService.class);
-
- private LoadQualityGateStep underTest = new LoadQualityGateStep(treeRootHolder, settingsRepository, qualityGateService, mutableQualityGateHolder);
-
- @Test
- public void execute_sets_default_QualityGate_when_project_has_no_settings() {
- ReportComponent root = ReportComponent.builder(Component.Type.PROJECT, 1).setKey(PROJECT_KEY).addChildren(ReportComponent.builder(Component.Type.FILE, 2).build()).build();
- treeRootHolder.setRoot(root);
- when(settingsRepository.getConfiguration(root)).thenReturn(new MapSettings().asConfig());
-
- underTest.execute();
-
- verifyNoQualityGate();
-
- // verify only project is processed
- verify(settingsRepository).getConfiguration(root);
- verifyNoMoreInteractions(settingsRepository);
- }
-
- @Test
- public void execute_sets_default_QualityGate_when_property_value_is_not_a_long() {
- expectedException.expect(VisitException.class);
- expectedException.expectCause(
- hasType(IllegalStateException.class)
- .andMessage(format("Unsupported value (%s) in property sonar.qualitygate", "10 sds")));
-
- treeRootHolder.setRoot(PROJECT_ALONE);
- when(settingsRepository.getConfiguration(PROJECT_ALONE)).thenReturn(new MapSettings().setProperty("sonar.qualitygate", "10 sds").asConfig());
-
- underTest.execute();
- }
-
- @Test
- public void execute_sets_default_QualityGate_if_it_can_not_be_found_by_service() {
- treeRootHolder.setRoot(PROJECT_ALONE);
- when(settingsRepository.getConfiguration(PROJECT_ALONE)).thenReturn(new MapSettings().setProperty("sonar.qualitygate", 10).asConfig());
- when(qualityGateService.findById(10)).thenReturn(Optional.<QualityGate>absent());
-
- underTest.execute();
-
- verifyNoQualityGate();
- }
-
- @Test
- public void execute_sets_QualityGate_if_it_can_be_found_by_service() {
- QualityGate qualityGate = new QualityGate(465, "name", Collections.<Condition>emptyList());
-
- treeRootHolder.setRoot(PROJECT_ALONE);
- when(settingsRepository.getConfiguration(PROJECT_ALONE)).thenReturn(new MapSettings().setProperty("sonar.qualitygate", 10).asConfig());
- when(qualityGateService.findById(10)).thenReturn(Optional.of(qualityGate));
-
- underTest.execute();
-
- assertThat(mutableQualityGateHolder.getQualityGate().get()).isSameAs(qualityGate);
- }
-
- private void verifyNoQualityGate() {
- assertThat(mutableQualityGateHolder.getQualityGate()).isAbsent();
- }
-
-}
import com.google.common.base.Optional;
import java.text.SimpleDateFormat;
import java.util.Date;
-import java.util.Random;
+import java.util.function.Consumer;
import java.util.stream.Stream;
+import javax.annotation.Nullable;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.sonar.api.utils.DateUtils;
import org.sonar.api.utils.System2;
+import org.sonar.core.component.ComponentKeys;
import org.sonar.db.DbClient;
import org.sonar.db.DbTester;
+import org.sonar.db.component.BranchType;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.component.ComponentTesting;
-import org.sonar.db.organization.OrganizationDto;
+import org.sonar.scanner.protocol.output.ScannerReport;
import org.sonar.server.computation.task.projectanalysis.analysis.AnalysisMetadataHolderRule;
+import org.sonar.server.computation.task.projectanalysis.analysis.Branch;
+import org.sonar.server.computation.task.projectanalysis.analysis.Project;
+import org.sonar.server.computation.task.projectanalysis.component.BranchPersisterDelegate;
import org.sonar.server.computation.task.projectanalysis.component.Component;
import org.sonar.server.computation.task.projectanalysis.component.FileAttributes;
+import org.sonar.server.computation.task.projectanalysis.component.MainBranchImpl;
import org.sonar.server.computation.task.projectanalysis.component.MutableDbIdsRepositoryRule;
import org.sonar.server.computation.task.projectanalysis.component.MutableDisabledComponentsHolder;
import org.sonar.server.computation.task.projectanalysis.component.ReportComponent;
import org.sonar.server.computation.task.projectanalysis.component.TreeRootHolderRule;
import org.sonar.server.computation.task.step.ComputationStep;
+import static org.apache.commons.lang.StringUtils.isEmpty;
+import static org.apache.commons.lang.StringUtils.trimToNull;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.guava.api.Assertions.assertThat;
import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
import static org.sonar.db.component.ComponentDto.UUID_PATH_SEPARATOR;
import static org.sonar.db.component.ComponentTesting.newDirectory;
import static org.sonar.db.component.ComponentTesting.newModuleDto;
-import static org.sonar.db.component.ComponentTesting.newPrivateProjectDto;
import static org.sonar.server.computation.task.projectanalysis.component.Component.Type.DIRECTORY;
import static org.sonar.server.computation.task.projectanalysis.component.Component.Type.FILE;
import static org.sonar.server.computation.task.projectanalysis.component.Component.Type.PROJECT;
private static final String ORGANIZATION_UUID = "org1";
@Rule
- public DbTester dbTester = DbTester.create(System2.INSTANCE);
+ public DbTester db = DbTester.create(System2.INSTANCE);
@Rule
public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();
@Rule
.setOrganizationUuid(ORGANIZATION_UUID);
private System2 system2 = mock(System2.class);
- private DbClient dbClient = dbTester.getDbClient();
+ private DbClient dbClient = db.getDbClient();
private Date now;
private MutableDisabledComponentsHolder disabledComponentsHolder = mock(MutableDisabledComponentsHolder.class, RETURNS_DEEP_STUBS);
private PersistComponentsStep underTest;
+ private BranchPersisterDelegate branchPersister;
@Before
public void setup() throws Exception {
now = DATE_FORMAT.parse("2015-06-02");
when(system2.now()).thenReturn(now.getTime());
- dbTester.organizations().insertForUuid(ORGANIZATION_UUID);
- underTest = new PersistComponentsStep(dbClient, treeRootHolder, dbIdsRepository, system2, disabledComponentsHolder, analysisMetadataHolder);
+ db.organizations().insertForUuid(ORGANIZATION_UUID);
+ underTest = new PersistComponentsStep(dbClient, treeRootHolder, dbIdsRepository, system2, disabledComponentsHolder, analysisMetadataHolder, branchPersister);
}
@Override
@Test
public void persist_components() {
- ComponentDto projectDto = insertProject();
+ ComponentDto projectDto = prepareProject();
Component file = builder(FILE, 4).setUuid("DEFG").setKey("MODULE_KEY:src/main/java/dir/Foo.java")
.setPath("src/main/java/dir/Foo.java")
.setFileAttributes(new FileAttributes(false, "java", 1))
underTest.execute();
- assertThat(dbTester.countRowsOfTable("projects")).isEqualTo(4);
+ assertThat(db.countRowsOfTable("projects")).isEqualTo(4);
- ComponentDto moduleDto = dbClient.componentDao().selectByKey(dbTester.getSession(), MODULE_KEY).get();
+ ComponentDto moduleDto = dbClient.componentDao().selectByKey(db.getSession(), MODULE_KEY).get();
assertThat(moduleDto.getOrganizationUuid()).isEqualTo(ORGANIZATION_UUID);
assertThat(moduleDto.name()).isEqualTo("Module");
assertThat(moduleDto.description()).isEqualTo("Module description");
assertThat(moduleDto.getRootUuid()).isEqualTo(projectDto.uuid());
assertThat(moduleDto.getCreatedAt()).isEqualTo(now);
- ComponentDto directoryDto = dbClient.componentDao().selectByKey(dbTester.getSession(), "MODULE_KEY:src/main/java/dir").get();
+ ComponentDto directoryDto = dbClient.componentDao().selectByKey(db.getSession(), "MODULE_KEY:src/main/java/dir").get();
assertThat(directoryDto.getOrganizationUuid()).isEqualTo(ORGANIZATION_UUID);
assertThat(directoryDto.name()).isEqualTo("src/main/java/dir");
assertThat(directoryDto.description()).isNull();
assertThat(directoryDto.getRootUuid()).isEqualTo(moduleDto.uuid());
assertThat(directoryDto.getCreatedAt()).isEqualTo(now);
- ComponentDto fileDto = dbClient.componentDao().selectByKey(dbTester.getSession(), "MODULE_KEY:src/main/java/dir/Foo.java").get();
+ ComponentDto fileDto = dbClient.componentDao().selectByKey(db.getSession(), "MODULE_KEY:src/main/java/dir/Foo.java").get();
assertThat(fileDto.getOrganizationUuid()).isEqualTo(ORGANIZATION_UUID);
assertThat(fileDto.name()).isEqualTo("Foo.java");
assertThat(fileDto.description()).isNull();
assertThat(dbIdsRepository.getComponentId(file)).isEqualTo(fileDto.getId());
}
+ @Test
+ public void persist_components_of_existing_branch() {
+ ComponentDto project = prepareBranch("feature/foo");
+ Component file = builder(FILE, 4).setUuid("DEFG").setKey("MODULE_KEY:src/main/java/dir/Foo.java")
+ .setPath("src/main/java/dir/Foo.java")
+ .setFileAttributes(new FileAttributes(false, "java", 1))
+ .build();
+ Component directory = builder(DIRECTORY, 3).setUuid("CDEF").setKey("MODULE_KEY:src/main/java/dir")
+ .setPath("src/main/java/dir")
+ .addChildren(file)
+ .build();
+ Component module = builder(Component.Type.MODULE, 2).setUuid("BCDE").setKey(MODULE_KEY)
+ .setPath("module")
+ .setName("Module")
+ .setDescription("Module description")
+ .addChildren(directory)
+ .build();
+ Component treeRoot = asTreeRoot(project)
+ .addChildren(module)
+ .build();
+ treeRootHolder.setRoot(treeRoot);
+
+ underTest.execute();
+
+ assertThat(db.countRowsOfTable("projects")).isEqualTo(4);
+
+ ComponentDto moduleDto = dbClient.componentDao().selectByKey(db.getSession(), MODULE_KEY).get();
+ assertThat(moduleDto.getOrganizationUuid()).isEqualTo(ORGANIZATION_UUID);
+ assertThat(moduleDto.name()).isEqualTo("Module");
+ assertThat(moduleDto.description()).isEqualTo("Module description");
+ assertThat(moduleDto.path()).isEqualTo("module");
+ assertThat(moduleDto.uuid()).isEqualTo("BCDE");
+ assertThat(moduleDto.getUuidPath()).isEqualTo(project.getUuidPath() + project.uuid() + UUID_PATH_SEPARATOR);
+ assertThat(moduleDto.moduleUuid()).isEqualTo(project.uuid());
+ assertThat(moduleDto.moduleUuidPath()).isEqualTo(project.moduleUuidPath() + moduleDto.uuid() + ".");
+ assertThat(moduleDto.getMainBranchProjectUuid()).isEqualTo(project.uuid());
+ assertThat(moduleDto.projectUuid()).isEqualTo(project.uuid());
+ assertThat(moduleDto.qualifier()).isEqualTo("BRC");
+ assertThat(moduleDto.scope()).isEqualTo("PRJ");
+ assertThat(moduleDto.getRootUuid()).isEqualTo(project.uuid());
+ assertThat(moduleDto.getCreatedAt()).isEqualTo(now);
+
+ ComponentDto directoryDto = dbClient.componentDao().selectByKey(db.getSession(), "MODULE_KEY:src/main/java/dir").get();
+ assertThat(directoryDto.getOrganizationUuid()).isEqualTo(ORGANIZATION_UUID);
+ assertThat(directoryDto.name()).isEqualTo("src/main/java/dir");
+ assertThat(directoryDto.description()).isNull();
+ assertThat(directoryDto.path()).isEqualTo("src/main/java/dir");
+ assertThat(directoryDto.uuid()).isEqualTo("CDEF");
+ assertThat(directoryDto.getUuidPath()).isEqualTo(moduleDto.getUuidPath() + moduleDto.uuid() + UUID_PATH_SEPARATOR);
+ assertThat(directoryDto.moduleUuid()).isEqualTo(moduleDto.uuid());
+ assertThat(directoryDto.moduleUuidPath()).isEqualTo(moduleDto.moduleUuidPath());
+ assertThat(directoryDto.getMainBranchProjectUuid()).isEqualTo(project.uuid());
+ assertThat(directoryDto.projectUuid()).isEqualTo(project.uuid());
+ assertThat(directoryDto.qualifier()).isEqualTo("DIR");
+ assertThat(directoryDto.scope()).isEqualTo("DIR");
+ assertThat(directoryDto.getRootUuid()).isEqualTo(moduleDto.uuid());
+ assertThat(directoryDto.getCreatedAt()).isEqualTo(now);
+
+ ComponentDto fileDto = dbClient.componentDao().selectByKey(db.getSession(), "MODULE_KEY:src/main/java/dir/Foo.java").get();
+ assertThat(fileDto.getOrganizationUuid()).isEqualTo(ORGANIZATION_UUID);
+ assertThat(fileDto.name()).isEqualTo("Foo.java");
+ assertThat(fileDto.description()).isNull();
+ assertThat(fileDto.path()).isEqualTo("src/main/java/dir/Foo.java");
+ assertThat(fileDto.language()).isEqualTo("java");
+ assertThat(fileDto.uuid()).isEqualTo("DEFG");
+ assertThat(fileDto.getUuidPath()).isEqualTo(directoryDto.getUuidPath() + directoryDto.uuid() + UUID_PATH_SEPARATOR);
+ assertThat(fileDto.moduleUuid()).isEqualTo(moduleDto.uuid());
+ assertThat(fileDto.moduleUuidPath()).isEqualTo(moduleDto.moduleUuidPath());
+ assertThat(fileDto.getMainBranchProjectUuid()).isEqualTo(project.uuid());
+ assertThat(fileDto.projectUuid()).isEqualTo(project.uuid());
+ assertThat(fileDto.qualifier()).isEqualTo("FIL");
+ assertThat(fileDto.scope()).isEqualTo("FIL");
+ assertThat(fileDto.getRootUuid()).isEqualTo(moduleDto.uuid());
+ assertThat(fileDto.getCreatedAt()).isEqualTo(now);
+
+ assertThat(dbIdsRepository.getComponentId(module)).isEqualTo(moduleDto.getId());
+ assertThat(dbIdsRepository.getComponentId(directory)).isEqualTo(directoryDto.getId());
+ assertThat(dbIdsRepository.getComponentId(file)).isEqualTo(fileDto.getId());
+ }
+
@Test
public void persist_file_directly_attached_on_root_directory() {
- ComponentDto projectDto = insertProject();
+ ComponentDto projectDto = prepareProject();
treeRootHolder.setRoot(
asTreeRoot(projectDto)
.addChildren(
- builder(DIRECTORY, 2).setUuid("CDEF").setKey(PROJECT_KEY + ":/").setPath("/")
+ builder(DIRECTORY, 2).setUuid("CDEF").setKey(projectDto.getDbKey() + ":/").setPath("/")
.addChildren(
- builder(FILE, 3).setUuid("DEFG").setKey(PROJECT_KEY + ":pom.xml").setPath("pom.xml")
+ builder(FILE, 3).setUuid("DEFG").setKey(projectDto.getDbKey() + ":pom.xml").setPath("pom.xml")
.build())
.build())
.build());
underTest.execute();
- ComponentDto directory = dbClient.componentDao().selectByKey(dbTester.getSession(), "PROJECT_KEY:/").get();
+ ComponentDto directory = dbClient.componentDao().selectByKey(db.getSession(), projectDto.getDbKey() + ":/").get();
assertThat(directory.name()).isEqualTo("/");
assertThat(directory.path()).isEqualTo("/");
- ComponentDto file = dbClient.componentDao().selectByKey(dbTester.getSession(), "PROJECT_KEY:pom.xml").get();
+ ComponentDto file = dbClient.componentDao().selectByKey(db.getSession(), projectDto.getDbKey() + ":pom.xml").get();
assertThat(file.name()).isEqualTo("pom.xml");
assertThat(file.path()).isEqualTo("pom.xml");
}
@Test
public void persist_unit_test() {
- ComponentDto projectDto = insertProject();
+ ComponentDto projectDto = prepareProject();
treeRootHolder.setRoot(
asTreeRoot(projectDto)
.addChildren(
underTest.execute();
- ComponentDto file = dbClient.componentDao().selectByKey(dbTester.getSession(), PROJECT_KEY + ":src/test/java/dir/FooTest.java").get();
+ ComponentDto file = dbClient.componentDao().selectByKey(db.getSession(), PROJECT_KEY + ":src/test/java/dir/FooTest.java").get();
assertThat(file.name()).isEqualTo("FooTest.java");
assertThat(file.path()).isEqualTo("src/test/java/dir/FooTest.java");
assertThat(file.qualifier()).isEqualTo("UTS");
@Test
public void persist_only_new_components() {
// Project and module already exists
- ComponentDto project = newPrivateProjectDto(dbTester.getDefaultOrganization(), "ABCD").setDbKey(PROJECT_KEY).setName("Project");
- dbClient.componentDao().insert(dbTester.getSession(), project);
+ ComponentDto project = prepareProject();
ComponentDto module = ComponentTesting.newModuleDto("BCDE", project).setDbKey(MODULE_KEY).setName("Module");
- dbClient.componentDao().insert(dbTester.getSession(), module);
- dbTester.getSession().commit();
+ dbClient.componentDao().insert(db.getSession(), module);
+ db.getSession().commit();
treeRootHolder.setRoot(
- builder(PROJECT, 1).setUuid("ABCD").setKey(PROJECT_KEY)
+ builder(PROJECT, 1).setUuid(project.uuid()).setKey(project.getDbKey())
.setName("Project")
.addChildren(
builder(Component.Type.MODULE, 2).setUuid("BCDE").setKey(MODULE_KEY)
underTest.execute();
- assertThat(dbTester.countRowsOfTable("projects")).isEqualTo(4);
+ assertThat(db.countRowsOfTable("projects")).isEqualTo(4);
- ComponentDto projectReloaded = dbClient.componentDao().selectByKey(dbTester.getSession(), PROJECT_KEY).get();
+ ComponentDto projectReloaded = dbClient.componentDao().selectByKey(db.getSession(), project.getDbKey()).get();
assertThat(projectReloaded.getId()).isEqualTo(project.getId());
assertThat(projectReloaded.uuid()).isEqualTo(project.uuid());
assertThat(projectReloaded.getUuidPath()).isEqualTo(UUID_PATH_OF_ROOT);
assertThat(projectReloaded.getMainBranchProjectUuid()).isNull();
- ComponentDto moduleReloaded = dbClient.componentDao().selectByKey(dbTester.getSession(), MODULE_KEY).get();
+ ComponentDto moduleReloaded = dbClient.componentDao().selectByKey(db.getSession(), MODULE_KEY).get();
assertThat(moduleReloaded.getId()).isEqualTo(module.getId());
assertThat(moduleReloaded.uuid()).isEqualTo(module.uuid());
assertThat(moduleReloaded.getUuidPath()).isEqualTo(module.getUuidPath());
assertThat(moduleReloaded.getRootUuid()).isEqualTo(module.getRootUuid());
assertThat(moduleReloaded.getMainBranchProjectUuid()).isNull();
- ComponentDto directory = dbClient.componentDao().selectByKey(dbTester.getSession(), "MODULE_KEY:src/main/java/dir").get();
+ ComponentDto directory = dbClient.componentDao().selectByKey(db.getSession(), "MODULE_KEY:src/main/java/dir").get();
assertThat(directory.getUuidPath()).isEqualTo(directory.getUuidPath());
assertThat(directory.moduleUuid()).isEqualTo(module.uuid());
assertThat(directory.moduleUuidPath()).isEqualTo(module.moduleUuidPath());
assertThat(directory.getRootUuid()).isEqualTo(module.uuid());
assertThat(directory.getMainBranchProjectUuid()).isNull();
- ComponentDto file = dbClient.componentDao().selectByKey(dbTester.getSession(), "MODULE_KEY:src/main/java/dir/Foo.java").get();
+ ComponentDto file = dbClient.componentDao().selectByKey(db.getSession(), "MODULE_KEY:src/main/java/dir/Foo.java").get();
assertThat(file.getUuidPath()).isEqualTo(file.getUuidPath());
assertThat(file.moduleUuid()).isEqualTo(module.uuid());
assertThat(file.moduleUuidPath()).isEqualTo(module.moduleUuidPath());
@Test
public void compute_root_uuid() {
- ComponentDto project = insertProject();
+ ComponentDto project = prepareProject();
treeRootHolder.setRoot(
asTreeRoot(project)
.addChildren(
underTest.execute();
- assertThat(dbTester.countRowsOfTable("projects")).isEqualTo(5);
+ assertThat(db.countRowsOfTable("projects")).isEqualTo(5);
- Optional<ComponentDto> module = dbClient.componentDao().selectByKey(dbTester.getSession(), MODULE_KEY);
+ Optional<ComponentDto> module = dbClient.componentDao().selectByKey(db.getSession(), MODULE_KEY);
assertThat(module).isPresent();
assertThat(module.get().getRootUuid()).isEqualTo(project.uuid());
- Optional<ComponentDto> subModule1 = dbClient.componentDao().selectByKey(dbTester.getSession(), "SUB_MODULE_1_KEY");
+ Optional<ComponentDto> subModule1 = dbClient.componentDao().selectByKey(db.getSession(), "SUB_MODULE_1_KEY");
assertThat(subModule1).isPresent();
assertThat(subModule1.get().getRootUuid()).isEqualTo(project.uuid());
- Optional<ComponentDto> subModule2 = dbClient.componentDao().selectByKey(dbTester.getSession(), "SUB_MODULE_2_KEY");
+ Optional<ComponentDto> subModule2 = dbClient.componentDao().selectByKey(db.getSession(), "SUB_MODULE_2_KEY");
assertThat(subModule2).isPresent();
assertThat(subModule2.get().getRootUuid()).isEqualTo(project.uuid());
- Optional<ComponentDto> directory = dbClient.componentDao().selectByKey(dbTester.getSession(), "SUB_MODULE_2_KEY:src/main/java/dir");
+ Optional<ComponentDto> directory = dbClient.componentDao().selectByKey(db.getSession(), "SUB_MODULE_2_KEY:src/main/java/dir");
assertThat(directory).isPresent();
assertThat(directory.get().getRootUuid()).isEqualTo(subModule2.get().uuid());
}
- private ReportComponent.Builder asTreeRoot(ComponentDto project) {
- return builder(PROJECT, 1).setUuid(project.uuid()).setKey(project.getDbKey()).setName(project.name());
- }
-
- public ComponentDto insertProject() {
- return dbTester.components().insertPrivateProject(dbTester.organizations().insert());
- }
-
@Test
public void persist_multi_modules() {
- ComponentDto project = insertProject();
+ ComponentDto project = prepareProject();
treeRootHolder.setRoot(
asTreeRoot(project)
.setName("Project")
underTest.execute();
- assertThat(dbTester.countRowsOfTable("projects")).isEqualTo(4);
+ assertThat(db.countRowsOfTable("projects")).isEqualTo(4);
- ComponentDto moduleA = dbClient.componentDao().selectByKey(dbTester.getSession(), "MODULE_A").get();
+ ComponentDto moduleA = dbClient.componentDao().selectByKey(db.getSession(), "MODULE_A").get();
assertThat(moduleA.getUuidPath()).isEqualTo(project.getUuidPath() + project.uuid() + UUID_PATH_SEPARATOR);
assertThat(moduleA.moduleUuid()).isEqualTo(project.uuid());
assertThat(moduleA.moduleUuidPath()).isEqualTo(project.moduleUuidPath() + moduleA.uuid() + ".");
assertThat(moduleA.getRootUuid()).isEqualTo(project.uuid());
- ComponentDto subModuleA = dbClient.componentDao().selectByKey(dbTester.getSession(), "SUB_MODULE_A").get();
+ ComponentDto subModuleA = dbClient.componentDao().selectByKey(db.getSession(), "SUB_MODULE_A").get();
assertThat(subModuleA.getUuidPath()).isEqualTo(moduleA.getUuidPath() + moduleA.uuid() + UUID_PATH_SEPARATOR);
assertThat(subModuleA.moduleUuid()).isEqualTo(moduleA.uuid());
assertThat(subModuleA.moduleUuidPath()).isEqualTo(moduleA.moduleUuidPath() + subModuleA.uuid() + ".");
assertThat(subModuleA.getRootUuid()).isEqualTo(project.uuid());
- ComponentDto moduleB = dbClient.componentDao().selectByKey(dbTester.getSession(), "MODULE_B").get();
+ ComponentDto moduleB = dbClient.componentDao().selectByKey(db.getSession(), "MODULE_B").get();
assertThat(moduleB.getUuidPath()).isEqualTo(project.getUuidPath() + project.uuid() + UUID_PATH_SEPARATOR);
assertThat(moduleB.moduleUuid()).isEqualTo(project.uuid());
assertThat(moduleB.moduleUuidPath()).isEqualTo(project.moduleUuidPath() + moduleB.uuid() + ".");
@Test
public void nothing_to_persist() {
- ComponentDto project = newPrivateProjectDto(dbTester.organizations().insert(), "ABCD").setDbKey(PROJECT_KEY).setName("Project");
- dbClient.componentDao().insert(dbTester.getSession(), project);
+ ComponentDto project = prepareProject();
ComponentDto module = ComponentTesting.newModuleDto("BCDE", project).setDbKey(MODULE_KEY).setName("Module");
- dbClient.componentDao().insert(dbTester.getSession(), module);
+ dbClient.componentDao().insert(db.getSession(), module);
ComponentDto directory = ComponentTesting.newDirectory(module, "src/main/java/dir").setUuid("CDEF").setDbKey("MODULE_KEY:src/main/java/dir");
ComponentDto file = ComponentTesting.newFileDto(module, directory, "DEFG").setPath("src/main/java/dir/Foo.java").setName("Foo.java")
.setDbKey("MODULE_KEY:src/main/java/dir/Foo.java");
- dbClient.componentDao().insert(dbTester.getSession(), directory, file);
- dbTester.getSession().commit();
+ dbClient.componentDao().insert(db.getSession(), directory, file);
+ db.getSession().commit();
treeRootHolder.setRoot(
- builder(PROJECT, 1).setUuid("ABCD").setKey(PROJECT_KEY)
+ builder(PROJECT, 1).setUuid(project.uuid()).setKey(project.getDbKey())
.setName("Project")
.addChildren(
builder(Component.Type.MODULE, 2).setUuid("BCDE").setKey(MODULE_KEY)
underTest.execute();
- assertThat(dbTester.countRowsOfTable("projects")).isEqualTo(4);
- assertThat(dbClient.componentDao().selectByKey(dbTester.getSession(), PROJECT_KEY).get().getId()).isEqualTo(project.getId());
- assertThat(dbClient.componentDao().selectByKey(dbTester.getSession(), MODULE_KEY).get().getId()).isEqualTo(module.getId());
- assertThat(dbClient.componentDao().selectByKey(dbTester.getSession(), "MODULE_KEY:src/main/java/dir").get().getId()).isEqualTo(directory.getId());
- assertThat(dbClient.componentDao().selectByKey(dbTester.getSession(), "MODULE_KEY:src/main/java/dir/Foo.java").get().getId()).isEqualTo(file.getId());
+ assertThat(db.countRowsOfTable("projects")).isEqualTo(4);
+ assertThat(dbClient.componentDao().selectByKey(db.getSession(), project.getDbKey()).get().getId()).isEqualTo(project.getId());
+ assertThat(dbClient.componentDao().selectByKey(db.getSession(), MODULE_KEY).get().getId()).isEqualTo(module.getId());
+ assertThat(dbClient.componentDao().selectByKey(db.getSession(), "MODULE_KEY:src/main/java/dir").get().getId()).isEqualTo(directory.getId());
+ assertThat(dbClient.componentDao().selectByKey(db.getSession(), "MODULE_KEY:src/main/java/dir/Foo.java").get().getId()).isEqualTo(file.getId());
- ComponentDto projectReloaded = dbClient.componentDao().selectByKey(dbTester.getSession(), PROJECT_KEY).get();
+ ComponentDto projectReloaded = dbClient.componentDao().selectByKey(db.getSession(), project.getDbKey()).get();
assertThat(projectReloaded.getId()).isEqualTo(project.getId());
assertThat(projectReloaded.uuid()).isEqualTo(project.uuid());
assertThat(projectReloaded.moduleUuid()).isEqualTo(project.moduleUuid());
assertThat(projectReloaded.projectUuid()).isEqualTo(project.projectUuid());
assertThat(projectReloaded.getRootUuid()).isEqualTo(project.getRootUuid());
- ComponentDto moduleReloaded = dbClient.componentDao().selectByKey(dbTester.getSession(), MODULE_KEY).get();
+ ComponentDto moduleReloaded = dbClient.componentDao().selectByKey(db.getSession(), MODULE_KEY).get();
assertThat(moduleReloaded.getId()).isEqualTo(module.getId());
assertThat(moduleReloaded.uuid()).isEqualTo(module.uuid());
assertThat(moduleReloaded.getUuidPath()).isEqualTo(module.getUuidPath());
assertThat(moduleReloaded.projectUuid()).isEqualTo(module.projectUuid());
assertThat(moduleReloaded.getRootUuid()).isEqualTo(module.getRootUuid());
- ComponentDto directoryReloaded = dbClient.componentDao().selectByKey(dbTester.getSession(), "MODULE_KEY:src/main/java/dir").get();
+ ComponentDto directoryReloaded = dbClient.componentDao().selectByKey(db.getSession(), "MODULE_KEY:src/main/java/dir").get();
assertThat(directoryReloaded.uuid()).isEqualTo(directory.uuid());
assertThat(directoryReloaded.getUuidPath()).isEqualTo(directory.getUuidPath());
assertThat(directoryReloaded.moduleUuid()).isEqualTo(directory.moduleUuid());
assertThat(directoryReloaded.name()).isEqualTo(directory.name());
assertThat(directoryReloaded.path()).isEqualTo(directory.path());
- ComponentDto fileReloaded = dbClient.componentDao().selectByKey(dbTester.getSession(), "MODULE_KEY:src/main/java/dir/Foo.java").get();
+ ComponentDto fileReloaded = dbClient.componentDao().selectByKey(db.getSession(), "MODULE_KEY:src/main/java/dir/Foo.java").get();
assertThat(fileReloaded.uuid()).isEqualTo(file.uuid());
assertThat(fileReloaded.getUuidPath()).isEqualTo(file.getUuidPath());
assertThat(fileReloaded.moduleUuid()).isEqualTo(file.moduleUuid());
@Test
public void update_module_name_and_description() {
- ComponentDto project = newPrivateProjectDto(dbTester.getDefaultOrganization(), "ABCD").setDbKey(PROJECT_KEY).setName("Project").setDescription("Project description");
- dbClient.componentDao().insert(dbTester.getSession(), project);
+ ComponentDto project = prepareProject(p -> p.setName("Project").setDescription("Project description"));
ComponentDto module = ComponentTesting.newModuleDto("BCDE", project).setDbKey(MODULE_KEY).setName("Module");
- dbClient.componentDao().insert(dbTester.getSession(), module);
- dbTester.getSession().commit();
+ dbClient.componentDao().insert(db.getSession(), module);
+ db.getSession().commit();
treeRootHolder.setRoot(
- builder(PROJECT, 1).setUuid("ABCD").setKey(PROJECT_KEY)
+ builder(PROJECT, 1)
+ .setUuid(project.uuid())
+ .setKey(project.getDbKey())
.setName("New Project")
.setDescription("New project description")
.addChildren(
underTest.execute();
// functional transaction not finished, "A-fields" are not updated yet
- assertNameAndDescription(PROJECT_KEY, "Project", "Project description");
+ assertNameAndDescription(project.getDbKey(), "Project", "Project description");
assertNameAndDescription(MODULE_KEY, "Module", null);
// commit functional transaction -> copies B-fields to A-fields
- dbClient.componentDao().applyBChangesForRootComponentUuid(dbTester.getSession(), "ABCD");
- assertNameAndDescription(PROJECT_KEY, "New Project", "New project description");
+ dbClient.componentDao().applyBChangesForRootComponentUuid(db.getSession(), project.uuid());
+ assertNameAndDescription(project.getDbKey(), "New Project", "New project description");
assertNameAndDescription(MODULE_KEY, "New Module", "New module description");
}
private void assertNameAndDescription(String key, String expectedName, String expectedDescription) {
- ComponentDto dto = dbClient.componentDao().selectByKey(dbTester.getSession(), key).get();
+ ComponentDto dto = dbClient.componentDao().selectByKey(db.getSession(), key).get();
assertThat(dto.name()).isEqualTo(expectedName);
assertThat(dto.description()).isEqualTo(expectedDescription);
}
@Test
public void update_module_path() {
- ComponentDto project = newPrivateProjectDto(dbTester.organizations().insert(), "ABCD").setDbKey(PROJECT_KEY).setName("Project");
- dbClient.componentDao().insert(dbTester.getSession(), project);
+ ComponentDto project = prepareProject();
ComponentDto module = ComponentTesting.newModuleDto("BCDE", project).setDbKey(MODULE_KEY).setName("Module").setPath("path");
- dbClient.componentDao().insert(dbTester.getSession(), module);
- dbTester.getSession().commit();
+ dbClient.componentDao().insert(db.getSession(), module);
+ db.getSession().commit();
treeRootHolder.setRoot(
- builder(PROJECT, 1).setUuid("ABCD").setKey(PROJECT_KEY)
+ builder(PROJECT, 1).setUuid(project.uuid()).setKey(project.getDbKey())
.setName("Project")
.addChildren(
builder(Component.Type.MODULE, 2).setUuid("BCDE").setKey(MODULE_KEY)
underTest.execute();
- assertThat(dbClient.componentDao().selectByKey(dbTester.getSession(), MODULE_KEY).get().path()).isEqualTo("path");
+ assertThat(dbClient.componentDao().selectByKey(db.getSession(), MODULE_KEY).get().path()).isEqualTo("path");
// commit the functional transaction
- dbClient.componentDao().applyBChangesForRootComponentUuid(dbTester.getSession(), project.uuid());
- assertThat(dbClient.componentDao().selectByKey(dbTester.getSession(), MODULE_KEY).get().path()).isEqualTo("New path");
+ dbClient.componentDao().applyBChangesForRootComponentUuid(db.getSession(), project.uuid());
+ assertThat(dbClient.componentDao().selectByKey(db.getSession(), MODULE_KEY).get().path()).isEqualTo("New path");
}
@Test
public void update_module_uuid_when_moving_a_module() {
- ComponentDto project = newPrivateProjectDto(dbTester.getDefaultOrganization(), "ABCD").setDbKey(PROJECT_KEY).setName("Project");
- dbClient.componentDao().insert(dbTester.getSession(), project);
+ ComponentDto project = prepareProject();
ComponentDto moduleA = ComponentTesting.newModuleDto("EDCB", project)
.setDbKey("MODULE_A")
.setName("Module A");
ComponentDto moduleB = ComponentTesting.newModuleDto("BCDE", project)
.setDbKey("MODULE_B")
.setName("Module B");
- dbClient.componentDao().insert(dbTester.getSession(), moduleA, moduleB);
+ dbClient.componentDao().insert(db.getSession(), moduleA, moduleB);
ComponentDto directory = ComponentTesting.newDirectory(moduleB, "src/main/java/dir").setUuid("CDEF").setDbKey("MODULE_B:src/main/java/dir");
ComponentDto file = ComponentTesting.newFileDto(moduleB, directory, "DEFG").setPath("src/main/java/dir/Foo.java").setName("Foo.java")
.setDbKey("MODULE_B:src/main/java/dir/Foo.java");
- dbClient.componentDao().insert(dbTester.getSession(), directory, file);
- dbTester.getSession().commit();
+ dbClient.componentDao().insert(db.getSession(), directory, file);
+ db.getSession().commit();
treeRootHolder.setRoot(
- builder(PROJECT, 1).setUuid("ABCD").setKey(PROJECT_KEY)
+ builder(PROJECT, 1).setUuid(project.uuid()).setKey(project.getDbKey())
.setName("Project")
.addChildren(
builder(Component.Type.MODULE, 2).setUuid("EDCB").setKey("MODULE_A")
underTest.execute();
// commit the functional transaction
- dbClient.componentDao().applyBChangesForRootComponentUuid(dbTester.getSession(), project.uuid());
- dbTester.commit();
+ dbClient.componentDao().applyBChangesForRootComponentUuid(db.getSession(), project.uuid());
+ db.commit();
- assertThat(dbTester.countRowsOfTable("projects")).isEqualTo(5);
+ assertThat(db.countRowsOfTable("projects")).isEqualTo(5);
- ComponentDto moduleAreloaded = dbClient.componentDao().selectByKey(dbTester.getSession(), "MODULE_A").get();
+ ComponentDto moduleAreloaded = dbClient.componentDao().selectByKey(db.getSession(), "MODULE_A").get();
- ComponentDto moduleBReloaded = dbClient.componentDao().selectByKey(dbTester.getSession(), "MODULE_B").get();
+ ComponentDto moduleBReloaded = dbClient.componentDao().selectByKey(db.getSession(), "MODULE_B").get();
assertThat(moduleBReloaded).isNotNull();
assertThat(moduleBReloaded.uuid()).isEqualTo(moduleB.uuid());
assertThat(moduleBReloaded.getUuidPath()).isEqualTo(moduleBReloaded.getUuidPath());
assertThat(moduleBReloaded.projectUuid()).isEqualTo(project.uuid());
assertThat(moduleBReloaded.getRootUuid()).isEqualTo(project.uuid());
- ComponentDto directoryReloaded = dbClient.componentDao().selectByKey(dbTester.getSession(), "MODULE_B:src/main/java/dir").get();
+ ComponentDto directoryReloaded = dbClient.componentDao().selectByKey(db.getSession(), "MODULE_B:src/main/java/dir").get();
assertThat(directoryReloaded).isNotNull();
assertThat(directoryReloaded.uuid()).isEqualTo(directory.uuid());
assertThat(directoryReloaded.getUuidPath()).isEqualTo(directoryReloaded.getUuidPath());
assertThat(directoryReloaded.projectUuid()).isEqualTo(project.uuid());
assertThat(directoryReloaded.getRootUuid()).isEqualTo(moduleBReloaded.uuid());
- ComponentDto fileReloaded = dbClient.componentDao().selectByKey(dbTester.getSession(), "MODULE_B:src/main/java/dir/Foo.java").get();
+ ComponentDto fileReloaded = dbClient.componentDao().selectByKey(db.getSession(), "MODULE_B:src/main/java/dir/Foo.java").get();
assertThat(fileReloaded).isNotNull();
assertThat(fileReloaded.uuid()).isEqualTo(file.uuid());
assertThat(fileReloaded.getUuidPath()).isEqualTo(fileReloaded.getUuidPath());
@Test
public void do_not_update_created_at_on_existing_component() {
Date oldDate = DateUtils.parseDate("2015-01-01");
- ComponentDto project = newPrivateProjectDto(dbTester.getDefaultOrganization(), "ABCD").setDbKey(PROJECT_KEY).setName("Project").setCreatedAt(oldDate);
- dbClient.componentDao().insert(dbTester.getSession(), project);
+ ComponentDto project = prepareProject(p -> p.setCreatedAt(oldDate));
ComponentDto module = ComponentTesting.newModuleDto("BCDE", project).setDbKey(MODULE_KEY).setName("Module").setPath("path").setCreatedAt(oldDate);
- dbClient.componentDao().insert(dbTester.getSession(), module);
- dbTester.getSession().commit();
+ dbClient.componentDao().insert(db.getSession(), module);
+ db.getSession().commit();
treeRootHolder.setRoot(
- builder(PROJECT, 1).setUuid("ABCD").setKey(PROJECT_KEY)
+ builder(PROJECT, 1).setUuid(project.uuid()).setKey(project.getDbKey())
.build());
underTest.execute();
- Optional<ComponentDto> projectReloaded = dbClient.componentDao().selectByKey(dbTester.getSession(), PROJECT_KEY);
+ Optional<ComponentDto> projectReloaded = dbClient.componentDao().selectByUuid(db.getSession(), project.uuid());
assertThat(projectReloaded.get().getCreatedAt()).isNotEqualTo(now);
}
@Test
public void persist_components_that_were_previously_removed() {
- ComponentDto project = newPrivateProjectDto(dbTester.organizations().insert(), "ABCD").setDbKey(PROJECT_KEY).setName("Project");
- dbClient.componentDao().insert(dbTester.getSession(), project);
+ ComponentDto project = prepareProject();
ComponentDto removedModule = ComponentTesting.newModuleDto("BCDE", project)
.setDbKey(MODULE_KEY)
.setName("Module")
.setEnabled(false);
- dbClient.componentDao().insert(dbTester.getSession(), removedModule);
+ dbClient.componentDao().insert(db.getSession(), removedModule);
ComponentDto removedDirectory = ComponentTesting.newDirectory(removedModule, "src/main/java/dir")
.setUuid("CDEF")
.setDbKey("MODULE_KEY:src/main/java/dir")
.setName("Foo.java")
.setDbKey("MODULE_KEY:src/main/java/dir/Foo.java")
.setEnabled(false);
- dbClient.componentDao().insert(dbTester.getSession(), removedDirectory, removedFile);
- dbTester.getSession().commit();
+ dbClient.componentDao().insert(db.getSession(), removedDirectory, removedFile);
+ db.getSession().commit();
treeRootHolder.setRoot(
- builder(PROJECT, 1).setUuid("ABCD").setKey(PROJECT_KEY)
+ builder(PROJECT, 1).setUuid(project.uuid()).setKey(project.getDbKey())
.setName("Project")
.addChildren(
builder(Component.Type.MODULE, 2).setUuid("BCDE").setKey(MODULE_KEY)
underTest.execute();
- assertThat(dbTester.countRowsOfTable("projects")).isEqualTo(4);
- assertThat(dbClient.componentDao().selectByKey(dbTester.getSession(), PROJECT_KEY).get().getId()).isEqualTo(project.getId());
- assertThat(dbClient.componentDao().selectByKey(dbTester.getSession(), MODULE_KEY).get().getId()).isEqualTo(removedModule.getId());
- assertThat(dbClient.componentDao().selectByKey(dbTester.getSession(), "MODULE_KEY:src/main/java/dir").get().getId()).isEqualTo(removedDirectory.getId());
- assertThat(dbClient.componentDao().selectByKey(dbTester.getSession(), "MODULE_KEY:src/main/java/dir/Foo.java").get().getId()).isEqualTo(removedFile.getId());
+ assertThat(db.countRowsOfTable("projects")).isEqualTo(4);
+ assertThat(dbClient.componentDao().selectByKey(db.getSession(), project.getDbKey()).get().getId()).isEqualTo(project.getId());
+ assertThat(dbClient.componentDao().selectByKey(db.getSession(), MODULE_KEY).get().getId()).isEqualTo(removedModule.getId());
+ assertThat(dbClient.componentDao().selectByKey(db.getSession(), "MODULE_KEY:src/main/java/dir").get().getId()).isEqualTo(removedDirectory.getId());
+ assertThat(dbClient.componentDao().selectByKey(db.getSession(), "MODULE_KEY:src/main/java/dir/Foo.java").get().getId()).isEqualTo(removedFile.getId());
assertExistButDisabled(removedModule.getDbKey(), removedDirectory.getDbKey(), removedFile.getDbKey());
// commit the functional transaction
- dbClient.componentDao().applyBChangesForRootComponentUuid(dbTester.getSession(), project.uuid());
+ dbClient.componentDao().applyBChangesForRootComponentUuid(db.getSession(), project.uuid());
- ComponentDto projectReloaded = dbClient.componentDao().selectByKey(dbTester.getSession(), PROJECT_KEY).get();
+ ComponentDto projectReloaded = dbClient.componentDao().selectByKey(db.getSession(), project.getDbKey()).get();
assertThat(projectReloaded.getId()).isEqualTo(project.getId());
assertThat(projectReloaded.uuid()).isEqualTo(project.uuid());
assertThat(projectReloaded.getUuidPath()).isEqualTo(project.getUuidPath());
assertThat(projectReloaded.getRootUuid()).isEqualTo(project.getRootUuid());
assertThat(projectReloaded.isEnabled()).isTrue();
- ComponentDto moduleReloaded = dbClient.componentDao().selectByKey(dbTester.getSession(), MODULE_KEY).get();
+ ComponentDto moduleReloaded = dbClient.componentDao().selectByKey(db.getSession(), MODULE_KEY).get();
assertThat(moduleReloaded.getId()).isEqualTo(removedModule.getId());
assertThat(moduleReloaded.uuid()).isEqualTo(removedModule.uuid());
assertThat(moduleReloaded.getUuidPath()).isEqualTo(removedModule.getUuidPath());
assertThat(moduleReloaded.getRootUuid()).isEqualTo(removedModule.getRootUuid());
assertThat(moduleReloaded.isEnabled()).isTrue();
- ComponentDto directoryReloaded = dbClient.componentDao().selectByKey(dbTester.getSession(), "MODULE_KEY:src/main/java/dir").get();
+ ComponentDto directoryReloaded = dbClient.componentDao().selectByKey(db.getSession(), "MODULE_KEY:src/main/java/dir").get();
assertThat(directoryReloaded.getId()).isEqualTo(removedDirectory.getId());
assertThat(directoryReloaded.uuid()).isEqualTo(removedDirectory.uuid());
assertThat(directoryReloaded.getUuidPath()).isEqualTo(removedDirectory.getUuidPath());
assertThat(directoryReloaded.path()).isEqualTo(removedDirectory.path());
assertThat(directoryReloaded.isEnabled()).isTrue();
- ComponentDto fileReloaded = dbClient.componentDao().selectByKey(dbTester.getSession(), "MODULE_KEY:src/main/java/dir/Foo.java").get();
+ ComponentDto fileReloaded = dbClient.componentDao().selectByKey(db.getSession(), "MODULE_KEY:src/main/java/dir/Foo.java").get();
assertThat(fileReloaded.getId()).isEqualTo(fileReloaded.getId());
assertThat(fileReloaded.uuid()).isEqualTo(removedFile.uuid());
assertThat(fileReloaded.getUuidPath()).isEqualTo(removedFile.getUuidPath());
private void assertExistButDisabled(String... keys) {
for (String key : keys) {
- ComponentDto dto = dbClient.componentDao().selectByKey(dbTester.getSession(), key).get();
+ ComponentDto dto = dbClient.componentDao().selectByKey(db.getSession(), key).get();
assertThat(dto.isEnabled()).isFalse();
}
}
@Test
public void update_module_uuid_when_reactivating_removed_component() {
- ComponentDto project = newPrivateProjectDto(dbTester.getDefaultOrganization(), "ABCD").setDbKey(PROJECT_KEY).setName("Project");
- dbClient.componentDao().insert(dbTester.getSession(), project);
+ ComponentDto project = prepareProject();
ComponentDto module = ComponentTesting.newModuleDto("BCDE", project).setDbKey(MODULE_KEY).setName("Module");
ComponentDto removedModule = ComponentTesting.newModuleDto("EDCD", project).setDbKey("REMOVED_MODULE_KEY").setName("Removed Module").setEnabled(false);
- dbClient.componentDao().insert(dbTester.getSession(), module, removedModule);
+ dbClient.componentDao().insert(db.getSession(), module, removedModule);
ComponentDto directory = ComponentTesting.newDirectory(module, "src/main/java/dir").setUuid("CDEF").setDbKey("MODULE_KEY:src/main/java/dir");
// The file was attached to another module
ComponentDto removedFile = ComponentTesting.newFileDto(removedModule, directory, "DEFG").setPath("src/main/java/dir/Foo.java").setName("Foo.java")
.setDbKey("MODULE_KEY:src/main/java/dir/Foo.java").setEnabled(false);
- dbClient.componentDao().insert(dbTester.getSession(), directory, removedFile);
- dbTester.getSession().commit();
+ dbClient.componentDao().insert(db.getSession(), directory, removedFile);
+ db.getSession().commit();
treeRootHolder.setRoot(
- builder(PROJECT, 1).setUuid("ABCD").setKey(PROJECT_KEY)
+ builder(PROJECT, 1).setUuid(project.uuid()).setKey(project.getDbKey())
.setName("Project")
.addChildren(
builder(Component.Type.MODULE, 2).setUuid("BCDE").setKey(MODULE_KEY)
underTest.execute();
// commit the functional transaction
- dbClient.componentDao().applyBChangesForRootComponentUuid(dbTester.getSession(), project.uuid());
- dbTester.commit();
+ dbClient.componentDao().applyBChangesForRootComponentUuid(db.getSession(), project.uuid());
+ db.commit();
// Projects contains 4 components from the report + one removed module
- assertThat(dbTester.countRowsOfTable("projects")).isEqualTo(5);
+ assertThat(db.countRowsOfTable("projects")).isEqualTo(5);
- ComponentDto moduleReloaded = dbClient.componentDao().selectByKey(dbTester.getSession(), MODULE_KEY).get();
+ ComponentDto moduleReloaded = dbClient.componentDao().selectByKey(db.getSession(), MODULE_KEY).get();
- ComponentDto fileReloaded = dbClient.componentDao().selectByKey(dbTester.getSession(), "MODULE_KEY:src/main/java/dir/Foo.java").get();
+ ComponentDto fileReloaded = dbClient.componentDao().selectByKey(db.getSession(), "MODULE_KEY:src/main/java/dir/Foo.java").get();
assertThat(fileReloaded.getId()).isEqualTo(removedFile.getId());
assertThat(fileReloaded.uuid()).isEqualTo(removedFile.uuid());
assertThat(fileReloaded.getUuidPath()).isEqualTo(fileReloaded.getUuidPath());
@Test
public void persists_existing_components_with_visibility_of_root_in_db_out_of_functional_transaction() {
- boolean isRootPrivate = new Random().nextBoolean();
- OrganizationDto organization = dbTester.organizations().insert();
- ComponentDto project = newPrivateProjectDto(organization, "ABCD").setDbKey(PROJECT_KEY).setName("Project").setPrivate(isRootPrivate);
- dbTester.components().insertComponent(project);
- ComponentDto module = newModuleDto(project).setUuid("BCDE").setDbKey("MODULE").setPrivate(!isRootPrivate);
- dbTester.components().insertComponent(module);
- dbTester.components().insertComponent(newDirectory(module, "DEFG", "Directory").setDbKey("DIR").setPrivate(isRootPrivate));
+ ComponentDto project = prepareProject(p -> p.setPrivate(true));
+ ComponentDto module = newModuleDto(project).setPrivate(false);
+ db.components().insertComponent(module);
+ ComponentDto dir = db.components().insertComponent(newDirectory(module, "DEFG", "Directory").setDbKey("DIR").setPrivate(true));
treeRootHolder.setRoot(createSampleProjectComponentTree(project));
underTest.execute();
- Stream.of("ABCD", "BCDE", "BCDE", "BCDE")
- .forEach(uuid -> assertThat(dbClient.componentDao().selectByUuid(dbTester.getSession(), uuid).get().isPrivate())
+ Stream.of(project.uuid(), module.uuid(), dir.uuid())
+ .forEach(uuid -> assertThat(dbClient.componentDao().selectByUuid(db.getSession(), uuid).get().isPrivate())
.describedAs("for uuid " + uuid)
- .isEqualTo(isRootPrivate));
+ .isEqualTo(true));
}
private ReportComponent createSampleProjectComponentTree(ComponentDto project) {
.build())
.build();
}
+
+ private ReportComponent.Builder asTreeRoot(ComponentDto project) {
+ return builder(PROJECT, 1).setUuid(project.uuid()).setKey(project.getDbKey()).setName(project.name());
+ }
+
+ private ComponentDto prepareProject(Consumer<ComponentDto>... populators) {
+ ComponentDto dto = db.components().insertPrivateProject(db.organizations().insert(), populators);
+ analysisMetadataHolder.setProject(Project.copyOf(dto));
+ analysisMetadataHolder.setBranch(new MainBranchImpl(null));
+ return dto;
+ }
+
+ private ComponentDto prepareBranch(String branchName, Consumer<ComponentDto>... populators) {
+ ComponentDto dto = db.components().insertPrivateProject(db.organizations().insert(), populators);
+ analysisMetadataHolder.setProject(Project.copyOf(dto));
+ analysisMetadataHolder.setBranch(new BranchImpl(branchName));
+ return dto;
+ }
+
+ private static class BranchImpl implements Branch {
+ private final String name;
+
+ public BranchImpl(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public BranchType getType() {
+ return BranchType.LONG;
+ }
+
+ @Override
+ public boolean isMain() {
+ return false;
+ }
+
+ @Override
+ public java.util.Optional<String> getName() {
+ return java.util.Optional.ofNullable(name);
+ }
+
+ @Override
+ public boolean supportsCrossProjectCpd() {
+ return false;
+ }
+
+ @Override
+ public String generateKey(ScannerReport.Component module, @Nullable ScannerReport.Component fileOrDir) {
+ String moduleKey = module.getKey();
+ if (fileOrDir == null || isEmpty(fileOrDir.getPath())) {
+ return moduleKey;
+ }
+ return ComponentKeys.createEffectiveKey(moduleKey, trimToNull(fileOrDir.getPath()));
+ }
+ }
}
import org.sonar.scanner.protocol.output.ScannerReport.Component.ComponentType;
import org.sonar.server.computation.task.projectanalysis.analysis.Analysis;
import org.sonar.server.computation.task.projectanalysis.analysis.AnalysisMetadataHolderRule;
+import org.sonar.server.computation.task.projectanalysis.analysis.Branch;
+import org.sonar.server.computation.task.projectanalysis.component.MainBranchImpl;
import org.sonar.server.computation.task.projectanalysis.batch.BatchReportReaderRule;
import org.sonar.server.computation.task.projectanalysis.component.Component;
import org.sonar.server.computation.task.projectanalysis.component.ReportComponent;
static long DEFAULT_ANALYSIS_TIME = 1433131200000L; // 2015-06-01
static final String PROJECT_KEY = "PROJECT_KEY";
static final String MODULE_KEY = "MODULE_KEY";
- static final String DEFAULT_BRANCH = "origin/master";
+ static final Branch DEFAULT_BRANCH = new MainBranchImpl(null);
@Rule
public DbTester dbTester = DbTester.create(System2.INSTANCE);
underTest.execute();
}
- @Test
- public void not_fail_on_valid_branch() {
- analysisMetadataHolder.setBranch(DEFAULT_BRANCH);
- reportReader.putComponent(ScannerReport.Component.newBuilder()
- .setRef(1)
- .setType(ComponentType.PROJECT)
- .setKey(PROJECT_KEY)
- .build());
- treeRootHolder.setRoot(ReportComponent.builder(Component.Type.PROJECT, 1).setUuid("ABCD").setKey(PROJECT_KEY + ":origin/master").build());
-
- underTest.execute();
- }
-
- @Test
- public void fail_on_invalid_branch() {
- analysisMetadataHolder.setBranch("bran#ch");
- reportReader.putComponent(ScannerReport.Component.newBuilder()
- .setRef(1)
- .setType(ComponentType.PROJECT)
- .setKey(PROJECT_KEY)
- .build());
- treeRootHolder.setRoot(ReportComponent.builder(Component.Type.PROJECT, 1).setUuid("ABCD").setKey(PROJECT_KEY + ":bran#ch").build());
-
- thrown.expect(MessageException.class);
- thrown.expectMessage("Validation of project failed:\n" +
- " o \"bran#ch\" is not a valid branch name. Allowed characters are alphanumeric, '-', '_', '.' and '/'.");
-
- underTest.execute();
- }
-
@Test
public void fail_on_invalid_key() {
String invalidProjectKey = "Project\\Key";
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.computation.task.projectanalysis.step;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.mockito.ArgumentCaptor;
+import org.sonar.api.utils.MessageException;
+import org.sonar.db.organization.OrganizationDto;
+import org.sonar.server.computation.task.projectanalysis.analysis.MutableAnalysisMetadataHolderRule;
+import org.sonar.server.computation.task.projectanalysis.analysis.Organization;
+import org.sonar.server.organization.BillingValidations;
+import org.sonar.server.organization.BillingValidations.BillingValidationsException;
+import org.sonar.server.organization.BillingValidationsProxy;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.sonar.db.organization.OrganizationTesting.newOrganizationDto;
+
+public class VerifyBillingStepTest {
+
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
+ private OrganizationDto organization = newOrganizationDto();
+ @Rule
+ public MutableAnalysisMetadataHolderRule analysisMetadata = new MutableAnalysisMetadataHolderRule()
+ .setOrganization(Organization.from(organization));
+
+ private BillingValidationsProxy validations = mock(BillingValidationsProxy.class);
+
+ @Test
+ public void execute_fails_with_MessageException_when_organization_is_not_allowed_to_execute_analysis() {
+ doThrow(new BillingValidationsException("This organization cannot execute project analysis"))
+ .when(validations)
+ .checkOnProjectAnalysis(any(BillingValidations.Organization.class));
+
+ VerifyBillingStep underTest = new VerifyBillingStep(analysisMetadata, validations);
+
+ expectedException.expect(MessageException.class);
+ expectedException.expectMessage("This organization cannot execute project analysis");
+
+ underTest.execute();
+
+ }
+
+ @Test
+ public void execute_does_no_fail_when_organization_is_allowed_to_execute_analysis() {
+ ArgumentCaptor<BillingValidations.Organization> orgCaptor = ArgumentCaptor.forClass(BillingValidations.Organization.class);
+
+ VerifyBillingStep underTest = new VerifyBillingStep(analysisMetadata, validations);
+ underTest.execute();
+
+ verify(validations).checkOnProjectAnalysis(orgCaptor.capture());
+ BillingValidations.Organization calledOrg = orgCaptor.getValue();
+ assertThat(calledOrg.getKey()).isEqualTo(organization.getKey());
+ }
+
+}
import org.sonar.db.component.ComponentTesting;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.server.computation.task.projectanalysis.analysis.AnalysisMetadataHolderRule;
+import org.sonar.server.computation.task.projectanalysis.component.BranchPersisterDelegate;
+import org.sonar.server.computation.task.projectanalysis.component.MainBranchImpl;
import org.sonar.server.computation.task.projectanalysis.component.MutableDbIdsRepositoryRule;
import org.sonar.server.computation.task.projectanalysis.component.MutableDisabledComponentsHolder;
import org.sonar.server.computation.task.projectanalysis.component.ProjectViewAttributes;
private ComponentDbTester componentDbTester = new ComponentDbTester(dbTester);
private MutableDisabledComponentsHolder disabledComponentsHolder = mock(MutableDisabledComponentsHolder.class, RETURNS_DEEP_STUBS);
private PersistComponentsStep underTest;
+ private BranchPersisterDelegate branchPersister;
@Before
public void setup() throws Exception {
when(system2.now()).thenReturn(now.getTime());
dbTester.organizations().insertForUuid(ORGANIZATION_UUID);
- underTest = new PersistComponentsStep(dbClient, treeRootHolder, dbIdsRepository, system2, disabledComponentsHolder, analysisMetadataHolder);
+ analysisMetadataHolder.setBranch(new MainBranchImpl(null));
+ underTest = new PersistComponentsStep(dbClient, treeRootHolder, dbIdsRepository, system2, disabledComponentsHolder, analysisMetadataHolder, branchPersister);
}
@Override
import org.sonar.api.utils.log.LoggerLevel;
import org.sonar.server.computation.task.projectanalysis.component.ConfigurationRepository;
import org.sonar.server.computation.task.projectanalysis.component.TestSettingsRepository;
-import org.sonar.server.computation.task.projectanalysis.component.TreeRootHolderRule;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Matchers.any;
import static org.sonar.api.ce.posttask.PostProjectAnalysisTaskTester.newCeTaskBuilder;
import static org.sonar.api.ce.posttask.PostProjectAnalysisTaskTester.newProjectBuilder;
import static org.sonar.api.ce.posttask.PostProjectAnalysisTaskTester.newScannerContextBuilder;
-import static org.sonar.server.computation.task.projectanalysis.component.ReportComponent.DUMB_PROJECT;
public class WebhookPostTaskTest {
@Rule
public LogTester logTester = new LogTester().setLevel(LoggerLevel.DEBUG);
- @Rule
- public TreeRootHolderRule rootHolder = new TreeRootHolderRule().setRoot(DUMB_PROJECT);
-
private final MapSettings settings = new MapSettings();
private final TestWebhookCaller caller = new TestWebhookCaller();
private final WebhookPayloadFactory payloadFactory = new TestWebhookPayloadFactory();
private void execute() {
ConfigurationRepository settingsRepository = new TestSettingsRepository(settings.asConfig());
- WebhookPostTask task = new WebhookPostTask(rootHolder, settingsRepository, payloadFactory, caller, deliveryStorage);
+ WebhookPostTask task = new WebhookPostTask(settingsRepository, payloadFactory, caller, deliveryStorage);
PostProjectAnalysisTaskTester.of(task)
.at(new Date())
}
@Test
- public void would_user_have_scann_permission_with_empty_template() {
+ public void would_user_have_scan_permission_with_empty_template() {
PermissionTemplateDto template = templateDb.insertTemplate(dbTester.getDefaultOrganization());
dbTester.organizations().setDefaultTemplates(template, null);
}
private void checkWouldUserHaveScanPermission(OrganizationDto organization, @Nullable Integer userId, boolean expectedResult) {
- assertThat(underTest.wouldUserHaveScanPermissionWithDefaultTemplate(session, organization.getUuid(), userId, null, "PROJECT_KEY", Qualifiers.PROJECT))
+ assertThat(underTest.wouldUserHaveScanPermissionWithDefaultTemplate(session, organization.getUuid(), userId, "PROJECT_KEY", Qualifiers.PROJECT))
.isEqualTo(expectedResult);
}
public void verify_count_of_added_components() {
ComponentContainer container = new ComponentContainer();
new ProjectsWsModule().configure(container);
- assertThat(container.size()).isEqualTo(COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER + 14);
+ assertThat(container.size()).isEqualTo(COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER + 15);
}
}
*/
package org.sonar.core.config;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
-import java.util.Arrays;
+import java.util.ArrayList;
import java.util.List;
import org.sonar.api.CoreProperties;
import org.sonar.api.PropertyType;
import org.sonar.api.config.PropertyDefinition;
import org.sonar.api.resources.Qualifiers;
+import static java.util.Arrays.asList;
import static org.sonar.api.PropertyType.BOOLEAN;
import static org.sonar.api.database.DatabaseProperties.PROP_PASSWORD;
}
public static List<PropertyDefinition> all() {
- List<PropertyDefinition> defs = Lists.newArrayList();
+ List<PropertyDefinition> defs = new ArrayList<>();
defs.addAll(IssueExclusionProperties.all());
defs.addAll(ExclusionProperties.all());
defs.addAll(SecurityProperties.all());
defs.addAll(EmailSettings.definitions());
defs.addAll(WebhookProperties.all());
defs.addAll(TelemetryProperties.all());
+ defs.addAll(ScannerProperties.all());
- defs.addAll(ImmutableList.of(
+ defs.addAll(asList(
PropertyDefinition.builder(PROP_PASSWORD)
.type(PropertyType.PASSWORD)
.hidden()
.category(CoreProperties.CATEGORY_GENERAL)
.hidden()
.build(),
- PropertyDefinition.builder(CoreProperties.ANALYSIS_MODE)
- .name("Analysis mode")
- .type(PropertyType.SINGLE_SELECT_LIST)
- .options(Arrays.asList(CoreProperties.ANALYSIS_MODE_ANALYSIS, CoreProperties.ANALYSIS_MODE_PREVIEW, CoreProperties.ANALYSIS_MODE_INCREMENTAL))
- .category(CoreProperties.CATEGORY_GENERAL)
- .defaultValue(CoreProperties.ANALYSIS_MODE_ANALYSIS)
- .hidden()
- .build(),
PropertyDefinition.builder(CoreProperties.PREVIEW_INCLUDE_PLUGINS)
.name("Plugins accepted for Preview mode")
.description("List of plugin keys. Those plugins will be used during preview analyses.")
.defaultValue(String.valueOf(false))
.hidden()
.build(),
- PropertyDefinition.builder(CoreProperties.SCM_DISABLED_KEY)
- .name("Disable the SCM Sensor")
- .description("Disable the retrieval of blame information from Source Control Manager")
- .category(CoreProperties.CATEGORY_SCM)
- .type(BOOLEAN)
- .onQualifiers(Qualifiers.PROJECT)
- .defaultValue(String.valueOf(false))
- .build(),
- PropertyDefinition.builder(CoreProperties.SCM_PROVIDER_KEY)
- .name("Key of the SCM provider for this project")
- .description("Force the provider to be used to get SCM information for this project. By default auto-detection is done. Example: svn, git.")
- .category(CoreProperties.CATEGORY_SCM)
- .onlyOnQualifiers(Qualifiers.PROJECT)
- .build(),
PropertyDefinition.builder(DISABLE_NOTIFICATION_ON_BUILT_IN_QPROFILES)
.name("Avoid quality profiles notification")
.description("Avoid sending email notification on each update of built-in quality profiles to quality profile administrators.")
*/
package org.sonar.core.config;
-import java.util.Arrays;
import java.util.List;
import org.sonar.api.CoreProperties;
import org.sonar.api.PropertyType;
import org.sonar.api.config.PropertyDefinition;
import org.sonar.api.resources.Qualifiers;
+import static java.util.Arrays.asList;
+
public final class PurgeProperties {
private PurgeProperties() {
}
public static List<PropertyDefinition> all() {
- return Arrays.asList(
+ return asList(
PropertyDefinition.builder(PurgeConstants.PROPERTY_CLEAN_DIRECTORY)
.defaultValue("true")
.name("Clean directory/package history")
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.core.config;
+
+import java.util.List;
+import org.sonar.api.CoreProperties;
+import org.sonar.api.PropertyType;
+import org.sonar.api.config.PropertyDefinition;
+import org.sonar.api.resources.Qualifiers;
+
+import static java.util.Arrays.asList;
+import static org.sonar.api.PropertyType.BOOLEAN;
+
+public class ScannerProperties {
+
+ public static final String BRANCH_NAME = "sonar.branch.name";
+ public static final String ORGANIZATION = "sonar.organization";
+
+ private ScannerProperties() {
+ // only static stuff
+ }
+
+ public static List<PropertyDefinition> all() {
+ return asList(
+ PropertyDefinition.builder(CoreProperties.ANALYSIS_MODE)
+ .name("Analysis mode")
+ .type(PropertyType.SINGLE_SELECT_LIST)
+ .options(asList(CoreProperties.ANALYSIS_MODE_ANALYSIS, CoreProperties.ANALYSIS_MODE_PREVIEW, CoreProperties.ANALYSIS_MODE_INCREMENTAL))
+ .category(CoreProperties.CATEGORY_GENERAL)
+ .defaultValue(CoreProperties.ANALYSIS_MODE_ANALYSIS)
+ .hidden()
+ .build(),
+ PropertyDefinition.builder(CoreProperties.SCM_DISABLED_KEY)
+ .name("Disable the SCM Sensor")
+ .description("Disable the retrieval of blame information from Source Control Manager")
+ .category(CoreProperties.CATEGORY_SCM)
+ .type(BOOLEAN)
+ .onQualifiers(Qualifiers.PROJECT)
+ .defaultValue(String.valueOf(false))
+ .build(),
+ PropertyDefinition.builder(CoreProperties.SCM_PROVIDER_KEY)
+ .name("Key of the SCM provider for this project")
+ .description("Force the provider to be used to get SCM information for this project. By default auto-detection is done. Example: svn, git.")
+ .category(CoreProperties.CATEGORY_SCM)
+ .onlyOnQualifiers(Qualifiers.PROJECT)
+ .build(),
+ PropertyDefinition.builder(ORGANIZATION)
+ .name("Organization key")
+ .description("Key of the organization that contains the project being analyzed. If unset, then the organization marked as default is used.")
+ .hidden()
+ .build(),
+ PropertyDefinition.builder(BRANCH_NAME)
+ .name("Optional name of SCM branch")
+ .description("TODO")
+ .hidden()
+ .build()
+ );
+ }
+}
*/
package org.sonar.core.config;
-import com.google.common.collect.ImmutableList;
import java.util.List;
import org.sonar.api.PropertyType;
import org.sonar.api.config.PropertyDefinition;
import org.sonar.api.config.PropertyFieldDefinition;
import org.sonar.api.resources.Qualifiers;
+import static java.util.Arrays.asList;
+
public class WebhookProperties {
public static final String GLOBAL_KEY = "sonar.webhooks.global";
}
static List<PropertyDefinition> all() {
- return ImmutableList.of(
+ return asList(
PropertyDefinition.builder(GLOBAL_KEY)
.category(CATEGORY)
.name("Webhooks")
* Defines the base keys (defined by {@link #basePluginKey(PluginInfo, Map)}) of the plugins which are allowed to
* run a full server extensions.
*/
- private static final Set<String> PRIVILEGED_PLUGINS_BASE_KEYS = ImmutableSet.of("views", "devcockpit", "governance", "billing", "developer", "incremental");
+ private static final Set<String> PRIVILEGED_PLUGINS_BASE_KEYS = ImmutableSet.of("views", "devcockpit", "governance", "billing", "developer", "incremental", "branch");
public static final Version COMPATIBILITY_MODE_MAX_VERSION = Version.create("5.2");
@Test
public void all() {
List<PropertyDefinition> defs = CorePropertyDefinitions.all();
- assertThat(defs).hasSize(61);
+ assertThat(defs).hasSize(63);
}
@Test
assertThat(prop.get().type()).isEqualTo(PropertyType.PASSWORD);
}
+ @Test
+ public void all_includes_scanner_properties() {
+ List<PropertyDefinition> defs = CorePropertyDefinitions.all();
+
+ assertThat(defs.stream()
+ .filter(def -> def.key().equals(ScannerProperties.BRANCH_NAME))
+ .findFirst()).isPresent();
+ }
}
String PROJECT_BRANCH_PROPERTY = "sonar.branch";
String PROJECT_VERSION_PROPERTY = "sonar.projectVersion";
- /**
- * @since 6.3
- */
- String PROJECT_ORGANIZATION_PROPERTY = "sonar.organization";
-
/**
* @since 2.6
*/
if (!container.getComponentByType(AnalysisMode.class).isIssues()) {
Metadata readMetadata = getReportReader().readMetadata();
int rootComponentRef = readMetadata.getRootComponentRef();
- storeReportComponents(rootComponentRef, null, readMetadata.getBranch());
+ storeReportComponents(rootComponentRef, null);
}
storeFs(container);
}
- private void storeReportComponents(int componentRef, String parentModuleKey, String branch) {
+ private void storeReportComponents(int componentRef, String parentModuleKey) {
Component component = getReportReader().readComponent(componentRef);
if (isNotEmpty(component.getKey())) {
reportComponents.put(component.getKey(), component);
reportComponents.put(parentModuleKey + ":" + component.getPath(), component);
}
for (int childId : component.getChildRefList()) {
- storeReportComponents(childId, isNotEmpty(component.getKey()) ? component.getKey() : parentModuleKey, branch);
+ storeReportComponents(childId, isNotEmpty(component.getKey()) ? component.getKey() : parentModuleKey);
}
}
* @param lineOffset 0-based offset in file
*/
public List<TypeOfText> highlightingTypeFor(InputFile file, int line, int lineOffset) {
- int ref = reportComponents.get(((DefaultInputFile) file).key()).getRef();
+ int ref = reportComponents.get(file.key()).getRef();
if (!reader.hasSyntaxHighlighting(ref)) {
return Collections.emptyList();
}
*/
@CheckForNull
public List<ScannerReport.TextRange> symbolReferencesFor(InputFile file, int symbolStartLine, int symbolStartLineOffset) {
- int ref = reportComponents.get(((DefaultInputFile) file).key()).getRef();
+ int ref = reportComponents.get(file.key()).getRef();
try (CloseableIterator<Symbol> symbols = getReportReader().readComponentSymbols(ref)) {
while (symbols.hasNext()) {
Symbol symbol = symbols.next();
public List<ScannerReport.Duplication> duplicationsFor(InputFile file) {
List<ScannerReport.Duplication> result = new ArrayList<>();
- int ref = reportComponents.get(((DefaultInputFile) file).key()).getRef();
+ int ref = reportComponents.get(file.key()).getRef();
try (CloseableIterator<ScannerReport.Duplication> it = getReportReader().readComponentDuplications(ref)) {
while (it.hasNext()) {
result.add(it.next());
public List<ScannerReport.CpdTextBlock> duplicationBlocksFor(InputFile file) {
List<ScannerReport.CpdTextBlock> result = new ArrayList<>();
- int ref = reportComponents.get(((DefaultInputFile) file).key()).getRef();
+ int ref = reportComponents.get(file.key()).getRef();
try (CloseableIterator<ScannerReport.CpdTextBlock> it = getReportReader().readCpdTextBlocks(ref)) {
while (it.hasNext()) {
result.add(it.next());
@CheckForNull
public ScannerReport.LineCoverage coverageFor(InputFile file, int line) {
- int ref = reportComponents.get(((DefaultInputFile) file).key()).getRef();
+ int ref = reportComponents.get(file.key()).getRef();
try (CloseableIterator<ScannerReport.LineCoverage> it = getReportReader().readComponentCoverage(ref)) {
while (it.hasNext()) {
ScannerReport.LineCoverage coverage = it.next();
}
public ScannerReport.Test firstTestExecutionForName(InputFile testFile, String testName) {
- int ref = reportComponents.get(((DefaultInputFile) testFile).key()).getRef();
+ int ref = reportComponents.get(testFile.key()).getRef();
try (InputStream inputStream = FileUtils.openInputStream(getReportReader().readTests(ref))) {
ScannerReport.Test test = ScannerReport.Test.parser().parseDelimitedFrom(inputStream);
while (test != null) {
}
public ScannerReport.CoverageDetail coveragePerTestFor(InputFile testFile, String testName) {
- int ref = reportComponents.get(((DefaultInputFile) testFile).key()).getRef();
+ int ref = reportComponents.get(testFile.key()).getRef();
try (InputStream inputStream = FileUtils.openInputStream(getReportReader().readCoverageDetails(ref))) {
ScannerReport.CoverageDetail details = ScannerReport.CoverageDetail.parser().parseDelimitedFrom(inputStream);
while (details != null) {
package org.sonar.scanner.report;
import java.util.Map.Entry;
-import org.sonar.api.CoreProperties;
import org.sonar.api.batch.AnalysisMode;
+import java.util.Optional;
import org.sonar.api.batch.bootstrap.ProjectDefinition;
import org.sonar.api.batch.fs.internal.DefaultInputModule;
import org.sonar.api.batch.fs.internal.InputModuleHierarchy;
import org.sonar.scanner.rule.ModuleQProfiles;
import org.sonar.scanner.rule.QProfile;
+import static org.sonar.core.config.ScannerProperties.BRANCH_NAME;
+import static org.sonar.core.config.ScannerProperties.ORGANIZATION;
+
public class MetadataPublisher implements ReportPublisherStep {
private final Configuration settings;
.setRootComponentRef(rootProject.batchId())
.setIncremental(mode.isIncremental());
- settings.get(CoreProperties.PROJECT_ORGANIZATION_PROPERTY).ifPresent(builder::setOrganizationKey);
+ settings.get(ORGANIZATION).ifPresent(builder::setOrganizationKey);
+ settings.get(BRANCH_NAME).ifPresent(builder::setBranchName);
+ Optional.ofNullable(rootDef.getBranch()).ifPresent(builder::setDeprecatedBranch);
- String branch = rootDef.getBranch();
- if (branch != null) {
- builder.setBranch(branch);
- }
for (QProfile qp : qProfiles.findAll()) {
builder.getMutableQprofilesPerLanguage().put(qp.getLanguage(), ScannerReport.Metadata.QProfile.newBuilder()
.setKey(qp.getKey())
import okhttp3.HttpUrl;
import org.apache.commons.io.FileUtils;
import org.picocontainer.Startable;
-import org.sonar.api.CoreProperties;
import org.sonar.api.batch.ScannerSide;
import org.sonar.api.batch.fs.internal.InputModuleHierarchy;
import org.sonar.api.config.Configuration;
import org.sonarqube.ws.client.PostRequest;
import org.sonarqube.ws.client.WsResponse;
+import static org.sonar.core.config.ScannerProperties.ORGANIZATION;
import static org.sonar.core.util.FileUtils.deleteQuietly;
@ScannerSide
PostRequest.Part filePart = new PostRequest.Part(MediaTypes.ZIP, report);
PostRequest post = new PostRequest("api/ce/submit")
.setMediaType(MediaTypes.PROTOBUF)
- .setParam("organization", settings.get(CoreProperties.PROJECT_ORGANIZATION_PROPERTY).orElse(null))
+ .setParam("organization", settings.get(ORGANIZATION).orElse(null))
.setParam("projectKey", moduleHierarchy.root().key())
.setParam("projectName", moduleHierarchy.root().getOriginalName())
.setParam("projectBranch", moduleHierarchy.root().getBranch())
Map<String, String> metadata = new LinkedHashMap<>();
String effectiveKey = moduleHierarchy.root().getKeyWithBranch();
- settings.get(CoreProperties.PROJECT_ORGANIZATION_PROPERTY).ifPresent(org -> metadata.put("organization", org));
+ settings.get(ORGANIZATION).ifPresent(org -> metadata.put("organization", org));
metadata.put("projectKey", effectiveKey);
metadata.put("serverUrl", publicUrl);
metadata.put("serverVersion", server.getVersion());
import java.util.function.BinaryOperator;
import javax.annotation.Nullable;
import org.apache.commons.io.IOUtils;
-import org.sonar.api.CoreProperties;
import org.sonar.api.config.Configuration;
import org.sonar.api.utils.MessageException;
import org.sonar.scanner.bootstrap.ScannerWsClient;
import static java.util.function.Function.identity;
import static java.util.stream.Collectors.toMap;
+import static org.sonar.core.config.ScannerProperties.ORGANIZATION;
import static org.sonar.scanner.util.ScannerUtils.encodeForUrl;
public class DefaultQualityProfileLoader implements QualityProfileLoader {
}
private Optional<String> getOrganizationKey() {
- return settings.get(CoreProperties.PROJECT_ORGANIZATION_PROPERTY);
+ return settings.get(ORGANIZATION);
}
private Map<String, QualityProfile> call(String url) {
DefaultInputFile inputfile = (DefaultInputFile) result.inputFile("src/sample.xoo");
assertThat(result.getReportReader().readComponent(inputfile.batchId()).getPath()).isEqualTo("src/sample.xoo");
- assertThat(result.getReportReader().readMetadata().getBranch()).isEqualTo("branch");
+ assertThat(result.getReportReader().readMetadata().getDeprecatedBranch()).isEqualTo("branch");
result = tester.newTask()
.properties(ImmutableMap.<String, String>builder()
// no branch in InputModule's key or in report
assertThat(result.getReportComponent("com.foo.project:moduleA").getKey()).isEqualTo("com.foo.project:moduleA");
- assertThat(result.getReportReader().readMetadata().getBranch()).isEqualTo("branch");
+ assertThat(result.getReportReader().readMetadata().getDeprecatedBranch()).isEqualTo("branch");
result = tester.newTask()
.properties(ImmutableMap.<String, String>builder()
import org.sonar.api.batch.fs.internal.InputModuleHierarchy;
import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
import org.sonar.api.config.internal.MapSettings;
+import org.sonar.core.config.ScannerProperties;
import org.sonar.scanner.ProjectAnalysisInfo;
import org.sonar.scanner.bootstrap.ScannerPlugin;
import org.sonar.scanner.bootstrap.ScannerPluginRepository;
ScannerReport.Metadata metadata = reader.readMetadata();
assertThat(metadata.getAnalysisDate()).isEqualTo(1234567L);
assertThat(metadata.getProjectKey()).isEqualTo("foo");
- assertThat(metadata.getBranch()).isEqualTo("myBranch");
+ assertThat(metadata.getDeprecatedBranch()).isEqualTo("myBranch");
assertThat(metadata.getCrossProjectDuplicationActivated()).isFalse();
}
@Test
public void write_project_organization() throws Exception {
- settings.setProperty(CoreProperties.PROJECT_ORGANIZATION_PROPERTY, "SonarSource");
+ settings.setProperty(ScannerProperties.ORGANIZATION, "SonarSource");
File outputDir = temp.newFolder();
ScannerReportWriter writer = new ScannerReportWriter(outputDir);
import org.junit.rules.TemporaryFolder;
import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;
-import org.sonar.api.CoreProperties;
import org.sonar.api.batch.bootstrap.ProjectDefinition;
import org.sonar.api.batch.fs.internal.DefaultInputModule;
import org.sonar.api.batch.fs.internal.InputModuleHierarchy;
import org.sonar.api.utils.log.LogTester;
import org.sonar.api.utils.log.LoggerLevel;
import org.sonar.core.config.CorePropertyDefinitions;
+import org.sonar.core.config.ScannerProperties;
import org.sonar.scanner.analysis.DefaultAnalysisMode;
import org.sonar.scanner.bootstrap.ScannerWsClient;
import org.sonarqube.ws.WsCe;
public void log_and_dump_information_about_report_uploading() throws IOException {
ReportPublisher underTest = new ReportPublisher(settings.asConfig(), wsClient, server, contextPublisher, moduleHierarchy, mode, mock(TempFolder.class),
new ReportPublisherStep[0]);
- settings.setProperty(CoreProperties.PROJECT_ORGANIZATION_PROPERTY, "MyOrg");
+ settings.setProperty(ScannerProperties.ORGANIZATION, "MyOrg");
underTest.logSuccess("TASK-123");
ReportPublisher underTest = new ReportPublisher(settings.asConfig(), wsClient, server, contextPublisher, moduleHierarchy, mode, mock(TempFolder.class),
new ReportPublisherStep[0]);
- settings.setProperty(CoreProperties.PROJECT_ORGANIZATION_PROPERTY, "MyOrg");
+ settings.setProperty(ScannerProperties.ORGANIZATION, "MyOrg");
WsResponse response = mock(WsResponse.class);
new ReportPublisherStep[0]);
when(mode.isIncremental()).thenReturn(true);
- settings.setProperty(CoreProperties.PROJECT_ORGANIZATION_PROPERTY, "MyOrg");
+ settings.setProperty(ScannerProperties.ORGANIZATION, "MyOrg");
WsResponse response = mock(WsResponse.class);
}
private void updateTitle() {
- frame.setTitle(metadata.getProjectKey() + (StringUtils.isNotEmpty(metadata.getBranch()) ? (" (" + metadata.getBranch() + ")") : "") + " "
+ frame.setTitle(metadata.getProjectKey() + (StringUtils.isNotEmpty(metadata.getBranchName()) ? (" (" + metadata.getBranchName() + ")") : "") + " "
+ sdf.format(new Date(metadata.getAnalysisDate())));
}
string organization_key = 2;
// TODO should we keep this project_key here or not ? Because it's a duplication of Component.key
string project_key = 3;
- string branch = 4;
+ // maps the property sonar.branch
+ string deprecated_branch = 4;
int32 root_component_ref = 5;
bool cross_project_duplication_activated = 6;
map<string, QProfile> qprofiles_per_language = 7;
map<string, Plugin> plugins_by_key = 8;
bool incremental = 9;
+ string branch_name = 10;
message QProfile {
string key = 1;
optional bool duplicate = 3;
}
}
+
+// WS api/projects/branches
+message BranchesWsResponse {
+ repeated Branch branches = 1;
+
+ message Branch {
+ optional string name = 1;
+ optional bool isMain = 2;
+ optional BranchType type = 3;
+ }
+
+ enum BranchType {
+ // Zero is required in order to not get MAINTAINABILITY as default value
+ // See http://androiddevblog.com/protocol-buffers-pitfall-adding-enum-values/
+ UNKNOWN = 0;
+
+ LONG = 1;
+ SHORT = 2;
+ }
+
+}
--- /dev/null
+projectKey=com.sonarsource.it.samples:multi-modules-sample
+serverUrl=http://localhost:9000
+serverVersion=6.6-SNAPSHOT
+dashboardUrl=http://localhost:9000/dashboard/index/com.sonarsource.it.samples:multi-modules-sample
+ceTaskId=AV2ZBK0ixJXLis3IozUo
+ceTaskUrl=http://localhost:9000/api/ce/task?id=AV2ZBK0ixJXLis3IozUo