From e7232c4e1cd2e998924414ce07784333981cc1d0 Mon Sep 17 00:00:00 2001 From: Gregory Bean Date: Thu, 23 Feb 2012 11:03:40 -0800 Subject: [PATCH] Add dependencies to query. Change-Id: Iba0416003901624d739cf8e1d3b5c2b109b508a6 --- Documentation/cmd-query.txt | 5 ++ .../gerrit/server/events/ChangeAttribute.java | 3 + .../server/events/DependencyAttribute.java | 23 +++++++ .../gerrit/server/events/EventFactory.java | 64 ++++++++++++++++++- .../server/query/change/QueryProcessor.java | 26 ++++++++ .../google/gerrit/sshd/commands/Query.java | 5 ++ 6 files changed, 125 insertions(+), 1 deletion(-) create mode 100644 gerrit-server/src/main/java/com/google/gerrit/server/events/DependencyAttribute.java diff --git a/Documentation/cmd-query.txt b/Documentation/cmd-query.txt index 1bd4862e78..253bed18cc 100644 --- a/Documentation/cmd-query.txt +++ b/Documentation/cmd-query.txt @@ -15,6 +15,7 @@ SYNOPSIS [--files] [--comments] [--commit-message] + [--dependencies] [--] [limit:] @@ -75,6 +76,10 @@ OPTIONS --commit-message:: Include the full commit message in the change description. +--dependencies:: + Show information about patch sets which depend on, or are needed by, + each patch set. + limit::: Maximum number of results to return. This is actually a query operator, and not a command line option. If more diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/events/ChangeAttribute.java b/gerrit-server/src/main/java/com/google/gerrit/server/events/ChangeAttribute.java index bb5abe4a35..9810f59d28 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/events/ChangeAttribute.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/events/ChangeAttribute.java @@ -39,4 +39,7 @@ public class ChangeAttribute { public List trackingIds; public PatchSetAttribute currentPatchSet; public List patchSets; + + public List dependsOn; + public List neededBy; } diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/events/DependencyAttribute.java b/gerrit-server/src/main/java/com/google/gerrit/server/events/DependencyAttribute.java new file mode 100644 index 0000000000..47fbdac1c2 --- /dev/null +++ b/gerrit-server/src/main/java/com/google/gerrit/server/events/DependencyAttribute.java @@ -0,0 +1,23 @@ +// Copyright (C) 2012 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.google.gerrit.server.events; + +public class DependencyAttribute { + public String id; + public String number; + public String revision; + public String ref; + public Boolean isCurrentPatchSet; +} diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/events/EventFactory.java b/gerrit-server/src/main/java/com/google/gerrit/server/events/EventFactory.java index bc9047d0a3..4d34b716f1 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/events/EventFactory.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/events/EventFactory.java @@ -22,13 +22,18 @@ import com.google.gerrit.reviewdb.client.Change; import com.google.gerrit.reviewdb.client.ChangeMessage; import com.google.gerrit.reviewdb.client.PatchLineComment; import com.google.gerrit.reviewdb.client.PatchSet; +import com.google.gerrit.reviewdb.client.PatchSetAncestor; import com.google.gerrit.reviewdb.client.PatchSetApproval; +import com.google.gerrit.reviewdb.client.RevId; import com.google.gerrit.reviewdb.client.TrackingId; +import com.google.gerrit.reviewdb.server.ReviewDb; import com.google.gerrit.server.account.AccountCache; import com.google.gerrit.server.config.CanonicalWebUrl; import com.google.gerrit.server.patch.PatchList; import com.google.gerrit.server.patch.PatchListCache; import com.google.gerrit.server.patch.PatchListEntry; +import com.google.gwtorm.server.OrmException; +import com.google.gwtorm.server.SchemaFactory; import com.google.inject.Inject; import com.google.inject.Provider; import com.google.inject.Singleton; @@ -47,16 +52,18 @@ public class EventFactory { private final Provider urlProvider; private final ApprovalTypes approvalTypes; private final PatchListCache patchListCache; + private final SchemaFactory schema; @Inject EventFactory(AccountCache accountCache, @CanonicalWebUrl @Nullable Provider urlProvider, ApprovalTypes approvalTypes, - PatchListCache patchListCache) { + PatchListCache patchListCache, SchemaFactory schema) { this.accountCache = accountCache; this.urlProvider = urlProvider; this.approvalTypes = approvalTypes; this.patchListCache = patchListCache; + this.schema = schema; } /** @@ -110,6 +117,61 @@ public class EventFactory { a.status = change.getStatus(); } + public void addDependencies(ChangeAttribute ca, Change change) { + ca.dependsOn = new ArrayList(); + ca.neededBy = new ArrayList(); + try { + final ReviewDb db = schema.open(); + try { + final PatchSet.Id psId = change.currentPatchSetId(); + for (PatchSetAncestor a : db.patchSetAncestors().ancestorsOf(psId)) { + for (PatchSet p : + db.patchSets().byRevision(a.getAncestorRevision())) { + Change c = db.changes().get(p.getId().getParentKey()); + ca.dependsOn.add(newDependsOn(c, p)); + } + } + + final RevId revId = db.patchSets().get(psId).getRevision(); + for (PatchSetAncestor a : db.patchSetAncestors().descendantsOf(revId)) { + final PatchSet p = db.patchSets().get(a.getPatchSet()); + final Change c = db.changes().get(p.getId().getParentKey()); + ca.neededBy.add(newNeededBy(c, p)); + } + } finally { + db.close(); + } + } catch (OrmException e) { + // Squash DB exceptions and leave dependency lists partially filled. + } + // Remove empty lists so a confusing label won't be displayed in the output. + if (ca.dependsOn.isEmpty()) { + ca.dependsOn = null; + } + if (ca.neededBy.isEmpty()) { + ca.neededBy = null; + } + } + + private DependencyAttribute newDependsOn(Change c, PatchSet ps) { + DependencyAttribute d = newDependencyAttribute(c, ps); + d.isCurrentPatchSet = c.currPatchSetId().equals(ps.getId()); + return d; + } + + private DependencyAttribute newNeededBy(Change c, PatchSet ps) { + return newDependencyAttribute(c, ps); + } + + private DependencyAttribute newDependencyAttribute(Change c, PatchSet ps) { + DependencyAttribute d = new DependencyAttribute(); + d.number = c.getId().toString(); + d.id = c.getKey().toString(); + d.revision = ps.getRevision().get(); + d.ref = ps.getRefName(); + return d; + } + public void addTrackingIds(ChangeAttribute a, Collection ids) { if (!ids.isEmpty()) { a.trackingIds = new ArrayList(ids.size()); diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/QueryProcessor.java b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/QueryProcessor.java index e6848ed28f..a2fa7fe34c 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/QueryProcessor.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/QueryProcessor.java @@ -77,6 +77,7 @@ public class QueryProcessor { private boolean includeComments; private boolean includeFiles; private boolean includeCommitMessage; + private boolean includeDependencies; private OutputStream outputStream = DisabledOutputStream.INSTANCE; private PrintWriter out; @@ -128,6 +129,14 @@ public class QueryProcessor { return includeFiles; } + public void setIncludeDependencies(boolean on) { + includeDependencies = on; + } + + public boolean getIncludeDependencies() { + return includeDependencies; + } + public void setIncludeCommitMessage(boolean on) { includeCommitMessage = on; } @@ -242,6 +251,10 @@ public class QueryProcessor { } } + if (includeDependencies) { + eventFactory.addDependencies(c, d.getChange()); + } + show(c); } @@ -367,7 +380,20 @@ public class QueryProcessor { out.print('\n'); } else if (value instanceof Collection) { out.print('\n'); + boolean firstElement = true; for (Object thing : ((Collection) value)) { + // The name of the collection was initially printed at the beginning + // of this routine. Beginning at the second sub-element, reprint + // the collection name so humans can separate individual elements + // with less strain and error. + // + if (firstElement) { + firstElement = false; + } else { + out.print(indent); + out.print(field); + out.print(":\n"); + } if (isPrimitive(thing)) { out.print(' '); out.print(value); diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/Query.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/Query.java index 9bca0e5385..d9a1c3f551 100644 --- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/Query.java +++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/Query.java @@ -66,6 +66,11 @@ class Query extends BaseCommand { processor.setIncludeCommitMessage(on); } + @Option(name = "--dependencies", usage = "Include depends-on and needed-by information") + void setDependencies(boolean on) { + processor.setIncludeDependencies(on); + } + @Argument(index = 0, required = true, multiValued = true, metaVar = "QUERY", usage = "Query to execute") private List query;