Merge "Update Bazel version to 7.6.1"
diff --git a/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions.ts b/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions.ts
index 0393242..46da136 100644
--- a/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions.ts
+++ b/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions.ts
@@ -1375,26 +1375,18 @@
}
async showRevertDialog() {
- const change = this.change;
- if (!change) return;
- const query = `submissionid: "${change.submission_id}"`;
- /* A chromium plugin expects that the modifyRevertMsg hook will only
- be called after the revert button is pressed, hence we populate the
- revert dialog after revert button is pressed. */
- const [changes, validationOptions] = await Promise.all([
- this.restApiService.getChanges(0, query),
- this.restApiService.getValidationOptions(this.change!._number),
- ]);
- if (!changes) {
+ if (!this.change) return;
+ assertIsDefined(this.confirmRevertDialog, 'confirmRevertDialog');
+ if (
+ !(await this.confirmRevertDialog.populate(
+ this.change,
+ this.commitMessage
+ ))
+ ) {
+ // This indicates error in REST response that will show error dialog, no
+ // need to open revert dialog.
return;
}
- assertIsDefined(this.confirmRevertDialog, 'confirmRevertDialog');
- this.confirmRevertDialog.populate(
- change,
- validationOptions,
- this.commitMessage,
- changes.length
- );
this.showActionDialog(this.confirmRevertDialog);
}
diff --git a/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions_test.ts b/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions_test.ts
index ed4c9c5..7131586 100644
--- a/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions_test.ts
+++ b/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions_test.ts
@@ -55,10 +55,7 @@
import {GrConfirmRebaseDialog} from '../gr-confirm-rebase-dialog/gr-confirm-rebase-dialog';
import {GrConfirmMoveDialog} from '../gr-confirm-move-dialog/gr-confirm-move-dialog';
import {GrConfirmAbandonDialog} from '../gr-confirm-abandon-dialog/gr-confirm-abandon-dialog';
-import {
- GrConfirmRevertDialog,
- RevertType,
-} from '../gr-confirm-revert-dialog/gr-confirm-revert-dialog';
+import {GrConfirmRevertDialog} from '../gr-confirm-revert-dialog/gr-confirm-revert-dialog';
import {testResolver} from '../../../test/common-test-setup';
import {storageServiceToken} from '../../../services/storage/gr-storage_impl';
import {pluginLoaderToken} from '../../shared/gr-js-api-interface/gr-plugin-loader';
@@ -66,7 +63,6 @@
ChangeModel,
changeModelToken,
} from '../../../models/change/change-model';
-import {assertIsDefined} from '../../../utils/common-util';
import {GrAutogrowTextarea} from '../../shared/gr-autogrow-textarea/gr-autogrow-textarea';
// TODO(dhruvsri): remove use of _populateRevertMessage as it's private
@@ -2619,45 +2615,6 @@
});
});
- test('sends validation options when opening revert dialog', async () => {
- sinon.stub(element, 'handleAction');
- const fireActionStub = sinon.stub(element, 'fireAction');
- element.actions = {
- revert: {
- method: HttpMethod.POST,
- label: 'Revert',
- title: 'Revert the change',
- enabled: true,
- },
- };
- const confirmRevertDialog = query<GrConfirmRevertDialog>(
- element,
- '#confirmRevertDialog'
- );
- assertIsDefined(confirmRevertDialog, 'confirmDialog');
- const populateRevertDialogStub = sinon.stub(
- confirmRevertDialog,
- 'populate'
- );
- await element.showRevertDialog();
- await waitUntil(() => !!populateRevertDialogStub.called);
- assert.deepEqual(populateRevertDialogStub.lastCall.args[1], {
- validation_options: [{name: 'o1', description: 'option 1'}],
- });
-
- element.handleRevertDialogConfirm(
- new CustomEvent('confirm', {
- detail: {
- revertType: RevertType.REVERT_SINGLE_CHANGE,
- message: 'revert this change',
- },
- })
- );
- await waitUntil(() => !!fireActionStub.called);
-
- assert.deepEqual(fireActionStub.lastCall.args[0], '/revert');
- });
-
suite('multiple changes revert', () => {
let showActionDialogStub: sinon.SinonStub;
let setUrlStub: sinon.SinonStub;
diff --git a/polygerrit-ui/app/elements/change/gr-change-autocomplete/gr-change-autocomplete.ts b/polygerrit-ui/app/elements/change/gr-change-autocomplete/gr-change-autocomplete.ts
index fb20cf3..5c1ca29 100644
--- a/polygerrit-ui/app/elements/change/gr-change-autocomplete/gr-change-autocomplete.ts
+++ b/polygerrit-ui/app/elements/change/gr-change-autocomplete/gr-change-autocomplete.ts
@@ -79,7 +79,7 @@
/* changeNumber=*/ 450,
'is:open -age:90d',
/* offset=*/ undefined,
- /* options=*/ undefined,
+ /* options=*/ '0',
throwingErrorCallback
);
if (!res) {
diff --git a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.ts b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.ts
index 0409f80..20bfeec 100644
--- a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.ts
+++ b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.ts
@@ -727,7 +727,7 @@
change.labels = {};
element.change = change;
- changeModel.setState({
+ changeModel.updateState({
loadingStatus: LoadingStatus.LOADED,
change,
});
@@ -1424,7 +1424,7 @@
changeNum: TEST_NUMERIC_CHANGE_ID,
repo: TEST_PROJECT_NAME,
};
- changeModel.setState({
+ changeModel.updateState({
loadingStatus: LoadingStatus.LOADED,
change: {
...createChangeViewChange(),
diff --git a/polygerrit-ui/app/elements/change/gr-confirm-rebase-dialog/gr-confirm-rebase-dialog_test.ts b/polygerrit-ui/app/elements/change/gr-confirm-rebase-dialog/gr-confirm-rebase-dialog_test.ts
index 30cf475..eac869d 100644
--- a/polygerrit-ui/app/elements/change/gr-confirm-rebase-dialog/gr-confirm-rebase-dialog_test.ts
+++ b/polygerrit-ui/app/elements/change/gr-confirm-rebase-dialog/gr-confirm-rebase-dialog_test.ts
@@ -131,7 +131,7 @@
element.branch = 'test' as BranchName;
await element.updateComplete;
changeModel = testResolver(changeModelToken);
- changeModel.setState({
+ changeModel.updateState({
loadingStatus: LoadingStatus.LOADED,
change,
});
diff --git a/polygerrit-ui/app/elements/change/gr-confirm-revert-dialog/gr-confirm-revert-dialog.ts b/polygerrit-ui/app/elements/change/gr-confirm-revert-dialog/gr-confirm-revert-dialog.ts
index 52ae1c2..26aefd5 100644
--- a/polygerrit-ui/app/elements/change/gr-confirm-revert-dialog/gr-confirm-revert-dialog.ts
+++ b/polygerrit-ui/app/elements/change/gr-confirm-revert-dialog/gr-confirm-revert-dialog.ts
@@ -26,6 +26,7 @@
import {GrAutogrowTextarea} from '../../shared/gr-autogrow-textarea/gr-autogrow-textarea';
import '@material/web/radio/radio';
import {materialStyles} from '../../../styles/gr-material-styles';
+import {getAppContext} from '../../../services/app-context';
const ERR_COMMIT_NOT_FOUND = 'Unable to find the commit hash of this change.';
const SPECIFY_REASON_STRING = '<MUST SPECIFY REASON HERE>';
@@ -83,6 +84,8 @@
private readonly getPluginLoader = resolve(this, pluginLoaderToken);
+ private readonly restApiService = getAppContext().restApiService;
+
static override get styles() {
return [
formStyles,
@@ -222,13 +225,31 @@
);
}
- populate(
+ /**
+ * Fetches required information and populates the dialog message.
+ *
+ * Returns `false` if the dialog shouldn't be shown.
+ */
+ async populate(
change: ParsedChangeInfo,
- validationOptions: ValidationOptionsInfo | undefined,
- commitMessage: string,
- changesCount: number
- ) {
- this.changesCount = changesCount;
+ commitMessage: string
+ ): Promise<boolean> {
+ const query = `submissionid: "${change.submission_id}"`;
+ /* A chromium plugin expects that the modifyRevertMsg hook will only
+ be called after the revert button is pressed, hence we populate the
+ revert dialog after revert button is pressed. */
+ const [changes, validationOptions] = await Promise.all([
+ // Specify options 0 to explicitly not request any additional information,
+ // as opposed to using default, since we only care about number of
+ // changes.
+ this.restApiService.getChanges(0, query, undefined, /* options=*/ '0'),
+ this.restApiService.getValidationOptions(change._number),
+ ]);
+ if (!changes) {
+ return false;
+ }
+
+ this.changesCount = changes.length;
this.validationOptions = validationOptions;
// The option to revert a single change is always available
this.populateRevertSingleChangeMessage(
@@ -237,6 +258,7 @@
change.current_revision
);
this.populateRevertSubmissionMessage(change, commitMessage);
+ return true;
}
populateRevertSingleChangeMessage(
diff --git a/polygerrit-ui/app/elements/change/gr-confirm-revert-dialog/gr-confirm-revert-dialog_test.ts b/polygerrit-ui/app/elements/change/gr-confirm-revert-dialog/gr-confirm-revert-dialog_test.ts
index 7077099..acdb84b 100644
--- a/polygerrit-ui/app/elements/change/gr-confirm-revert-dialog/gr-confirm-revert-dialog_test.ts
+++ b/polygerrit-ui/app/elements/change/gr-confirm-revert-dialog/gr-confirm-revert-dialog_test.ts
@@ -6,10 +6,21 @@
import * as sinon from 'sinon';
import {assert, fixture, html} from '@open-wc/testing';
import '../../../test/common-test-setup';
-import {createParsedChange} from '../../../test/test-data-generators';
-import {ChangeSubmissionId, CommitId} from '../../../types/common';
+import {
+ createChange,
+ createParsedChange,
+} from '../../../test/test-data-generators';
+import {
+ ChangeId,
+ ChangeSubmissionId,
+ CommitId,
+ TopicName,
+ ValidationOptionsInfo,
+} from '../../../types/common';
import './gr-confirm-revert-dialog';
import {GrConfirmRevertDialog} from './gr-confirm-revert-dialog';
+import {stubRestApi} from '../../../test/test-utils';
+import {ParsedChangeInfo} from '../../../types/types';
suite('gr-confirm-revert-dialog tests', () => {
let element: GrConfirmRevertDialog;
@@ -129,4 +140,44 @@
'Reverted changes: /q/submissionid:5545\n';
assert.equal(element.message, expected);
});
+
+ suite('populate tests', () => {
+ let change: ParsedChangeInfo;
+
+ setup(async () => {
+ change = {
+ ...createParsedChange(),
+ submission_id: '5545' as ChangeSubmissionId,
+ current_revision: 'abcd123' as CommitId,
+ };
+ stubRestApi('getChanges').returns(
+ Promise.resolve([
+ {
+ ...createChange(),
+ change_id: '12345678901234' as ChangeId,
+ topic: 'T' as TopicName,
+ subject: 'random',
+ },
+ {
+ ...createChange(),
+ change_id: '23456' as ChangeId,
+ topic: 'T' as TopicName,
+ subject: 'a'.repeat(100),
+ },
+ ])
+ );
+ stubRestApi('getValidationOptions').returns(
+ Promise.resolve({
+ validation_options: [{name: 'o1', description: 'option 1'}],
+ } as ValidationOptionsInfo)
+ );
+ });
+
+ test('validation options are fetched when populating revert dialog', async () => {
+ await element.populate(change, 'commit message');
+ assert.deepEqual(element.validationOptions, {
+ validation_options: [{name: 'o1', description: 'option 1'}],
+ });
+ });
+ });
});
diff --git a/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.ts b/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.ts
index 04c8618..88e029a 100644
--- a/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.ts
+++ b/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.ts
@@ -1615,6 +1615,10 @@
);
if (reloadRequired) {
fireReload(this);
+ } else {
+ // Only reload submittability if the full reload is not triggered, to
+ // avoid duplicate requests.
+ this.getChangeModel().reloadSubmittability();
}
this.patchsetLevelDraftMessage = '';
diff --git a/polygerrit-ui/app/elements/change/gr-submit-requirements/gr-submit-requirements.ts b/polygerrit-ui/app/elements/change/gr-submit-requirements/gr-submit-requirements.ts
index 377a649..5972b41 100644
--- a/polygerrit-ui/app/elements/change/gr-submit-requirements/gr-submit-requirements.ts
+++ b/polygerrit-ui/app/elements/change/gr-submit-requirements/gr-submit-requirements.ts
@@ -13,7 +13,7 @@
import '../../checks/gr-checks-chip-for-label';
import {css, html, LitElement, nothing, TemplateResult} from 'lit';
import {customElement, property, state} from 'lit/decorators.js';
-import {ParsedChangeInfo} from '../../../types/types';
+import {LoadingStatus, ParsedChangeInfo} from '../../../types/types';
import {repeat} from 'lit/directives/repeat.js';
import {
AccountInfo,
@@ -49,6 +49,7 @@
import {subscribe} from '../../lit/subscription-controller';
import {when} from 'lit/directives/when.js';
import {spinnerStyles} from '../../../styles/gr-spinner-styles';
+import {changeModelToken} from '../../../models/change/change-model';
/**
* @attr {Boolean} suppress-title - hide titles, currently for hovercard view
@@ -73,6 +74,9 @@
@state()
runs: CheckRun[] = [];
+ @state()
+ requirementsLoading?: boolean;
+
static override get styles() {
return [
fontStyles,
@@ -147,6 +151,8 @@
private readonly getChecksModel = resolve(this, checksModelToken);
+ private readonly getChangeModel = resolve(this, changeModelToken);
+
constructor() {
super();
subscribe(
@@ -154,6 +160,11 @@
() => this.getChecksModel().allRunsLatestPatchsetLatestAttempt$,
x => (this.runs = x)
);
+ subscribe(
+ this,
+ () => this.getChangeModel().submittabilityLoadingStatus$,
+ x => (this.requirementsLoading = x === LoadingStatus.LOADING)
+ );
}
override render() {
@@ -173,7 +184,7 @@
>
Submit Requirements
${when(
- submit_requirements.length === 0,
+ this.requirementsLoading,
() =>
html`<span
class="loadingSpin"
diff --git a/polygerrit-ui/app/elements/change/gr-submit-requirements/gr-submit-requirements_test.ts b/polygerrit-ui/app/elements/change/gr-submit-requirements/gr-submit-requirements_test.ts
index aee2017..8f55c29 100644
--- a/polygerrit-ui/app/elements/change/gr-submit-requirements/gr-submit-requirements_test.ts
+++ b/polygerrit-ui/app/elements/change/gr-submit-requirements/gr-submit-requirements_test.ts
@@ -72,6 +72,7 @@
submittable: false,
},
loadingStatus: LoadingStatus.LOADED,
+ submittabilityLoadingStatus: LoadingStatus.LOADED,
});
element = await fixture<GrSubmitRequirements>(
html`<gr-submit-requirements
@@ -138,6 +139,32 @@
);
});
+ test('renders loading', async () => {
+ element.requirementsLoading = true;
+ element.change = {
+ ...element.change,
+ submit_requirements: undefined,
+ } as ParsedChangeInfo;
+ await element.updateComplete;
+ assert.shadowDom.equal(
+ element,
+ /* HTML */ `
+ <h3 class="heading-3 metadata-title" id="submit-requirements-caption">
+ Submit Requirements
+ <span
+ class="loadingSpin"
+ title="Submit Requirements status is being updated"
+ >
+ </span>
+ </h3>
+ <h3 class="heading-3 metadata-title">Label Votes</h3>
+ <section class="trigger-votes">
+ <gr-trigger-vote> </gr-trigger-vote>
+ </section>
+ `
+ );
+ });
+
suite('votes-cell', () => {
setup(async () => {
element.disableEndpoints = true;
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view_test.ts b/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view_test.ts
index 4881f49..ca12afd 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view_test.ts
+++ b/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view_test.ts
@@ -1380,7 +1380,7 @@
};
userModel.setDiffPreferences(diffPreferences);
viewModel.updateState({diffView: {path: 'wheatley.md'}});
- changeModel.setState({
+ changeModel.updateState({
change: createParsedChange(),
reviewedFiles: [],
loadingStatus: LoadingStatus.LOADED,
@@ -1412,7 +1412,7 @@
};
userModel.setDiffPreferences(diffPreferences);
viewModel.updateState({diffView: {path: 'wheatley.md'}});
- changeModel.setState({
+ changeModel.updateState({
change: createParsedChange(),
reviewedFiles: [],
loadingStatus: LoadingStatus.LOADED,
@@ -1433,7 +1433,7 @@
basePatchNum: PARENT,
diffView: {path: '/COMMIT_MSG'},
});
- changeModel.setState({
+ changeModel.updateState({
change: createParsedChange(),
reviewedFiles: [],
loadingStatus: LoadingStatus.LOADED,
diff --git a/polygerrit-ui/app/elements/shared/gr-formatted-text/gr-formatted-text.ts b/polygerrit-ui/app/elements/shared/gr-formatted-text/gr-formatted-text.ts
index 2bf84fe..0a14ef7 100644
--- a/polygerrit-ui/app/elements/shared/gr-formatted-text/gr-formatted-text.ts
+++ b/polygerrit-ui/app/elements/shared/gr-formatted-text/gr-formatted-text.ts
@@ -170,11 +170,12 @@
// [/?#] // Start with one of / ? #
// [^\s'"]* // Followed by some chars that are not whitespace,
// // ' or " (to not grab trailing quotes)
+ // (?<![.,]) // and not ending with '.' or ','
// ) // End path/query/fragment group
// ) // End capture group 1
// (?=\s|$|[)'"!?.,]) // Ensure the match is followed by whitespace,
// // end of line, or one of ) ' " ! ? . ,
- match: `(?<=\\s|^|[('":[])((?:[\\w-]+\\.)+(?:${TLD_REGEX})(?=.*?/)(?:[/?#][^\\s'"]*))(?=\\s|$|[)'"!?.,])`,
+ match: `(?<=\\s|^|[('":[])((?:[\\w-]+\\.)+(?:${TLD_REGEX})(?=.*?/)(?:[/?#][^\\s'"]*(?<![.,])))(?=\\s|$|[)'"!?.,])`,
// Prepend http:// for the link href otherwise it will be treated as
// a relative URL.
link: 'http://$1',
diff --git a/polygerrit-ui/app/elements/shared/gr-formatted-text/gr-formatted-text_test.ts b/polygerrit-ui/app/elements/shared/gr-formatted-text/gr-formatted-text_test.ts
index 113a6cd..2085cc7 100644
--- a/polygerrit-ui/app/elements/shared/gr-formatted-text/gr-formatted-text_test.ts
+++ b/polygerrit-ui/app/elements/shared/gr-formatted-text/gr-formatted-text_test.ts
@@ -264,6 +264,15 @@
}
};
+ const getLinkifiedUrl = async (url: string) => {
+ element.content = url;
+ await element.updateComplete;
+ const a = query<HTMLElement>(element, 'a');
+
+ assert.isDefined<HTMLElement | undefined>(a);
+ return a.innerText;
+ };
+
await checkLinking('http://www.google.com');
await checkLinking('https://www.google.com');
await checkLinking('https://www.google.com/');
@@ -271,6 +280,10 @@
await checkLinking('https://www.google.com/asdf-');
await checkLinking('https://www.google.com/asdf-');
await checkLinking('https://www.google.com/asdf)');
+ assert.equal(
+ await getLinkifiedUrl('hello gerrit.com/asdf,'),
+ 'gerrit.com/asdf'
+ );
// matches & part as well, even we first linkify and then htmlEscape
await checkLinking(
'https://google.com/traces/list?project=gerrit&tid=123'
diff --git a/polygerrit-ui/app/models/change/change-model.ts b/polygerrit-ui/app/models/change/change-model.ts
index a71d225..db2fda3 100644
--- a/polygerrit-ui/app/models/change/change-model.ts
+++ b/polygerrit-ui/app/models/change/change-model.ts
@@ -102,6 +102,7 @@
* Corresponding values in `change` are always kept in sync.
*/
submittabilityInfo?: SubmittabilityInfo;
+ submittabilityLoadingStatus: LoadingStatus;
/**
* The list of reviewed files, kept in the model because we want changes made
* in one view to reflect on other views without re-rendering the other views.
@@ -338,6 +339,7 @@
// Use DeepReadOnly?
const initialState: ChangeState = {
loadingStatus: LoadingStatus.NOT_LOADED,
+ submittabilityLoadingStatus: LoadingStatus.NOT_LOADED,
};
export const changeModelToken = define<ChangeModel>('change-model');
@@ -373,6 +375,11 @@
changeState => changeState.submittabilityInfo
);
+ public readonly submittabilityLoadingStatus$ = select(
+ this.state$,
+ changeState => changeState.submittabilityLoadingStatus
+ );
+
public readonly submittable$ = select(
this.state$,
changeState => changeState.submittabilityInfo?.submittable
@@ -827,8 +834,14 @@
if (!changeNum) {
// On change reload changeNum is set to undefined to reset change
// state. We propagate undefined and reset the state in this case.
+ this.updateState({
+ submittabilityLoadingStatus: LoadingStatus.NOT_LOADED,
+ });
return of(undefined);
}
+ this.updateState({
+ submittabilityLoadingStatus: LoadingStatus.LOADING,
+ });
return from(this.restApiService.getSubmittabilityInfo(changeNum));
})
)
@@ -840,6 +853,9 @@
KnownExperimentId.ASYNC_SUBMIT_REQUIREMENTS
)
) {
+ this.updateState({
+ submittabilityLoadingStatus: LoadingStatus.NOT_LOADED,
+ });
return;
}
const change = fillFromSubmittabilityInfo(
@@ -849,6 +865,9 @@
this.updateState({
change,
submittabilityInfo,
+ submittabilityLoadingStatus: submittabilityInfo
+ ? LoadingStatus.LOADED
+ : LoadingStatus.NOT_LOADED,
});
});
}
diff --git a/polygerrit-ui/app/services/gr-rest-api/gr-rest-api-impl.ts b/polygerrit-ui/app/services/gr-rest-api/gr-rest-api-impl.ts
index 553000b..aae54ad 100644
--- a/polygerrit-ui/app/services/gr-rest-api/gr-rest-api-impl.ts
+++ b/polygerrit-ui/app/services/gr-rest-api/gr-rest-api-impl.ts
@@ -2383,10 +2383,12 @@
'DETAILED_ACCOUNTS',
'MESSAGES',
'REVIEWER_UPDATES',
- 'SUBMITTABLE',
'SKIP_DIFFSTAT',
- 'SUBMIT_REQUIREMENTS',
];
+ if (!this.flags.isEnabled(KnownExperimentId.ASYNC_SUBMIT_REQUIREMENTS)) {
+ options.push('SUBMITTABLE');
+ options.push('SUBMIT_REQUIREMENTS');
+ }
return options;
}
diff --git a/tools/nongoogle.bzl b/tools/nongoogle.bzl
index 11125d7..4fdc091 100644
--- a/tools/nongoogle.bzl
+++ b/tools/nongoogle.bzl
@@ -186,8 +186,8 @@
maven_jar(
name = "commons-io",
- artifact = "commons-io:commons-io:2.18.0",
- sha1 = "44084ef756763795b31c578403dd028ff4a22950",
+ artifact = "commons-io:commons-io:2.20.0",
+ sha1 = "36f3474daec2849c149e877614e7f979b2082cd2",
)
# Google internal dependencies: these are developed at Google, so there is