Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Terraform version info #1190

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { ShowReferencesFeature } from './features/showReferences';
import { CustomSemanticTokens } from './features/semanticTokens';
import { ModuleProvidersFeature } from './features/moduleProviders';
import { ModuleCallsFeature } from './features/moduleCalls';
import { TerraformVersionFeature } from './features/terraformVersion';

const id = 'terraform';
const brand = `HashiCorp Terraform`;
Expand Down Expand Up @@ -173,6 +174,7 @@ export async function activate(context: vscode.ExtensionContext): Promise<void>
new CustomSemanticTokens(client, manifest),
new ModuleProvidersFeature(client, moduleProvidersDataProvider),
new ModuleCallsFeature(client, moduleCallsDataProvider),
new TerraformVersionFeature(client, reporter),
];
if (vscode.env.isTelemetryEnabled) {
features.push(new TelemetryFeature(client, reporter));
Expand Down
46 changes: 46 additions & 0 deletions src/features/terraformVersion.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import * as terraform from '../terraform';
import * as vscode from 'vscode';
import { ClientCapabilities, ServerCapabilities, StaticFeature } from 'vscode-languageclient';
import { ExperimentalClientCapabilities } from './types';
import TelemetryReporter from '@vscode/extension-telemetry';
import { LanguageClient } from 'vscode-languageclient/node';
import { getActiveTextEditor } from '../utils/vscode';

export const CLIENT_TERRAFORM_VERSION_CMD_ID = 'client.refreshTerraformVersion';

export class TerraformVersionFeature implements StaticFeature {
private disposables: vscode.Disposable[] = [];

constructor(private client: LanguageClient, private reporter: TelemetryReporter) {}

public fillClientCapabilities(capabilities: ClientCapabilities & ExperimentalClientCapabilities): void {
if (!capabilities['experimental']) {
capabilities['experimental'] = {};
}
capabilities['experimental']['refreshTerraformVersionCommandId'] = CLIENT_TERRAFORM_VERSION_CMD_ID;
}

public async initialize(capabilities: ServerCapabilities): Promise<void> {
if (!capabilities.experimental?.refreshTerraformVersion) {
console.log("Server doesn't support client.refreshTerraformVersion");
return;
}

await this.client.onReady();

const d = this.client.onRequest(CLIENT_TERRAFORM_VERSION_CMD_ID, async () => {
const editor = getActiveTextEditor();
if (editor === undefined) {
return;
}

terraform.getTerraformVersion(editor.document.uri, this.client, this.reporter);
});

this.disposables.push(d);
}

public dispose(): void {
this.disposables.forEach((d: vscode.Disposable) => d.dispose());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to remove the disposable after disposing it?

}
}
1 change: 1 addition & 0 deletions src/features/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ export interface ExperimentalClientCapabilities {
showReferencesCommandId?: string;
refreshModuleProvidersCommandId?: string;
refreshModuleCallsCommandId?: string;
refreshTerraformVersionCommandId?: string;
};
}
27 changes: 27 additions & 0 deletions src/status/terraform.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import * as vscode from 'vscode';

const terraformStatus = vscode.languages.createLanguageStatusItem('terraform.status', [
{ language: 'terraform' },
{ language: 'terraform-vars' },
]);
terraformStatus.name = 'Terraform';
terraformStatus.detail = 'Terraform';
terraformStatus.command = {
command: 'terraform.commands',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does this command do? Do we need to register it?

title: 'Terraform Commands',
tooltip: 'foo',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

foo?

};

export function setTerraformState(
detail: string,
busy: boolean,
severity: vscode.LanguageStatusSeverity = vscode.LanguageStatusSeverity.Information,
) {
terraformStatus.busy = busy;
terraformStatus.detail = detail;
terraformStatus.severity = severity;
}

export function setTerraformVersion(version: string) {
terraformStatus.text = version;
}
47 changes: 46 additions & 1 deletion src/terraform.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import * as tfStatus from './status/terraform';
import TelemetryReporter from '@vscode/extension-telemetry';
import * as vscode from 'vscode';
import { ExecuteCommandParams, ExecuteCommandRequest, LanguageClient } from 'vscode-languageclient/node';
import {
ExecuteCommandParams,
ExecuteCommandRequest,
LanguageClient,
WorkDoneProgress,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
WorkDoneProgress,

} from 'vscode-languageclient/node';
import { Utils } from 'vscode-uri';
import { getActiveTextEditor } from './utils/vscode';
import { clientSupportsCommand } from './utils/clientHelpers';
Expand All @@ -10,6 +16,12 @@ export interface ModuleCaller {
uri: string;
}

export interface TerraformInfoResponse {
v: number;
required_version: string;
discovered_version: string;
}

export interface ModuleCallersResponse {
v: number;
callers: ModuleCaller[];
Expand Down Expand Up @@ -44,6 +56,39 @@ interface ModuleProvidersResponse {
}
/* eslint-enable @typescript-eslint/naming-convention */

export async function getTerraformVersion(
moduleUri: vscode.Uri,
client: LanguageClient,
reporter: TelemetryReporter,
): Promise<void> {
try {
const moduleDir = Utils.dirname(moduleUri);

const response = await terraformVersion(moduleDir.toString(), client, reporter);
tfStatus.setTerraformVersion(response.discovered_version);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if this is the place where I would expect the modification of the status bar item. Most of the other functions in this file make an API call and return the result.

Maybe this line belongs in the TerraformVersionFeature?

} catch (error) {
let message = 'Error requesting terraform version from terraform-ls';
if (error instanceof Error) {
message = error.message;
} else if (typeof error === 'string') {
message = error;
}

vscode.window.showErrorMessage(message);
}
}
export async function terraformVersion(
moduleUri: string,
client: LanguageClient,
reporter: TelemetryReporter,
): Promise<TerraformInfoResponse> {
const command = 'terraform-ls.module.terraform';

const response = await execWorkspaceLSCommand<TerraformInfoResponse>(command, moduleUri, client, reporter);

return response;
}

export async function moduleCallers(
moduleUri: string,
client: LanguageClient,
Expand Down