Skip to content
This repository has been archived by the owner on Nov 18, 2022. It is now read-only.

Commit

Permalink
Wholly use vscode.Memento API to store installed RA release tag
Browse files Browse the repository at this point in the history
  • Loading branch information
Xanewok committed Aug 18, 2020
1 parent 1575d11 commit 71893c2
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 92 deletions.
79 changes: 6 additions & 73 deletions src/rust-analyzer/persistent_state.ts
Original file line number Diff line number Diff line change
@@ -1,75 +1,8 @@
import * as fs from 'fs';
import * as path from 'path';
import { promisify } from 'util';
import * as vscode from 'vscode';

const stat = promisify(fs.stat);
const mkdir = promisify(fs.mkdir);
const readFile = promisify(fs.readFile);
const writeFile = promisify(fs.writeFile);

/** Returns a path where persistent data for rust-analyzer should be installed. */
function metadataDir(): string | undefined {
if (process.platform === 'linux' || process.platform === 'darwin') {
// Prefer, in this order:
// 1. $XDG_CONFIG_HOME/rust-analyzer
// 2. $HOME/.config/rust-analyzer
const { HOME, XDG_CONFIG_HOME } = process.env;
const baseDir = XDG_CONFIG_HOME || (HOME && path.join(HOME, '.config'));

return baseDir && path.resolve(path.join(baseDir, 'rust-analyzer'));
} else if (process.platform === 'win32') {
// %LocalAppData%\rust-analyzer\
const { LocalAppData } = process.env;
return (
LocalAppData && path.resolve(path.join(LocalAppData, 'rust-analyzer'))
);
}

return undefined;
}

export interface Metadata {
releaseTag: string;
}

export async function readMetadata(): Promise<Partial<Metadata>> {
const stateDir = metadataDir();
if (!stateDir) {
throw new Error('Not supported');
}

const filePath = path.join(stateDir, 'metadata.json');
if (!(await stat(filePath).catch(() => false))) {
throw new Error('File missing');
}

const contents = await readFile(filePath, 'utf8');
const obj = JSON.parse(contents) as unknown;
return typeof obj === 'object' ? obj || {} : {};
}

export async function writeMetadata(config: Metadata) {
const stateDir = metadataDir();
if (!stateDir) {
return false;
}

if (!(await ensureDir(stateDir))) {
return false;
}

const filePath = path.join(stateDir, 'metadata.json');
return writeFile(filePath, JSON.stringify(config)).then(() => true);
}

function ensureDir(path: string) {
return !!path && stat(path).catch(() => mkdir(path, { recursive: true }));
}

export class PersistentState {
constructor(private readonly globalState: vscode.Memento) {
const { lastCheck, releaseId, serverVersion } = this;
const { lastCheck, releaseId, releaseTag: serverVersion } = this;
console.info('PersistentState:', { lastCheck, releaseId, serverVersion });
}

Expand All @@ -95,13 +28,13 @@ export class PersistentState {
}

/**
* Version of the extension that installed the server.
* Release tag of the installed server.
* Used to check if we need to update the server.
*/
get serverVersion(): string | undefined {
return this.globalState.get('serverVersion');
get releaseTag(): string | undefined {
return this.globalState.get('releaseTag');
}
async updateServerVersion(value: string | undefined) {
await this.globalState.update('serverVersion', value);
async updateReleaseTag(value: string | undefined) {
await this.globalState.update('releaseTag', value);
}
}
32 changes: 13 additions & 19 deletions src/rust-analyzer/rustAnalyzer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,7 @@ import { WorkspaceProgress } from '../extension';
import { download, fetchRelease } from '../net';
import * as rustup from '../rustup';
import { Observable } from '../utils/observable';
import {
Metadata,
readMetadata,
writeMetadata,
PersistentState,
} from './persistent_state';
import { PersistentState } from './persistent_state';

const stat = promisify(fs.stat);
const mkdir = promisify(fs.mkdir);
Expand Down Expand Up @@ -64,8 +59,6 @@ export async function getServer(
config: RustAnalyzerConfig,
state: PersistentState,
): Promise<string | undefined> {
const { askBeforeDownload, package: pkg } = config;

let binaryName: string | undefined;
if (process.arch === 'x64' || process.arch === 'ia32') {
if (process.platform === 'linux') {
Expand Down Expand Up @@ -96,22 +89,25 @@ export async function getServer(
}
await ensureDir(dir);

const metadata: Partial<Metadata> = await readMetadata().catch(() => ({}));

const dest = path.join(dir, binaryName);
const exists = await stat(dest).catch(() => false);
if (exists && metadata.releaseTag === pkg.releaseTag) {

if (!exists) {
await state.updateReleaseTag(undefined);
} else if (state.releaseTag === config.package.releaseTag) {
return dest;
}

if (askBeforeDownload) {
if (config.askBeforeDownload) {
const userResponse = await vs.window.showInformationMessage(
`${
metadata.releaseTag && metadata.releaseTag !== pkg.releaseTag
? `You seem to have installed release \`${metadata.releaseTag}\` but requested a different one.`
state.releaseTag && state.releaseTag !== config.package.releaseTag
? `You seem to have installed release \`${state.releaseTag}\` but requested a different one.`
: ''
}
Release \`${pkg.releaseTag}\` of rust-analyzer is not installed.\n
Release \`${
config.package.releaseTag
}\` of rust-analyzer is not installed.\n
Install to ${dir}?`,
'Download',
);
Expand All @@ -123,7 +119,7 @@ export async function getServer(
const release = await fetchRelease(
'rust-analyzer',
'rust-analyzer',
pkg.releaseTag,
config.package.releaseTag,
);
const artifact = release.assets.find(asset => asset.name === binaryName);
if (!artifact) {
Expand All @@ -137,9 +133,7 @@ export async function getServer(
mode: 0o755,
});

await writeMetadata({ releaseTag: pkg.releaseTag }).catch(() => {
vs.window.showWarningMessage(`Couldn't save rust-analyzer metadata`);
});
await state.updateReleaseTag(config.package.releaseTag);

return dest;
}
Expand Down

0 comments on commit 71893c2

Please sign in to comment.