]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-11151 Generate isNew for lines when it's not stored in DB
authorDuarte Meneses <duarte.meneses@sonarsource.com>
Tue, 21 Aug 2018 14:19:14 +0000 (16:19 +0200)
committersonartech <sonartech@sonarsource.com>
Wed, 19 Sep 2018 08:51:40 +0000 (10:51 +0200)
server/sonar-server/src/main/java/org/sonar/server/source/ws/LinesAction.java
server/sonar-server/src/test/java/org/sonar/server/source/ws/LinesActionTest.java
server/sonar-server/src/test/resources/org/sonar/server/source/ws/LinesActionTest/generated_isNew.json [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/source/ws/LinesActionTest/show_source_by_file_key.json

index bd5857ba36204c1e76098c3422cc4e5369ca2f65..cee8513508a35fbcfd7f4b49d965f1600afca9a3 100644 (file)
@@ -23,6 +23,7 @@ import com.google.common.base.MoreObjects;
 import com.google.common.io.Resources;
 import java.util.Date;
 import java.util.Optional;
+import java.util.function.Supplier;
 import org.sonar.api.server.ws.Change;
 import org.sonar.api.server.ws.Request;
 import org.sonar.api.server.ws.Response;
@@ -33,6 +34,7 @@ import org.sonar.api.web.UserRole;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
 import org.sonar.db.component.ComponentDto;
+import org.sonar.db.component.SnapshotDto;
 import org.sonar.db.organization.OrganizationDto;
 import org.sonar.db.protobuf.DbFileSources;
 import org.sonar.server.component.ComponentFinder;
@@ -140,6 +142,10 @@ public class LinesAction implements SourcesWsAction {
   public void handle(Request request, Response response) {
     try (DbSession dbSession = dbClient.openSession(false)) {
       ComponentDto file = loadComponent(dbSession, request);
+      Supplier<Optional<Long>> periodDateSupplier = () -> dbClient.snapshotDao()
+        .selectLastAnalysisByComponentUuid(dbSession, file.projectUuid())
+        .map(SnapshotDto::getPeriodDate);
+
       userSession.checkComponentPermission(UserRole.CODEVIEWER, file);
       int from = request.mandatoryParamAsInt(PARAM_FROM);
       int to = MoreObjects.firstNonNull(request.paramAsInt(PARAM_TO), Integer.MAX_VALUE);
@@ -147,7 +153,7 @@ public class LinesAction implements SourcesWsAction {
       Iterable<DbFileSources.Line> lines = checkFoundWithOptional(sourceService.getLines(dbSession, file.uuid(), from, to), "No source found for file '%s'", file.getDbKey());
       try (JsonWriter json = response.newJsonWriter()) {
         json.beginObject();
-        writeSource(lines, json, isMemberOfOrganization(dbSession, file));
+        writeSource(lines, json, isMemberOfOrganization(dbSession, file), periodDateSupplier);
         json.endObject();
       }
     }
@@ -170,11 +176,13 @@ public class LinesAction implements SourcesWsAction {
       return componentFinder.getByUuidOrKey(dbSession, componentId, componentKey, UUID_AND_KEY);
     }
 
-    checkRequest(componentKey!=null, "The '%s' parameter is missing", PARAM_KEY);
+    checkRequest(componentKey != null, "The '%s' parameter is missing", PARAM_KEY);
     return componentFinder.getByKeyAndOptionalBranchOrPullRequest(dbSession, componentKey, branch, pullRequest);
   }
 
-  private void writeSource(Iterable<DbFileSources.Line> lines, JsonWriter json, boolean filterScmAuthors) {
+  private void writeSource(Iterable<DbFileSources.Line> lines, JsonWriter json, boolean filterScmAuthors, Supplier<Optional<Long>> periodDateSupplier) {
+    Optional<Long> periodDate = null;
+
     json.name("sources").beginArray();
     for (DbFileSources.Line line : lines) {
       json.beginObject()
@@ -203,7 +211,14 @@ public class LinesAction implements SourcesWsAction {
         json.prop("coveredConditions", coveredConditions.get());
       }
       json.prop("duplicated", line.getDuplicationCount() > 0);
-      json.prop("isNew", line.getIsNewLine());
+      if (line.hasIsNewLine()) {
+        json.prop("isNew", line.getIsNewLine());
+      } else {
+        if (periodDate == null) {
+          periodDate = periodDateSupplier.get();
+        }
+        json.prop("isNew", periodDate.isPresent() && line.getScmDate() > periodDate.get());
+      }
       json.endObject();
     }
     json.endArray();
index 70f0811c18587f09b8641adffe6b5e7df9627df7..a337c3986c611c45a3a14967359d2befba78d0af 100644 (file)
@@ -30,6 +30,8 @@ import org.sonar.db.DbTester;
 import org.sonar.db.component.ComponentDao;
 import org.sonar.db.component.ComponentDto;
 import org.sonar.db.component.ComponentTesting;
+import org.sonar.db.component.SnapshotDao;
+import org.sonar.db.component.SnapshotDto;
 import org.sonar.db.organization.OrganizationDto;
 import org.sonar.db.protobuf.DbFileSources;
 import org.sonar.db.source.FileSourceDto;
@@ -61,6 +63,7 @@ public class LinesActionTest {
   public UserSessionRule userSession = UserSessionRule.standalone();
 
   private ComponentDao componentDao = new ComponentDao();
+  private SnapshotDao snapshotDao = new SnapshotDao();
   private ComponentDto privateProject;
   private OrganizationDto organization;
   private WsTester wsTester;
@@ -218,6 +221,25 @@ public class LinesActionTest {
       .assertJson(getClass(), "display_deprecated_fields.json");
   }
 
+  @Test
+  public void use_period_date_if_new_line_not_yet_available_in_db() throws Exception {
+    DbFileSources.Data.Builder dataBuilder = DbFileSources.Data.newBuilder();
+    dataBuilder.addLines(DbFileSources.Line.newBuilder().setLine(1).setScmDate(1000L).build());
+    dataBuilder.addLines(DbFileSources.Line.newBuilder().setLine(2).setScmDate(2000L).build());
+    // only this line should be considered as new
+    dataBuilder.addLines(DbFileSources.Line.newBuilder().setLine(3).setScmDate(3000L).build());
+    ComponentDto project = db.components().insertPrivateProject();
+    insertPeriod(project, 2000L);
+    ComponentDto file = insertFileWithData(dataBuilder.build(), project);
+    setUserWithValidPermission(file);
+
+    wsTester
+      .newGetRequest("api/sources", "lines")
+      .setParam("uuid", file.uuid())
+      .execute()
+      .assertJson(getClass(), "generated_isNew.json");
+  }
+
   @Test
   public void use_deprecated_overall_coverage_fields_if_exists() throws Exception {
     DbFileSources.Data.Builder dataBuilder = DbFileSources.Data.newBuilder();
@@ -405,4 +427,13 @@ public class LinesActionTest {
       .setScmDate(1_500_000_000_00L)
       .setSource("SOURCE_" + 1);
   }
+
+  private void insertPeriod(ComponentDto componentDto, long date) {
+    SnapshotDto dto = new SnapshotDto();
+    dto.setUuid("uuid");
+    dto.setLast(true);
+    dto.setPeriodDate(date);
+    dto.setComponentUuid(componentDto.uuid());
+    snapshotDao.insert(db.getSession(), dto);
+  }
 }
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/source/ws/LinesActionTest/generated_isNew.json b/server/sonar-server/src/test/resources/org/sonar/server/source/ws/LinesActionTest/generated_isNew.json
new file mode 100644 (file)
index 0000000..f026ce1
--- /dev/null
@@ -0,0 +1,28 @@
+{
+  "sources": [
+    {
+      "line": 1,
+      "code": "\u003cp\u003e\u003c/p\u003e",
+      "scmRevision": "",
+      "scmDate": "1970-01-01T01:00:01+0100",
+      "duplicated": false,
+      "isNew": false
+    },
+    {
+      "line": 2,
+      "code": "\u003cp\u003e\u003c/p\u003e",
+      "scmRevision": "",
+      "scmDate": "1970-01-01T01:00:02+0100",
+      "duplicated": false,
+      "isNew": false
+    },
+    {
+      "line": 3,
+      "code": "\u003cp\u003e\u003c/p\u003e",
+      "scmRevision": "",
+      "scmDate": "1970-01-01T01:00:03+0100",
+      "duplicated": false,
+      "isNew": true
+    }
+  ]
+}
index ba2a4c6e52b3c923c7f9be3a2e8c564cd68a1852..fe9dad72f2e618a4a39d99fecbbec5a3c369775f 100644 (file)
@@ -4,7 +4,8 @@
       "code": "}",
       "line": 3,
       "scmAuthor": "polop",
-      "scmRevision": "cafebabe"
+      "scmRevision": "cafebabe",
+      "isNew": false
     }
   ]
 }