Merge changes I8c164877,Idfd86ba8
* changes:
ReceiveCommits: Retry scanning for changes to auto-close
RetryHelper: Rename and parameterize the metrics
diff --git a/java/com/google/gerrit/server/account/AccountsUpdate.java b/java/com/google/gerrit/server/account/AccountsUpdate.java
index 7f9825f..ee3cf87f 100644
--- a/java/com/google/gerrit/server/account/AccountsUpdate.java
+++ b/java/com/google/gerrit/server/account/AccountsUpdate.java
@@ -29,6 +29,7 @@
import com.google.gerrit.server.GerritPersonIdent;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.account.externalids.ExternalIdNotes;
+import com.google.gerrit.server.account.externalids.ExternalIdNotes.ExternalIdNotesLoader;
import com.google.gerrit.server.config.AllUsersName;
import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
import com.google.gerrit.server.git.GitRepositoryManager;
@@ -161,6 +162,62 @@
}
/**
+ * Factory to create an AccountsUpdate instance for updating accounts by the Gerrit server.
+ *
+ * <p>Using this class no reindex will be performed for the affected accounts and they will also
+ * not be evicted from the account cache.
+ *
+ * <p>The Gerrit server identity will be used as author and committer for all commits that update
+ * the accounts.
+ */
+ @Singleton
+ public static class ServerNoReindex {
+ private final GitRepositoryManager repoManager;
+ private final GitReferenceUpdated gitRefUpdated;
+ private final AllUsersName allUsersName;
+ private final OutgoingEmailValidator emailValidator;
+ private final Provider<PersonIdent> serverIdentProvider;
+ private final Provider<MetaDataUpdate.InternalFactory> metaDataUpdateInternalFactory;
+ private final RetryHelper retryHelper;
+ private final ExternalIdNotes.FactoryNoReindex extIdNotesFactory;
+
+ @Inject
+ public ServerNoReindex(
+ GitRepositoryManager repoManager,
+ GitReferenceUpdated gitRefUpdated,
+ AllUsersName allUsersName,
+ OutgoingEmailValidator emailValidator,
+ @GerritPersonIdent Provider<PersonIdent> serverIdentProvider,
+ Provider<MetaDataUpdate.InternalFactory> metaDataUpdateInternalFactory,
+ RetryHelper retryHelper,
+ ExternalIdNotes.FactoryNoReindex extIdNotesFactory) {
+ this.repoManager = repoManager;
+ this.gitRefUpdated = gitRefUpdated;
+ this.allUsersName = allUsersName;
+ this.emailValidator = emailValidator;
+ this.serverIdentProvider = serverIdentProvider;
+ this.metaDataUpdateInternalFactory = metaDataUpdateInternalFactory;
+ this.retryHelper = retryHelper;
+ this.extIdNotesFactory = extIdNotesFactory;
+ }
+
+ public AccountsUpdate create() {
+ PersonIdent serverIdent = serverIdentProvider.get();
+ return new AccountsUpdate(
+ repoManager,
+ gitRefUpdated,
+ null,
+ allUsersName,
+ emailValidator,
+ metaDataUpdateInternalFactory,
+ retryHelper,
+ extIdNotesFactory,
+ serverIdent,
+ serverIdent);
+ }
+ }
+
+ /**
* Factory to create an AccountsUpdate instance for updating accounts by the current user.
*
* <p>The identity of the current user will be used as author for all commits that update the
@@ -229,7 +286,7 @@
private final OutgoingEmailValidator emailValidator;
private final Provider<MetaDataUpdate.InternalFactory> metaDataUpdateInternalFactory;
private final RetryHelper retryHelper;
- private final ExternalIdNotes.Factory extIdNotesFactory;
+ private final ExternalIdNotesLoader extIdNotesLoader;
private final PersonIdent committerIdent;
private final PersonIdent authorIdent;
private final Runnable afterReadRevision;
@@ -242,7 +299,7 @@
OutgoingEmailValidator emailValidator,
Provider<MetaDataUpdate.InternalFactory> metaDataUpdateInternalFactory,
RetryHelper retryHelper,
- ExternalIdNotes.Factory extIdNotesFactory,
+ ExternalIdNotesLoader extIdNotesLoader,
PersonIdent committerIdent,
PersonIdent authorIdent) {
this(
@@ -253,7 +310,7 @@
emailValidator,
metaDataUpdateInternalFactory,
retryHelper,
- extIdNotesFactory,
+ extIdNotesLoader,
committerIdent,
authorIdent,
Runnables.doNothing());
@@ -268,7 +325,7 @@
OutgoingEmailValidator emailValidator,
Provider<MetaDataUpdate.InternalFactory> metaDataUpdateInternalFactory,
RetryHelper retryHelper,
- ExternalIdNotes.Factory extIdNotesFactory,
+ ExternalIdNotesLoader extIdNotesLoader,
PersonIdent committerIdent,
PersonIdent authorIdent,
Runnable afterReadRevision) {
@@ -280,7 +337,7 @@
this.metaDataUpdateInternalFactory =
checkNotNull(metaDataUpdateInternalFactory, "metaDataUpdateInternalFactory");
this.retryHelper = checkNotNull(retryHelper, "retryHelper");
- this.extIdNotesFactory = checkNotNull(extIdNotesFactory, "extIdNotesFactory");
+ this.extIdNotesLoader = checkNotNull(extIdNotesLoader, "extIdNotesLoader");
this.committerIdent = checkNotNull(committerIdent, "committerIdent");
this.authorIdent = checkNotNull(authorIdent, "authorIdent");
this.afterReadRevision = afterReadRevision;
@@ -494,7 +551,7 @@
update.getDeletedExternalIds()),
accountId);
- ExternalIdNotes extIdNotes = extIdNotesFactory.load(allUsersRepo);
+ ExternalIdNotes extIdNotes = extIdNotesLoader.load(allUsersRepo);
extIdNotes.replace(update.getDeletedExternalIds(), update.getCreatedExternalIds());
extIdNotes.upsert(update.getUpdatedExternalIds());
return extIdNotes;
diff --git a/java/com/google/gerrit/server/account/externalids/ExternalIdNotes.java b/java/com/google/gerrit/server/account/externalids/ExternalIdNotes.java
index f6ded07..f663247 100644
--- a/java/com/google/gerrit/server/account/externalids/ExternalIdNotes.java
+++ b/java/com/google/gerrit/server/account/externalids/ExternalIdNotes.java
@@ -78,8 +78,12 @@
private static final int MAX_NOTE_SZ = 1 << 19;
+ public interface ExternalIdNotesLoader {
+ ExternalIdNotes load(Repository allUsersRepo) throws IOException, ConfigInvalidException;
+ }
+
@Singleton
- public static class Factory {
+ public static class Factory implements ExternalIdNotesLoader {
private final ExternalIdCache externalIdCache;
private final AccountCache accountCache;
@@ -89,6 +93,7 @@
this.accountCache = accountCache;
}
+ @Override
public ExternalIdNotes load(Repository allUsersRepo)
throws IOException, ConfigInvalidException {
return new ExternalIdNotes(externalIdCache, accountCache, allUsersRepo).load();
@@ -96,7 +101,7 @@
}
@Singleton
- public static class FactoryNoReindex {
+ public static class FactoryNoReindex implements ExternalIdNotesLoader {
private final ExternalIdCache externalIdCache;
@Inject
@@ -104,6 +109,7 @@
this.externalIdCache = externalIdCache;
}
+ @Override
public ExternalIdNotes load(Repository allUsersRepo)
throws IOException, ConfigInvalidException {
return new ExternalIdNotes(externalIdCache, null, allUsersRepo).load();
diff --git a/java/com/google/gerrit/server/schema/AllUsersCreator.java b/java/com/google/gerrit/server/schema/AllUsersCreator.java
index 8a11ca8..8e38754 100644
--- a/java/com/google/gerrit/server/schema/AllUsersCreator.java
+++ b/java/com/google/gerrit/server/schema/AllUsersCreator.java
@@ -37,7 +37,9 @@
import java.io.IOException;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.errors.RepositoryNotFoundException;
+import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.PersonIdent;
+import org.eclipse.jgit.lib.RefUpdate;
import org.eclipse.jgit.lib.Repository;
/** Creates the {@code All-Users} repository. */
@@ -76,6 +78,8 @@
} catch (RepositoryNotFoundException notFound) {
try (Repository git = mgr.createRepository(allUsersName)) {
initAllUsers(git);
+ RefUpdate u = git.updateRef(Constants.HEAD);
+ u.link(RefNames.REFS_CONFIG);
} catch (RepositoryNotFoundException err) {
String name = allUsersName.get();
throw new IOException("Cannot create repository " + name, err);
diff --git a/java/com/google/gerrit/server/schema/SchemaVersion.java b/java/com/google/gerrit/server/schema/SchemaVersion.java
index 61a6235..4b8c13f 100644
--- a/java/com/google/gerrit/server/schema/SchemaVersion.java
+++ b/java/com/google/gerrit/server/schema/SchemaVersion.java
@@ -35,7 +35,7 @@
/** A version of the database schema. */
public abstract class SchemaVersion {
/** The current schema version. */
- public static final Class<Schema_165> C = Schema_165.class;
+ public static final Class<Schema_166> C = Schema_166.class;
public static int getBinaryVersion() {
return guessVersion(C);
diff --git a/java/com/google/gerrit/server/schema/Schema_166.java b/java/com/google/gerrit/server/schema/Schema_166.java
new file mode 100644
index 0000000..aa6f4e6
--- /dev/null
+++ b/java/com/google/gerrit/server/schema/Schema_166.java
@@ -0,0 +1,52 @@
+// Copyright (C) 2018 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.schema;
+
+import com.google.gerrit.reviewdb.client.RefNames;
+import com.google.gerrit.reviewdb.server.ReviewDb;
+import com.google.gerrit.server.config.AllUsersName;
+import com.google.gerrit.server.git.GitRepositoryManager;
+import com.google.gwtorm.server.OrmException;
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+import java.io.IOException;
+import java.sql.SQLException;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.RefUpdate;
+import org.eclipse.jgit.lib.Repository;
+
+/** Set HEAD for All-Users to refs/meta/config. */
+public class Schema_166 extends SchemaVersion {
+ private final GitRepositoryManager repoManager;
+ private final AllUsersName allUsersName;
+
+ @Inject
+ Schema_166(
+ Provider<Schema_165> prior, GitRepositoryManager repoManager, AllUsersName allUsersName) {
+ super(prior);
+ this.repoManager = repoManager;
+ this.allUsersName = allUsersName;
+ }
+
+ @Override
+ protected void migrateData(ReviewDb db, UpdateUI ui) throws OrmException, SQLException {
+ try (Repository git = repoManager.openRepository(allUsersName)) {
+ RefUpdate u = git.updateRef(Constants.HEAD);
+ u.link(RefNames.REFS_CONFIG);
+ } catch (IOException e) {
+ throw new OrmException(String.format("Failed to update HEAD for %s", allUsersName.get()), e);
+ }
+ }
+}
diff --git a/javatests/com/google/gerrit/acceptance/git/RefAdvertisementIT.java b/javatests/com/google/gerrit/acceptance/git/RefAdvertisementIT.java
index 0e39ee1..cc5b5d3 100644
--- a/javatests/com/google/gerrit/acceptance/git/RefAdvertisementIT.java
+++ b/javatests/com/google/gerrit/acceptance/git/RefAdvertisementIT.java
@@ -66,6 +66,7 @@
import java.util.function.Predicate;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.junit.TestRepository;
+import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.Ref;
@@ -650,7 +651,8 @@
RefNames.refsGroups(nonInteractiveUsers),
RefNames.REFS_SEQUENCES + Sequences.NAME_ACCOUNTS,
RefNames.REFS_SEQUENCES + Sequences.NAME_GROUPS,
- RefNames.REFS_CONFIG);
+ RefNames.REFS_CONFIG,
+ Constants.HEAD);
List<String> expectedMetaRefs =
new ArrayList<>(ImmutableList.of(mr.getPatchSetId().toRefName()));
diff --git a/javatests/com/google/gerrit/acceptance/rest/project/ListProjectsIT.java b/javatests/com/google/gerrit/acceptance/rest/project/ListProjectsIT.java
index ffde073..4af329a 100644
--- a/javatests/com/google/gerrit/acceptance/rest/project/ListProjectsIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/project/ListProjectsIT.java
@@ -182,8 +182,7 @@
public void listProjectWithType() throws Exception {
Map<String, ProjectInfo> result =
gApi.projects().list().withType(FilterType.PERMISSIONS).getAsMap();
- assertThat(result).hasSize(1);
- assertThat(result).containsKey(allProjects.get());
+ assertThat(result.keySet()).containsExactly(allProjects.get(), allUsers.get());
assertThatNameList(filter(gApi.projects().list().withType(FilterType.ALL).get()))
.containsExactly(allProjects, allUsers, project)
diff --git a/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view.js b/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view.js
index 37b2c21..a7b5e54 100644
--- a/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view.js
+++ b/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view.js
@@ -117,40 +117,32 @@
if (linkCopy.name === 'Repositories' && this._repoName) {
linkCopy.subsection = {
name: this._repoName,
- view: 'gr-repo',
+ view: Gerrit.Nav.View.REPO,
noBaseUrl: true,
- url: `/admin/repos/${this.encodeURL(this._repoName, true)}`,
+ url: Gerrit.Nav.getUrlForRepo(this._repoName),
children: [{
name: 'Access',
- detailType: 'access',
- view: 'gr-repo-access',
- noBaseUrl: true,
- url: `/admin/repos/` +
- `${this.encodeURL(this._repoName, true)},access`,
+ view: Gerrit.Nav.View.REPO,
+ detailType: Gerrit.Nav.RepoDetailView.ACCESS,
+ url: Gerrit.Nav.getUrlForRepoAccess(this._repoName),
},
{
name: 'Commands',
- detailType: 'commands',
- view: 'gr-repo-commands',
- noBaseUrl: true,
- url: `/admin/repos/` +
- `${this.encodeURL(this._repoName, true)},commands`,
+ view: Gerrit.Nav.View.REPO,
+ detailType: Gerrit.Nav.RepoDetailView.COMMANDS,
+ url: Gerrit.Nav.getUrlForRepoCommands(this._repoName),
},
{
name: 'Branches',
- detailType: 'branches',
- view: 'gr-repo-detail-list',
- noBaseUrl: true,
- url: `/admin/repos/` +
- `${this.encodeURL(this._repoName, true)},branches`,
+ view: Gerrit.Nav.View.REPO,
+ detailType: Gerrit.Nav.RepoDetailView.BRANCHES,
+ url: Gerrit.Nav.getUrlForRepoBranches(this._repoName),
},
{
name: 'Tags',
- detailType: 'tags',
- view: 'gr-repo-detail-list',
- noBaseUrl: true,
- url: `/admin/repos/` +
- `${this.encodeURL(this._repoName, true)},tags`,
+ view: Gerrit.Nav.View.REPO,
+ detailType: Gerrit.Nav.RepoDetailView.TAGS,
+ url: Gerrit.Nav.getUrlForRepoTags(this._repoName),
}],
};
}
@@ -268,6 +260,13 @@
return '';
}
+ if (params.view === Gerrit.Nav.View.REPO &&
+ itemView === Gerrit.Nav.View.REPO) {
+ if (!params.detail && !opt_detailType) { return 'selected'; }
+ if (params.detail === opt_detailType) { return 'selected'; }
+ return '';
+ }
+
if (params.detailType && params.detailType !== opt_detailType) {
return '';
}
diff --git a/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view_test.html b/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view_test.html
index 6a90488..bd79872 100644
--- a/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view_test.html
+++ b/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view_test.html
@@ -258,9 +258,8 @@
test('repo', done => {
element.params = {
- view: Gerrit.Nav.View.ADMIN,
- project: 'foo',
- adminView: 'gr-repo',
+ view: Gerrit.Nav.View.REPO,
+ repoName: 'foo',
};
element._repoName = 'foo';
element.reload().then(() => {
@@ -275,10 +274,9 @@
test('repo access', done => {
element.params = {
- view: Gerrit.Nav.View.ADMIN,
- adminView: 'gr-repo-access',
- detailType: 'access',
- repo: 'foo',
+ view: Gerrit.Nav.View.REPO,
+ detail: Gerrit.Nav.RepoDetailView.ACCESS,
+ repoName: 'foo',
};
element._repoName = 'foo';
element.reload().then(() => {
diff --git a/polygerrit-ui/app/elements/change/gr-message/gr-message.html b/polygerrit-ui/app/elements/change/gr-message/gr-message.html
index e93e710..526cc86 100644
--- a/polygerrit-ui/app/elements/change/gr-message/gr-message.html
+++ b/polygerrit-ui/app/elements/change/gr-message/gr-message.html
@@ -195,6 +195,7 @@
<span class="date">
<gr-date-formatter
has-tooltip
+ show-date-and-time
date-str="[[message.date]]"></gr-date-formatter>
</span>
</template>
@@ -202,6 +203,7 @@
<a class="date" href$="[[_computeMessageHash(message)]]" on-tap="_handleLinkTap">
<gr-date-formatter
has-tooltip
+ show-date-and-time
date-str="[[message.date]]"></gr-date-formatter>
</a>
</template>
diff --git a/polygerrit-ui/app/elements/core/gr-navigation/gr-navigation.html b/polygerrit-ui/app/elements/core/gr-navigation/gr-navigation.html
index f8c7e74..7b17f22 100644
--- a/polygerrit-ui/app/elements/core/gr-navigation/gr-navigation.html
+++ b/polygerrit-ui/app/elements/core/gr-navigation/gr-navigation.html
@@ -55,6 +55,12 @@
// - `groupId`, required, String, the ID of the group.
// - `detail`, optional, String, the name of the group detail view.
// Takes any value from Gerrit.Nav.GroupDetailView.
+ //
+ // - Gerrit.Nav.View.REPO:
+ // - `repoName`, required, String, the name of the repo
+ // - `detail`, optional, String, the name of the repo detail view.
+ // Takes any value from Gerrit.Nav.RepoDetailView.
+
window.Gerrit = window.Gerrit || {};
@@ -79,6 +85,7 @@
EDIT: 'edit',
GROUP: 'group',
PLUGIN_SCREEN: 'plugin-screen',
+ REPO: 'repo',
SEARCH: 'search',
SETTINGS: 'settings',
},
@@ -88,6 +95,13 @@
LOG: 'log',
},
+ RepoDetailView: {
+ ACCESS: 'access',
+ BRANCHES: 'branches',
+ COMMANDS: 'commands',
+ TAGS: 'tags',
+ },
+
WeblinkType: {
CHANGE: 'change',
FILE: 'file',
@@ -362,6 +376,65 @@
},
/**
+ * @param {string} repoName
+ * @return {string}
+ */
+ getUrlForRepo(repoName) {
+ return this._getUrlFor({
+ view: Gerrit.Nav.View.REPO,
+ repoName,
+ });
+ },
+
+ /**
+ * @param {string} repoName
+ * @return {string}
+ */
+ getUrlForRepoTags(repoName) {
+ return this._getUrlFor({
+ view: Gerrit.Nav.View.REPO,
+ repoName,
+ detail: Gerrit.Nav.RepoDetailView.TAGS,
+ });
+ },
+
+ /**
+ * @param {string} repoName
+ * @return {string}
+ */
+ getUrlForRepoBranches(repoName) {
+ return this._getUrlFor({
+ view: Gerrit.Nav.View.REPO,
+ repoName,
+ detail: Gerrit.Nav.RepoDetailView.BRANCHES,
+ });
+ },
+
+ /**
+ * @param {string} repoName
+ * @return {string}
+ */
+ getUrlForRepoAccess(repoName) {
+ return this._getUrlFor({
+ view: Gerrit.Nav.View.REPO,
+ repoName,
+ detail: Gerrit.Nav.RepoDetailView.ACCESS,
+ });
+ },
+
+ /**
+ * @param {string} repoName
+ * @return {string}
+ */
+ getUrlForRepoCommands(repoName) {
+ return this._getUrlFor({
+ view: Gerrit.Nav.View.REPO,
+ repoName,
+ detail: Gerrit.Nav.RepoDetailView.COMMANDS,
+ });
+ },
+
+ /**
* @param {string} groupId
* @return {string}
*/
diff --git a/polygerrit-ui/app/elements/core/gr-router/gr-router.js b/polygerrit-ui/app/elements/core/gr-router/gr-router.js
index f309747..37f9f23 100644
--- a/polygerrit-ui/app/elements/core/gr-router/gr-router.js
+++ b/polygerrit-ui/app/elements/core/gr-router/gr-router.js
@@ -233,6 +233,8 @@
url = this._generateDiffOrEditUrl(params);
} else if (params.view === Views.GROUP) {
url = this._generateGroupUrl(params);
+ } else if (params.view === Views.REPO) {
+ url = this._generateRepoUrl(params);
} else if (params.view === Views.SETTINGS) {
url = this._generateSettingsUrl(params);
} else {
@@ -448,6 +450,24 @@
* @param {!Object} params
* @return {string}
*/
+ _generateRepoUrl(params) {
+ let url = `/admin/repos/${this.encodeURL(params.repoName + '', true)}`;
+ if (params.detail === Gerrit.Nav.RepoDetailView.ACCESS) {
+ url += ',access';
+ } else if (params.detail === Gerrit.Nav.RepoDetailView.BRANCHES) {
+ url += ',branches';
+ } else if (params.detail === Gerrit.Nav.RepoDetailView.TAGS) {
+ url += ',tags';
+ } else if (params.detail === Gerrit.Nav.RepoDetailView.COMMANDS) {
+ url += ',commands';
+ }
+ return url;
+ },
+
+ /**
+ * @param {!Object} params
+ * @return {string}
+ */
_generateSettingsUrl(params) {
return '/settings';
},
diff --git a/polygerrit-ui/app/elements/shared/gr-date-formatter/gr-date-formatter.html b/polygerrit-ui/app/elements/shared/gr-date-formatter/gr-date-formatter.html
index 21552d9..fb41ca6 100644
--- a/polygerrit-ui/app/elements/shared/gr-date-formatter/gr-date-formatter.html
+++ b/polygerrit-ui/app/elements/shared/gr-date-formatter/gr-date-formatter.html
@@ -30,7 +30,7 @@
}
</style>
<span>
- [[_computeDateStr(dateStr, _timeFormat, _relative)]]
+ [[_computeDateStr(dateStr, _timeFormat, _relative, showDateAndTime)]]
</span>
<gr-rest-api-interface id="restAPI"></gr-rest-api-interface>
</template>
diff --git a/polygerrit-ui/app/elements/shared/gr-date-formatter/gr-date-formatter.js b/polygerrit-ui/app/elements/shared/gr-date-formatter/gr-date-formatter.js
index 65a4c68..3f7b8db 100644
--- a/polygerrit-ui/app/elements/shared/gr-date-formatter/gr-date-formatter.js
+++ b/polygerrit-ui/app/elements/shared/gr-date-formatter/gr-date-formatter.js
@@ -37,6 +37,10 @@
value: null,
notify: true,
},
+ showDateAndTime: {
+ type: Boolean,
+ value: false,
+ },
/**
* When true, the detailed date appears in a GR-TOOLTIP rather than in the
@@ -131,7 +135,7 @@
diff < 180 * Duration.DAY;
},
- _computeDateStr(dateStr, timeFormat, relative) {
+ _computeDateStr(dateStr, timeFormat, relative, showDateAndTime) {
if (!dateStr) { return ''; }
const date = moment(util.parseDate(dateStr));
if (!date.isValid()) { return ''; }
@@ -147,8 +151,13 @@
let format = TimeFormats.MONTH_DAY_YEAR;
if (this._isWithinDay(now, date)) {
format = timeFormat;
- } else if (this._isWithinHalfYear(now, date)) {
- format = TimeFormats.MONTH_DAY;
+ } else {
+ if (this._isWithinHalfYear(now, date)) {
+ format = TimeFormats.MONTH_DAY;
+ }
+ if (this.showDateAndTime) {
+ format = `${format} ${timeFormat}`;
+ }
}
return date.format(format);
},
diff --git a/polygerrit-ui/app/elements/shared/gr-date-formatter/gr-date-formatter_test.html b/polygerrit-ui/app/elements/shared/gr-date-formatter/gr-date-formatter_test.html
index 2c15ef6..b418a42 100644
--- a/polygerrit-ui/app/elements/shared/gr-date-formatter/gr-date-formatter_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-date-formatter/gr-date-formatter_test.html
@@ -55,7 +55,8 @@
return d;
}
- function testDates(nowStr, dateStr, expected, expectedTooltip, done) {
+ function testDates(nowStr, dateStr, expected, expectedWithDateAndTime,
+ expectedTooltip, done) {
// Normalize and convert the date to mimic server response.
dateStr = normalizedDate(dateStr)
.toJSON().replace('T', ' ').slice(0, -1);
@@ -65,6 +66,9 @@
const span = element.$$('span');
assert.equal(span.textContent.trim(), expected);
assert.equal(element.title, expectedTooltip);
+ element.showDateAndTime = true;
+ flushAsynchronousOperations();
+ assert.equal(span.textContent.trim(), expectedWithDateAndTime);
done();
});
}
@@ -98,25 +102,33 @@
test('Within 24 hours on same day', done => {
testDates('2015-07-29 20:34:14.985000000',
'2015-07-29 15:34:14.985000000',
- '15:34', 'Jul 29, 2015, 15:34:14', done);
+ '15:34',
+ '15:34',
+ 'Jul 29, 2015, 15:34:14', done);
});
test('Within 24 hours on different days', done => {
testDates('2015-07-29 03:34:14.985000000',
'2015-07-28 20:25:14.985000000',
- 'Jul 28', 'Jul 28, 2015, 20:25:14', done);
+ 'Jul 28',
+ 'Jul 28 20:25',
+ 'Jul 28, 2015, 20:25:14', done);
});
test('More than 24 hours but less than six months', done => {
testDates('2015-07-29 20:34:14.985000000',
'2015-06-15 03:25:14.985000000',
- 'Jun 15', 'Jun 15, 2015, 03:25:14', done);
+ 'Jun 15',
+ 'Jun 15 03:25',
+ 'Jun 15, 2015, 03:25:14', done);
});
test('More than six months', done => {
testDates('2015-09-15 20:34:00.000000000',
'2015-01-15 03:25:00.000000000',
- 'Jan 15, 2015', 'Jan 15, 2015, 03:25:00', done);
+ 'Jan 15, 2015',
+ 'Jan 15, 2015 03:25',
+ 'Jan 15, 2015, 03:25:00', done);
});
});
@@ -135,7 +147,9 @@
test('Within 24 hours on same day', done => {
testDates('2015-07-29 20:34:14.985000000',
'2015-07-29 15:34:14.985000000',
- '3:34 PM', 'Jul 29, 2015, 3:34:14 PM', done);
+ '3:34 PM',
+ '3:34 PM',
+ 'Jul 29, 2015, 3:34:14 PM', done);
});
});
@@ -153,13 +167,17 @@
test('Within 24 hours on same day', done => {
testDates('2015-07-29 20:34:14.985000000',
'2015-07-29 15:34:14.985000000',
- '5 hours ago', 'Jul 29, 2015, 3:34:14 PM', done);
+ '5 hours ago',
+ '5 hours ago',
+ 'Jul 29, 2015, 3:34:14 PM', done);
});
test('More than six months', done => {
testDates('2015-09-15 20:34:00.000000000',
'2015-01-15 03:25:00.000000000',
- '8 months ago', 'Jan 15, 2015, 3:25:00 AM', done);
+ '8 months ago',
+ '8 months ago',
+ 'Jan 15, 2015, 3:25:00 AM', done);
});
});
diff --git a/resources/com/google/gerrit/httpd/auth/ldap/LoginForm.html b/resources/com/google/gerrit/httpd/auth/ldap/LoginForm.html
index 64d16c5..c5e38b3 100644
--- a/resources/com/google/gerrit/httpd/auth/ldap/LoginForm.html
+++ b/resources/com/google/gerrit/httpd/auth/ldap/LoginForm.html
@@ -15,7 +15,7 @@
</style>
<style id="gerrit_sitecss" type="text/css"></style>
</head>
- <body>
+ <body class="login" id="login_ldap">
<div id="gerrit_topmenu" style="height:45px;" class="gerritTopMenu"></div>
<div id="gerrit_header"></div>
<div id="gerrit_body" class="gerritBody">
diff --git a/resources/com/google/gerrit/httpd/auth/oauth/LoginForm.html b/resources/com/google/gerrit/httpd/auth/oauth/LoginForm.html
index f7814c0..67c40c3 100644
--- a/resources/com/google/gerrit/httpd/auth/oauth/LoginForm.html
+++ b/resources/com/google/gerrit/httpd/auth/oauth/LoginForm.html
@@ -24,7 +24,7 @@
</style>
<style id="gerrit_sitecss" type="text/css"></style>
</head>
- <body>
+ <body class="login" id="login_oauth">
<div id="gerrit_topmenu" style="height:45px;" class="gerritTopMenu"></div>
<div id="gerrit_header"></div>
<div id="gerrit_body" class="gerritBody">
diff --git a/resources/com/google/gerrit/httpd/auth/openid/LoginForm.html b/resources/com/google/gerrit/httpd/auth/openid/LoginForm.html
index 07e09f5..4923143 100644
--- a/resources/com/google/gerrit/httpd/auth/openid/LoginForm.html
+++ b/resources/com/google/gerrit/httpd/auth/openid/LoginForm.html
@@ -39,7 +39,7 @@
</style>
<style id="gerrit_sitecss" type="text/css"></style>
</head>
- <body>
+ <body class="login" id="login_openid">
<div id="gerrit_topmenu" style="height:45px;" class="gerritTopMenu"></div>
<div id="gerrit_header"></div>
<div id="gerrit_body" class="gerritBody">
diff --git a/tools/bzl/asciidoc.bzl b/tools/bzl/asciidoc.bzl
index 9fb53c0..62fa4c6 100644
--- a/tools/bzl/asciidoc.bzl
+++ b/tools/bzl/asciidoc.bzl
@@ -122,9 +122,9 @@
}
_asciidoc = rule(
- attrs = _asciidoc_attrs + {
+ attrs = dict(_asciidoc_attrs.items() + {
"outs": attr.output_list(mandatory = True),
- },
+ }.items()),
implementation = _asciidoc_impl,
)
diff --git a/tools/bzl/js.bzl b/tools/bzl/js.bzl
index 2e74091..945b8e1 100644
--- a/tools/bzl/js.bzl
+++ b/tools/bzl/js.bzl
@@ -177,10 +177,10 @@
js_component = rule(
_js_component,
- attrs = _common_attrs + {
+ attrs = dict(_common_attrs.items() + {
"srcs": attr.label_list(allow_files = [".js"]),
"license": attr.label(allow_single_file = True),
- },
+ }.items()),
outputs = {
"zip": "%{name}.zip",
},
@@ -188,14 +188,14 @@
_bower_component = rule(
_bower_component_impl,
- attrs = _common_attrs + {
+ attrs = dict(_common_attrs.items() + {
"zipfile": attr.label(allow_single_file = [".zip"]),
"license": attr.label(allow_single_file = True),
"version_json": attr.label(allow_files = [".json"]),
# If set, define by hand, and don't regenerate this entry in bower2bazel.
"seed": attr.bool(default = False),
- },
+ }.items()),
)
# TODO(hanwen): make license mandatory.