Skip to content

Commit

Permalink
TLC statistics sharing config synchronization, #114
Browse files Browse the repository at this point in the history
  • Loading branch information
alygin committed Dec 1, 2019
1 parent b00b04c commit 2f10148
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 40 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -267,9 +267,9 @@
},
"tlaplus.tlc.statisticsSharing": {
"type": "string",
"scope": "application",
"scope": "machine",
"default": "doNotShare",
"markdownDescription": "Allows you to send the TLC usage statistics to [the plublicly available database](https://exec-stats.tlapl.us). You can find more details on what is shared [here](https://github.com/alygin/vscode-tlaplus/wiki/TLC-Statistics-Sharing).",
"markdownDescription": "Allows you to send the TLC usage statistics to [the publicly available database](https://exec-stats.tlapl.us). You can find more details on what is shared [here](https://github.com/tlaplus/tlaplus/blob/master/tlatools/src/util/ExecutionStatisticsCollector.md).",
"enum": [
"share",
"shareWithoutId",
Expand Down
2 changes: 0 additions & 2 deletions src/commands/checkModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import { saveStreamToFile } from '../outputSaver';
import { replaceExtension, LANG_TLAPLUS, LANG_TLAPLUS_CFG, listFiles, exists } from '../common';
import { ModelCheckResultSource, ModelCheckResult } from '../model/check';
import { ToolOutputChannel } from '../outputChannels';
import { processTlcStatisticsSetting } from './tlcStatisticsCfg';

export const CMD_CHECK_MODEL_RUN = 'tlaplus.model.check.run';
export const CMD_CHECK_MODEL_CUSTOM_RUN = 'tlaplus.model.check.customRun';
Expand Down Expand Up @@ -54,7 +53,6 @@ export async function checkModel(diagnostic: vscode.DiagnosticCollection, extCon
if (!specFiles) {
return;
}
await processTlcStatisticsSetting();
doCheckModel(specFiles, false, extContext, diagnostic);
}

Expand Down
91 changes: 55 additions & 36 deletions src/commands/tlcStatisticsCfg.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,61 +6,80 @@ import { exists, readFile, writeFile, mkDir } from '../common';
const CFG_TLC_STATISTICS_TYPE = 'tlaplus.tlc.statisticsSharing';
const STAT_SETTINGS_DIR = '.tlaplus';
const STAT_SETTINGS_FILE = 'esc.txt';
const STAT_OPT_SHARE = '*';
const STAT_OPT_SHARE_NO_ID = 'RANDOM_IDENTIFIER';
const STAT_OPT_DO_NOT_SHARE = 'NO_STATISTICS';

let lastStatCfgValue: string | undefined;
enum ShareOption {
Share = 'share',
ShareWithoutId = 'shareWithoutId',
DoNotShare = 'doNotShare'
}

/**
* Writes TLC statistics sharing cfg file when the corresponding configuration setting is changed.
*/
export function listenTlcStatConfigurationChanges(disposables: vscode.Disposable[]) {
vscode.workspace.onDidChangeConfiguration((event) => {
if (event.affectsConfiguration(CFG_TLC_STATISTICS_TYPE)) {
const cfgOption = vscode.workspace.getConfiguration().get<ShareOption>(CFG_TLC_STATISTICS_TYPE);
if (cfgOption) {
writeFileOption(cfgOption);
}
}
}, undefined, disposables);
}

/**
* Checks the TLC statistics collection setting, rewrites the statistics config file if necessary.
* The statistics config file contains one of the following:
* - {installation ID} - when the user allows to share statistics along with the installation ID.
* - NO_STATISTICS - when the user doesn't want to share statistics.
* - RANDOM_IDENTIFIER - when the user allows to share statistics but without the installation ID.
* TLC handles this file automatically when running.
* Updates the TLC statistics sharing setting in accordance with the config file if necessary.
*/
export async function processTlcStatisticsSetting() {
const statCfg = vscode.workspace.getConfiguration().get<string>(CFG_TLC_STATISTICS_TYPE);
if (statCfg === lastStatCfgValue) {
export async function syncTlcStatisticsSetting() {
const cfgOption = vscode.workspace.getConfiguration().get<string>(CFG_TLC_STATISTICS_TYPE);
const fileOption = await readFileOption();
if (cfgOption === fileOption) {
return;
}
lastStatCfgValue = statCfg;
switch (statCfg) {
case 'share':
setStatisticsSetting(STAT_OPT_SHARE);
const target = vscode.ConfigurationTarget.Global;
return vscode.workspace.getConfiguration().update(CFG_TLC_STATISTICS_TYPE, fileOption, target);
}

async function readFileOption(): Promise<ShareOption> {
const file = path.join(homedir(), STAT_SETTINGS_DIR, STAT_SETTINGS_FILE);
if (!await exists(file)) {
return ShareOption.DoNotShare;
}
const fileContents = await readFile(file);
if (fileContents.startsWith(STAT_OPT_DO_NOT_SHARE)) {
return ShareOption.DoNotShare;
} else if (fileContents.startsWith(STAT_OPT_SHARE_NO_ID)) {
return ShareOption.ShareWithoutId;
} else if (fileContents.length > 0) {
return ShareOption.Share;
}
return ShareOption.DoNotShare;
}

async function writeFileOption(option: ShareOption) {
let contents;
switch (option) {
case ShareOption.Share:
contents = generateRandomInstallationId();
break;
case 'shareWithoutId':
setStatisticsSetting(STAT_OPT_SHARE_NO_ID);
case ShareOption.ShareWithoutId:
contents = STAT_OPT_SHARE_NO_ID;
break;
case 'doNotShare':
setStatisticsSetting(STAT_OPT_DO_NOT_SHARE);
case ShareOption.DoNotShare:
contents = STAT_OPT_DO_NOT_SHARE;
break;
default:
console.error('Unsupported TLC statistics option: ' + statCfg);
console.error('Unsupported TLC statistics option: ' + option);
return;
}
}

async function setStatisticsSetting(option: string) {
const dir = path.join(homedir(), STAT_SETTINGS_DIR);
const file = path.join(dir, STAT_SETTINGS_FILE);
if (await exists(file)) {
const curOption = await readFile(file);
if ((option === STAT_OPT_DO_NOT_SHARE || option === STAT_OPT_SHARE_NO_ID) && curOption.startsWith(option)) {
return;
}
if (option === STAT_OPT_SHARE
&& !curOption.startsWith(STAT_OPT_DO_NOT_SHARE)
&& !curOption.startsWith(STAT_OPT_SHARE_NO_ID)) {
return;
}
}
const fileContents = option === STAT_OPT_SHARE ? generateRandomInstallationId() : option;
if (!await exists(dir)) {
await mkDir(dir);
}
await writeFile(file, fileContents + '\n');
return writeFile(file, contents + '\n');
}

function generateRandomInstallationId(): string {
Expand Down
4 changes: 4 additions & 0 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { TlaCompletionItemProvider } from './completions/tlaCompletions';
import { CfgCompletionItemProvider } from './completions/cfgCompletions';
import { TlaDeclarationsProvider } from './declarations/tlaDeclarations';
import { TlaDocumentInfos } from './model/documentInfo';
import { syncTlcStatisticsSetting, listenTlcStatConfigurationChanges } from './commands/tlcStatisticsCfg';

const TLAPLUS_FILE_SELECTOR: vscode.DocumentSelector = { scheme: 'file', language: LANG_TLAPLUS };
const TLAPLUS_CFG_FILE_SELECTOR: vscode.DocumentSelector = { scheme: 'file', language: LANG_TLAPLUS_CFG };
Expand Down Expand Up @@ -94,6 +95,9 @@ export function activate(context: vscode.ExtensionContext) {
new TlaDeclarationsProvider(tlaDocInfos)
)
);
syncTlcStatisticsSetting()
.catch((err) => console.error(err))
.then(() => listenTlcStatConfigurationChanges(context.subscriptions));
showChangeLog(context.extensionPath)
.catch((err) => console.error(err));
}
Expand Down

0 comments on commit 2f10148

Please sign in to comment.