mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-28 21:05:02 +00:00
Allow to use a Github Auth token for fetching releases
This change allows to use a authorization token provided by Github in order to fetch metadata for a RA release. Using an authorization token prevents to get rate-limited in environments where lots of RA users use a shared client IP (e.g. behind a company NAT). The auth token is stored in `ExtensionContext.globalState`. As far as I could observe through testing with a local WSL2 environment that state is synced between an extension installed locally and a remote version. The change provides no explicit command to query for an auth token. However in case a download fails it will provide a retry option as well as an option to enter the auth token. This should be more discoverable for most users. Closes #3688
This commit is contained in:
parent
bcdedbb3d5
commit
b93ced6f63
3 changed files with 72 additions and 4 deletions
|
@ -173,7 +173,9 @@ async function bootstrapExtension(config: Config, state: PersistentState): Promi
|
|||
if (!shouldCheckForNewNightly) return;
|
||||
}
|
||||
|
||||
const release = await fetchRelease("nightly").catch((e) => {
|
||||
const release = await performDownloadWithRetryDialog(async () => {
|
||||
return await fetchRelease("nightly", state.githubToken);
|
||||
}, state).catch((e) => {
|
||||
log.error(e);
|
||||
if (state.releaseId === undefined) { // Show error only for the initial download
|
||||
vscode.window.showErrorMessage(`Failed to download rust-analyzer nightly ${e}`);
|
||||
|
@ -308,7 +310,10 @@ async function getServer(config: Config, state: PersistentState): Promise<string
|
|||
if (userResponse !== "Download now") return dest;
|
||||
}
|
||||
|
||||
const release = await fetchRelease(config.package.releaseTag);
|
||||
const releaseTag = config.package.releaseTag;
|
||||
const release = await performDownloadWithRetryDialog(async () => {
|
||||
return await fetchRelease(releaseTag, state.githubToken);
|
||||
}, state);
|
||||
const artifact = release.assets.find(artifact => artifact.name === `rust-analyzer-${platform}.gz`);
|
||||
assert(!!artifact, `Bad release: ${JSON.stringify(release)}`);
|
||||
|
||||
|
@ -333,3 +338,49 @@ async function getServer(config: Config, state: PersistentState): Promise<string
|
|||
await state.updateServerVersion(config.package.version);
|
||||
return dest;
|
||||
}
|
||||
|
||||
async function performDownloadWithRetryDialog<T>(downloadFunc: () => Promise<T>, state: PersistentState): Promise<T> {
|
||||
while (true) {
|
||||
try {
|
||||
return await downloadFunc();
|
||||
} catch (e) {
|
||||
let selected = await vscode.window.showErrorMessage("Failed perform download: " + e.message, {}, {
|
||||
title: "Update Github Auth Token",
|
||||
updateToken: true,
|
||||
}, {
|
||||
title: "Retry download",
|
||||
retry: true,
|
||||
}, {
|
||||
title: "Dismiss",
|
||||
});
|
||||
|
||||
if (selected?.updateToken) {
|
||||
await queryForGithubToken(state);
|
||||
continue;
|
||||
} else if (selected?.retry) {
|
||||
continue;
|
||||
}
|
||||
throw e;
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
async function queryForGithubToken(state: PersistentState): Promise<void> {
|
||||
const githubTokenOptions: vscode.InputBoxOptions = {
|
||||
value: state.githubToken,
|
||||
password: true,
|
||||
prompt: `
|
||||
This dialog allows to store a Github authorization token.
|
||||
The usage of an authorization token allows will increase the rate
|
||||
limit on the use of Github APIs and can thereby prevent getting
|
||||
throttled.
|
||||
Auth tokens can be obtained at https://github.com/settings/tokens`,
|
||||
};
|
||||
|
||||
const newToken = await vscode.window.showInputBox(githubTokenOptions);
|
||||
if (newToken) {
|
||||
log.info("Storing new github token");
|
||||
await state.updateGithubToken(newToken);
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue