Merge "Upstream fixes from import"
diff --git a/web/code-owners-api.ts b/web/code-owners-api.ts
index c2a2374..70573c1 100644
--- a/web/code-owners-api.ts
+++ b/web/code-owners-api.ts
@@ -92,7 +92,7 @@
}
export interface PathCodeOwnerStatusInfo {
path: string;
- status?: OwnerStatus;
+ status: OwnerStatus;
reasons?: Array<string>;
}
@@ -145,7 +145,7 @@
* Send a get request and provides custom response-code handling
*/
private async get(url: string): Promise<unknown> {
- const errFn = (response?: Response | null, error?: Error) => {
+ const errFn = (response?: Response|null, error?: Error) => {
if (error) throw error;
if (response) throw new ResponseError(response);
throw new Error('Generic REST API error');
@@ -163,57 +163,57 @@
}
/**
- * Returns a promise fetching the owner statuses for all files within the change.
+ * Returns a promise fetching the owner statuses for all files within the
+ * change.
*
- * @doc https://gerrit.googlesource.com/plugins/code-owners/+/HEAD/resources/Documentation/rest-api.md#change-endpoints
+ * @doc
+ * https://gerrit.googlesource.com/plugins/code-owners/+/HEAD/resources/Documentation/rest-api.md#change-endpoints
*/
listOwnerStatus(changeId: NumericChangeId): Promise<CodeOwnerStatusInfo> {
- return this.get(
- `/changes/${changeId}/code_owners.status?limit=100000`
- ) as Promise<CodeOwnerStatusInfo>;
+ return this.get(`/changes/${changeId}/code_owners.status?limit=100000`) as
+ Promise<CodeOwnerStatusInfo>;
}
/**
* Returns a promise fetching the owners for a given path.
*
- * @doc https://gerrit.googlesource.com/plugins/code-owners/+/HEAD/resources/Documentation/rest-api.md#list-code-owners-for-path-in-branch
+ * @doc
+ * https://gerrit.googlesource.com/plugins/code-owners/+/HEAD/resources/Documentation/rest-api.md#list-code-owners-for-path-in-branch
*/
- listOwnersForPath(
- changeId: NumericChangeId,
- path: string,
- limit: number
- ): Promise<CodeOwnersInfo> {
+ listOwnersForPath(changeId: NumericChangeId, path: string, limit: number):
+ Promise<CodeOwnersInfo> {
return this.get(
- `/changes/${changeId}/revisions/current/code_owners` +
- `/${encodeURIComponent(path)}?limit=${limit}&o=DETAILS`
- ) as Promise<CodeOwnersInfo>;
+ `/changes/${changeId}/revisions/current/code_owners` +
+ `/${encodeURIComponent(path)}?limit=${limit}&o=DETAILS`) as
+ Promise<CodeOwnersInfo>;
}
/**
* Returns a promise fetching the owners config for a given path.
*
- * @doc https://gerrit.googlesource.com/plugins/code-owners/+/HEAD/resources/Documentation/rest-api.md#branch-endpoints
+ * @doc
+ * https://gerrit.googlesource.com/plugins/code-owners/+/HEAD/resources/Documentation/rest-api.md#branch-endpoints
*/
getConfigForPath(project: string, branch: string, path: string) {
return this.get(
- `/projects/${encodeURIComponent(project)}/` +
+ `/projects/${encodeURIComponent(project)}/` +
`branches/${encodeURIComponent(branch)}/` +
- `code_owners.config/${encodeURIComponent(path)}`
- );
+ `code_owners.config/${encodeURIComponent(path)}`);
}
/**
* Returns a promise fetching the owners config for a given branch.
*
- * @doc https://gerrit.googlesource.com/plugins/code-owners/+/HEAD/resources/Documentation/rest-api.md#branch-endpoints
+ * @doc
+ * https://gerrit.googlesource.com/plugins/code-owners/+/HEAD/resources/Documentation/rest-api.md#branch-endpoints
*/
async getBranchConfig(project: RepoName, branch: BranchName) {
try {
- const config = (await this.get(
- `/projects/${encodeURIComponent(project)}/` +
- `branches/${encodeURIComponent(branch)}/` +
- `code_owners.branch_config`
- )) as CodeOwnerBranchConfigInfo;
+ const config =
+ (await this.get(
+ `/projects/${encodeURIComponent(project)}/` +
+ `branches/${encodeURIComponent(branch)}/` +
+ `code_owners.branch_config`)) as CodeOwnerBranchConfigInfo;
return config;
} catch (err) {
if (err instanceof ResponseError) {
@@ -249,14 +249,11 @@
private promises = new Map<string, Promise<unknown>>();
constructor(
- private readonly codeOwnerApi: CodeOwnersApi,
- private readonly change: ChangeInfo
- ) {}
+ private readonly codeOwnerApi: CodeOwnersApi,
+ private readonly change: ChangeInfo) {}
- private fetchOnce(
- cacheKey: string,
- asyncFn: () => Promise<unknown>
- ): Promise<unknown> {
+ private fetchOnce(cacheKey: string, asyncFn: () => Promise<unknown>):
+ Promise<unknown> {
let promise = this.promises.get(cacheKey);
if (promise) return promise;
promise = asyncFn();
@@ -264,10 +261,9 @@
return promise;
}
- getAccount(): Promise<AccountDetailInfo | undefined> {
- return this.fetchOnce('getAccount', () => this.getAccountImpl()) as Promise<
- AccountDetailInfo | undefined
- >;
+ getAccount(): Promise<AccountDetailInfo|undefined> {
+ return this.fetchOnce('getAccount', () => this.getAccountImpl()) as
+ Promise<AccountDetailInfo|undefined>;
}
private async getAccountImpl() {
@@ -277,14 +273,17 @@
}
listOwnerStatus(): Promise<CodeOwnerStatusInfo> {
- return this.fetchOnce('listOwnerStatus', () =>
- this.codeOwnerApi.listOwnerStatus(this.change._number)
- ) as Promise<CodeOwnerStatusInfo>;
+ return this.fetchOnce(
+ 'listOwnerStatus',
+ () => this.codeOwnerApi.listOwnerStatus(this.change._number)) as
+ Promise<CodeOwnerStatusInfo>;
}
getBranchConfig(): Promise<CodeOwnerBranchConfigInfo> {
- return this.fetchOnce('getBranchConfig', () =>
- this.codeOwnerApi.getBranchConfig(this.change.project, this.change.branch)
- ) as Promise<CodeOwnerBranchConfigInfo>;
+ return this.fetchOnce(
+ 'getBranchConfig',
+ () => this.codeOwnerApi.getBranchConfig(
+ this.change.project, this.change.branch)) as
+ Promise<CodeOwnerBranchConfigInfo>;
}
}
diff --git a/web/code-owners-model.ts b/web/code-owners-model.ts
index 18ebf64..3e8d8ff 100644
--- a/web/code-owners-model.ts
+++ b/web/code-owners-model.ts
@@ -48,9 +48,8 @@
export function isPluginErrorState(state: PluginState) {
return (
- state === PluginState.ServerConfigurationError ||
- state === PluginState.Failed
- );
+ state === PluginState.ServerConfigurationError ||
+ state === PluginState.Failed);
}
export enum SuggestionsType {
@@ -88,14 +87,14 @@
export interface FileStatus {
changeType: ChangeType;
status: OwnerStatus;
- newPath?: string | null;
- oldPath?: string | null;
+ newPath?: string|null;
+ oldPath?: string|null;
}
export const BestSuggestionsLimit = 5;
export const AllSuggestionsLimit = 1000;
-let codeOwnersModel: CodeOwnersModel | undefined;
+let codeOwnersModel: CodeOwnersModel|undefined;
export interface CodeOwnersState {
showSuggestions: boolean;
@@ -112,11 +111,11 @@
* Maintain the state of code-owners.
* Raises 'model-property-changed' event when a property is changed.
* The plugin shares the same model between all UI elements (if it is not,
- * the plugin can't maintain showSuggestions state across different UI elements).
- * UI elements use values from this model to display information
- * and listens for the model-property-changed event. To do so, UI elements
- * add CodeOwnersModelMixin, which is doing the listening and the translation
- * from model-property-changed event to Polymer property-changed-event. The
+ * the plugin can't maintain showSuggestions state across different UI
+ * elements). UI elements use values from this model to display information and
+ * listens for the model-property-changed event. To do so, UI elements add
+ * CodeOwnersModelMixin, which is doing the listening and the translation from
+ * model-property-changed event to Polymer property-changed-event. The
* translation allows to use model properties in observables, bindings,
* computed properties, etc...
* The CodeOwnersModelLoader updates the model.
@@ -136,26 +135,23 @@
public showSuggestions$ = select(this.state$, state => state.showSuggestions);
- public selectedSuggestionsType$ = select(
- this.state$,
- state => state.selectedSuggestionsType
- );
+ public selectedSuggestionsType$ =
+ select(this.state$, state => state.selectedSuggestionsType);
public selectedSuggestionsFiles$ = select(
- this.state$,
- state => state.suggestionsByTypes.get(state.selectedSuggestionsType)?.files
- );
+ this.state$,
+ state =>
+ state.suggestionsByTypes.get(state.selectedSuggestionsType)?.files);
public selectedSuggestionsState$ = select(
- this.state$,
- state => state.suggestionsByTypes.get(state.selectedSuggestionsType)!.state
- );
+ this.state$,
+ state =>
+ state.suggestionsByTypes.get(state.selectedSuggestionsType)!.state);
public selectedSuggestionsLoadProgress$ = select(
- this.state$,
- state =>
- state.suggestionsByTypes.get(state.selectedSuggestionsType)!.loadProgress
- );
+ this.state$,
+ state => state.suggestionsByTypes.get(state.selectedSuggestionsType)!
+ .loadProgress);
constructor(readonly change: ChangeInfo) {
super();
@@ -233,9 +229,8 @@
}
private updateSuggestion(
- suggestionsType: SuggestionsType,
- suggestionsUpdate: Partial<Suggestion>
- ) {
+ suggestionsType: SuggestionsType,
+ suggestionsUpdate: Partial<Suggestion>) {
const current = this.subject$.getValue();
const nextState = {
...current,
@@ -249,9 +244,7 @@
}
setSuggestionsFiles(
- suggestionsType: SuggestionsType,
- files: Array<FetchedFile>
- ) {
+ suggestionsType: SuggestionsType, files: Array<FetchedFile>) {
const current = this.subject$.getValue();
const suggestions = current.suggestionsByTypes.get(suggestionsType);
if (!suggestions) return;
@@ -261,9 +254,7 @@
}
setSuggestionsState(
- suggestionsType: SuggestionsType,
- state: SuggestionsState
- ) {
+ suggestionsType: SuggestionsType, state: SuggestionsState) {
const current = this.subject$.getValue();
const suggestions = current.suggestionsByTypes.get(suggestionsType);
if (!suggestions) return;
@@ -272,9 +263,7 @@
}
setSuggestionsLoadProgress(
- suggestionsType: SuggestionsType,
- loadProgress: string
- ) {
+ suggestionsType: SuggestionsType, loadProgress: string) {
const current = this.subject$.getValue();
const suggestions = current.suggestionsByTypes.get(suggestionsType);
if (!suggestions) return;
@@ -300,16 +289,14 @@
}
_arePluginStatusesEqual(
- status1: PluginStatus | undefined,
- status2: PluginStatus | undefined
- ) {
+ status1: PluginStatus|undefined, status2: PluginStatus|undefined) {
if (status1 === undefined || status2 === undefined) {
return status1 === status2;
}
if (status1.state !== status2.state) return false;
- return isPluginErrorState(status1.state)
- ? status1.failedMessage === status2.failedMessage
- : true;
+ return isPluginErrorState(status1.state) ?
+ status1.failedMessage === status2.failedMessage :
+ true;
}
static getModel(change: ChangeInfo) {
diff --git a/web/code-owners-service.ts b/web/code-owners-service.ts
index 2bf9cd1..a7206f0 100644
--- a/web/code-owners-service.ts
+++ b/web/code-owners-service.ts
@@ -56,6 +56,8 @@
maxConcurrentRequests?: number;
}
+function noAwait(_promise: Promise<unknown>) {}
+
/**
* Service for the data layer used in the plugin UI.
*/
@@ -169,7 +171,7 @@
// new status - it is expected, that after several retry a status
// for the newest patchset is returned
this.reset();
- this.prefetch();
+ noAwait(this.prefetch());
return await this.getStatus();
}
return status;
@@ -181,7 +183,7 @@
return {
patchsetNumber: 0,
enabled: false,
- codeOwnerStatusMap: new Map(),
+ codeOwnerStatusMap: new Map<string, FileStatus>(),
rawStatuses: [],
newerPatchsetUploaded: false,
};
@@ -281,7 +283,7 @@
});
}
return prev;
- }, new Map());
+ }, new Map<string, FileStatus>());
}
private computeFileStatus(
diff --git a/web/suggest-owners-util.ts b/web/suggest-owners-util.ts
index ca494d6..3a32d8e 100644
--- a/web/suggest-owners-util.ts
+++ b/web/suggest-owners-util.ts
@@ -20,10 +20,7 @@
import {BestSuggestionsLimit} from './code-owners-model';
export interface GroupedFiles {
- groupName: {
- name: string | undefined;
- prefix: string;
- };
+ groupName: {name: string|undefined; prefix: string;};
files: Array<FetchedFile>;
owners?: CodeOwnersInfo;
error?: Error;
@@ -42,35 +39,28 @@
* "fake" groups a user can see inconsistent state in dialog.
*/
export function getDisplayOwnersGroups(
- files: Array<FetchedFile>,
- allOwnersByPathMap: Map<string, CodeOwnersInfo | undefined>,
- reviewersIdSet: Set<AccountId | GroupId>,
- allowAllOwnersSubstition: boolean
-): Array<GroupedFiles> {
- const getDisplayOwnersFunc =
- !allowAllOwnersSubstition ||
- allOwnersByPathMap.size === 0 ||
- reviewersIdSet.size === 0
- ? (file: FetchedFile) => file.info.owners
- : (file: FetchedFile) =>
+ files: Array<FetchedFile>,
+ allOwnersByPathMap: Map<string, CodeOwnersInfo|undefined>,
+ reviewersIdSet: Set<AccountId|GroupId>,
+ allowAllOwnersSubstition: boolean): Array<GroupedFiles> {
+ const getDisplayOwnersFunc = !allowAllOwnersSubstition ||
+ allOwnersByPathMap.size === 0 || reviewersIdSet.size === 0 ?
+ (file: FetchedFile) => file.info.owners :
+ (file: FetchedFile) =>
getDisplayOwners(file, allOwnersByPathMap, reviewersIdSet);
return groupFilesByOwners(files, getDisplayOwnersFunc);
}
function getDisplayOwners(
- file: FetchedFile,
- allOwnersByPathMap: Map<String, CodeOwnersInfo | undefined>,
- reviewersIdSet: Set<AccountId | GroupId>
-) {
+ file: FetchedFile,
+ allOwnersByPathMap: Map<String, CodeOwnersInfo|undefined>,
+ reviewersIdSet: Set<AccountId|GroupId>) {
const ownerSelected = (owner: CodeOwnerInfo) =>
- owner?.account?._account_id !== undefined &&
- reviewersIdSet.has(owner.account._account_id);
+ owner?.account?._account_id !== undefined &&
+ reviewersIdSet.has(owner.account._account_id);
const defaultOwners = file.info.owners;
- if (
- !defaultOwners ||
- defaultOwners.owned_by_all_users ||
- defaultOwners.code_owners.some(ownerSelected)
- ) {
+ if (!defaultOwners || defaultOwners.owned_by_all_users ||
+ defaultOwners.code_owners.some(ownerSelected)) {
return defaultOwners;
}
const allOwners = allOwnersByPathMap.get(file.path);
@@ -84,13 +74,14 @@
}
function groupFilesByOwners(
- files: Array<FetchedFile>,
- getDisplayOwnersFunc: (file: FetchedFile) => CodeOwnersInfo | undefined
-): Array<GroupedFiles> {
+ files: Array<FetchedFile>,
+ getDisplayOwnersFunc: (file: FetchedFile) =>
+ CodeOwnersInfo | undefined): Array<GroupedFiles> {
// Note: for renamed or moved files, they will have two entries in the map
// we will treat them as two entries when group as well
- const ownersFilesMap = new Map();
- const failedToFetchFiles: Set<FetchedFile> = new Set();
+ const ownersFilesMap =
+ new Map<string, {files: Array<FetchedFile>, owners: CodeOwnersInfo}>();
+ const failedToFetchFiles = new Set<FetchedFile>();
for (const file of files) {
// for files failed to fetch, add them to the special group
if (file.info.error) {
@@ -107,18 +98,17 @@
const ownersKey = getOwnersGroupKey(displayOwners);
ownersFilesMap.set(
- ownersKey,
- ownersFilesMap.get(ownersKey) || {files: [], owners: displayOwners}
- );
- ownersFilesMap.get(ownersKey).files.push(file);
+ ownersKey,
+ ownersFilesMap.get(ownersKey) ?? {files: [], owners: displayOwners});
+ ownersFilesMap.get(ownersKey)!.files.push(file);
}
const groupedItems = [];
for (const ownersKey of ownersFilesMap.keys()) {
- const groupName = getGroupName(ownersFilesMap.get(ownersKey).files);
+ const groupName = getGroupName(ownersFilesMap.get(ownersKey)!.files);
groupedItems.push({
groupName,
- files: ownersFilesMap.get(ownersKey).files,
- owners: ownersFilesMap.get(ownersKey).owners,
+ files: ownersFilesMap.get(ownersKey)!.files,
+ owners: ownersFilesMap.get(ownersKey)!.owners,
});
}
@@ -128,8 +118,7 @@
groupName: getGroupName(failedFiles),
files: failedFiles,
error: new Error(
- 'Failed to fetch code owner info. Try to refresh the page.'
- ),
+ 'Failed to fetch code owner info. Try to refresh the page.'),
});
}
return groupedItems;
@@ -140,10 +129,7 @@
return '__owned_by_all_users__';
}
const code_owners = owners.code_owners;
- return code_owners
- .map(owner => owner.account?._account_id)
- .sort()
- .join(',');
+ return code_owners.map(owner => owner.account?._account_id).sort().join(',');
}
function getGroupName(files: Array<FetchedFile>) {