Skip to content

Commit

Permalink
src/goToolsInformation: delete legacy tools
Browse files Browse the repository at this point in the history
Fixes #2799
For #1652

Change-Id: Ib7e046a1df0a63bd3babcf2019851bdcfe7e6726
Reviewed-on: https://go-review.googlesource.com/c/vscode-go/+/538762
TryBot-Result: kokoro <noreply+kokoro@google.com>
Commit-Queue: Hyang-Ah Hana Kim <hyangah@gmail.com>
Reviewed-by: Suzy Mueller <suzmue@golang.org>
  • Loading branch information
hyangah committed Nov 6, 2023
1 parent 324992b commit 053cd93
Show file tree
Hide file tree
Showing 5 changed files with 13 additions and 379 deletions.
47 changes: 0 additions & 47 deletions docs/tools.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,6 @@ This extension uses Delve for its debug/test functionalities. The extension curr

For a comprehensive overview of how to debug your Go programs, please see the [debugging guide](./debugging.md).

### [`dlv-dap`](https://github.com/go-delve/delve)
This extension requires an unstable version of [`dlv`](#dlv) when users opt in to use Delve's native DAP implementation. `dlv-dap` is a `dlv` built from the master, which includes unreleased features. Please see the documentation about [Dlv DAP - Delve's Native DAP implementation](./dlv-dap.md) for details.

### [`go-outline`](https://pkg.go.dev/github.com/ramya-rao-a/go-outline?tab=overview)

This tool provides the information needed to compute the various test code lenses. It will be replaced with [`gopls`]. <!--TODO: reference to the issue-->

### [`goplay`](https://pkg.go.dev/github.com/haya14busa/goplay?tab=overview)

This tool provides support for the [`Go: Run on Go Playground`](features.md#go-playground) command.
Expand Down Expand Up @@ -90,48 +83,8 @@ Configure `revive` to exclude `vendor` directories and apply extra configuration
]
```

### Misc tools used in the legacy mode

When `gopls` cannot be used, the extension falls back to the legacy mode. Be aware that many of these tools may be incompatible with the recent versions of Go or do not work in Modules mode.

* [`go-outline`](https://pkg.go.dev/github.com/ramya-rao-a/go-outline?tab=overview):
In the legacy mode, this tool provides the `[document outline](features.md#document-outline) feature` and the [go to symbol](features.md#go-to-symbol) in the current file feature.

* `gocode`: code completion in the legacy mode is provided by `gocode`. Different versions of `gocode` are used depending on your version of Go.
* Go 1.9 and above: [mdempsky/gocode](https://github.com/mdempsky/gocode)
* Go 1.11 and above, with modules enabled: [stamblerre/gocode](https://github.com/stamblerre/gocode), named `gocode-gomod` internally.

* [`go-symbols`](https://pkg.go.dev/github.com/acroca/go-symbols?tab=overview): provides the [go to symbol](features.md#go-to-symbol) in workspace feature.

* [`guru`](https://pkg.go.dev/golang.org/x/tools/cmd/guru?tab=doc): provides the [find references](features.md#find-references) and [find interface implementations](features.md#find-interface-implementations) features.
It can also be used to provide the [go to definition](features.md#go-to-definition) via the [`"go.docsTool"`](settings.md#go.docsTool) setting. `guru` does not support Go modules.

* [`gorename`](https://pkg.go.dev/golang.org/x/tools/cmd/gorename?tab=doc): provides the [rename symbol](features.md#rename-symbol) feature. `gorename` does not have support for Go modules

* [`godoctor`](https://github.com/godoctor/godoctor): provides the [refactoring](features.md#refactor) features. It does not support Go modules, and we expect that [`gopls`] will provide this feature instead ([golang/go#37170](https://github.com/golang/go/issues/37170)).

* [`fillstruct`](https://github.com/davidrjenni/reftools/tree/master/cmd/fillstruct): provides support the [`Go: Fill struct`](features.md#fill-struct-literals) command.

* [`gogetdoc`], [`godef`], [`godoc`]: these are documentation tools used for the [go to definition](features.md#go-to-definition), [signature help](features.md#signature-help), and [quick info on hover](features.md#quick-info-on-hover) in the legacy mode. [`guru`](#guru) can also be used, but only for the [go to definition](features.md#go-to-definition) behavior. Configure this via the [`"go.docsTool"`](settings.md#go.docsTool) setting.

* [`goimports`], [`gofmt`]: Formatting tools are used by the [formatting and import organization](features.md#format-and-organize-imports) features. [`goreturns`] is used by default in the legacy mode. It formats the file according to the industry standard [`gofmt`] style, organizes imports, and fills in default return values for functions. Other tools can be used for formatting instead; this can be configured with the [`"go.go.formatTool"`](settings.md#formatTool) setting.

* [`gofmt`] only formats the file, without import organization or filling in return values
* [`goformat`] is a configurable version of [`gofmt`]
* [`goreturns`] fills in default return values for functions, in addition to applying `goimports`-style formatting. This tool does not have support for Go modules.

* Diagnostics tools: By default, [`gotype-live`], [`go vet`], and [`golint`] are used to provide [build](features.md#build-errors), [vet](features.md#vet-errors), and [lint](features.md#lint-errors) errors. [`gotype-live`] provides build errors as you type, while `go build` can be used to show build errors only on save. [`gotype-live`] does not work with modules.



[`gogetdoc`]: https://pkg.go.dev/github.com/zmb3/gogetdoc?tab=overview
[`godef`]: https://pkg.go.dev/github.com/rogpeppe/godef?tab=doc
[`godoc`]: https://pkg.go.dev/golang.org/x/tools/godoc?tab=doc
[`goreturns`]: https://pkg.go.dev/github.com/sqs/goreturns?tab=overview
[`goimports`]: https://pkg.go.dev/golang.org/x/tools/cmd/goimports?tab=doc
[`gofmt`]: https://golang.org/cmd/gofmt/
[`goformat`]: https://pkg.go.dev/winterdrache.de/goformat?tab=overview
[`gotype-live`]: https://pkg.go.dev/github.com/tylerb/gotype-live?tab=doc
[`golint`]: https://pkg.go.dev/golang.org/x/lint/golint?tab=overview
[`staticcheck`]: https://pkg.go.dev/honnef.co/go/tools/staticcheck?tab=overview
[`golangci-lint`]: https://golangci-lint.run/
Expand Down
91 changes: 4 additions & 87 deletions src/goInstallTools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,7 @@ import { addGoRuntimeBaseToPATH, clearGoRuntimeBaseFromPATH } from './goEnvironm
import { logVerbose, logError } from './goLogging';
import { GoExtensionContext } from './context';
import { addGoStatus, initGoStatusBar, outputChannel, removeGoStatus } from './goStatus';
import {
containsTool,
getConfiguredTools,
getImportPath,
getImportPathWithVersion,
getTool,
hasModSuffix,
Tool,
ToolAtVersion
} from './goTools';
import { containsTool, getConfiguredTools, getImportPathWithVersion, getTool, Tool, ToolAtVersion } from './goTools';
import {
getBinPath,
getBinPathWithExplanation,
Expand All @@ -39,7 +30,7 @@ import {
GoVersion,
rmdirRecursive
} from './util';
import { correctBinname, getEnvPath, getCurrentGoRoot, setCurrentGoRoot } from './utils/pathUtils';
import { getEnvPath, getCurrentGoRoot, setCurrentGoRoot } from './utils/pathUtils';
import util = require('util');
import vscode = require('vscode');
import { RestartReason } from './language/goLanguageServer';
Expand Down Expand Up @@ -256,11 +247,7 @@ async function installToolWithGo(
const importPath = getImportPathWithVersion(tool, version, goVersion);

try {
if (hasModSuffix(tool)) {
await installToolWithGoGet(tool, goVersion, env, importPath);
} else {
await installToolWithGoInstall(goVersion, env, importPath);
}
await installToolWithGoInstall(goVersion, env, importPath);
const toolInstallPath = getBinPath(tool.name);
outputChannel.appendLine(`Installing ${importPath} (${toolInstallPath}) SUCCEEDED`);
} catch (e) {
Expand All @@ -284,76 +271,6 @@ async function installToolWithGoInstall(goVersion: GoVersion, env: NodeJS.Dict<s
await execFile(goBinary, ['install', '-v', importPath], opts);
}

async function installToolWithGoGet(
tool: ToolAtVersion,
goVersion: GoVersion,
env: NodeJS.Dict<string>,
importPath: string
) {
// Some users use direnv-like setup where the choice of go is affected by
// the current directory path. In order to avoid choosing a different go,
// we will explicitly use `GOROOT/bin/go` instead of goVersion.binaryPath
// (which can be a wrapper script that switches 'go').
const goBinary = getCurrentGoRoot()
? path.join(getCurrentGoRoot(), 'bin', correctBinname('go'))
: goVersion?.binaryPath;
if (!goBinary) {
vscode.window.showErrorMessage('Go binary not found.');
return;
}

// Build the arguments list for the tool installation.
const args = ['get', '-x'];
// tools with a "mod" suffix can't be installed with
// simple `go install` or `go get`. We need to get, build, and rename them.
if (hasModSuffix(tool)) {
args.push('-d'); // get the version, but don't build.
}
args.push(importPath);

let toolsTmpDir = '';
try {
toolsTmpDir = await tmpDirForToolInstallation();
} catch (e) {
throw new Error(`Failed to create a temp directory: ${e}`);
}

const opts = {
env,
cwd: toolsTmpDir
};

try {
const execFile = util.promisify(cp.execFile);
logVerbose(`$ ${goBinary} ${args.join(' ')} (cwd: ${opts.cwd})`);
await execFile(goBinary, args, opts);

if (hasModSuffix(tool)) {
// Actual installation of the -gomod tool is done by running go build.
let destDir = env['GOBIN'];
if (!destDir) {
const gopath0 = env['GOPATH']?.split(path.delimiter)[0];
destDir = gopath0 ? path.join(gopath0, 'bin') : undefined;
}
if (!destDir) {
throw new Error('GOBIN/GOPATH not configured in environment');
}
const outputFile = path.join(destDir, correctBinname(tool.name));

// go build does not take @version suffix yet.
const importPathWithoutVersion = getImportPath(tool, goVersion);
logVerbose(`$ ${goBinary} build -o ${outputFile} ${importPathWithoutVersion} (cwd: ${opts.cwd})`);
await execFile(goBinary, ['build', '-o', outputFile, importPathWithoutVersion], opts);
}
} catch (e) {
logVerbose(`FAILED: ${JSON.stringify(e, null, 1)}`);
throw e;
} finally {
// Delete the temporary installation directory.
rmdirRecursive(toolsTmpDir);
}
}

export function declinedToolInstall(toolName: string) {
const tool = getTool(toolName);

Expand Down Expand Up @@ -773,7 +690,7 @@ export async function shouldUpdateTool(tool: Tool, toolPath: string): Promise<bo

export async function suggestUpdates() {
const configuredGoVersion = await getGoVersion();
if (!configuredGoVersion || configuredGoVersion.lt('1.12')) {
if (!configuredGoVersion || configuredGoVersion.lt('1.16')) {
// User is using an ancient or a dev version of go. Don't suggest updates -
// user should know what they are doing.
return;
Expand Down
42 changes: 2 additions & 40 deletions src/goTools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,11 @@

'use strict';

import cp = require('child_process');
import moment = require('moment');
import path = require('path');
import semver = require('semver');
import util = require('util');
import { getFormatTool, usingCustomFormatTool } from './language/legacy/goFormat';
import { allToolsInformation } from './goToolsInformation';
import { getBinPath, GoVersion } from './util';
import { GoVersion } from './util';

export interface Tool {
name: string;
Expand Down Expand Up @@ -59,25 +56,12 @@ export interface ToolAtVersion extends Tool {
version?: semver.SemVer;
}

/**
* Returns the import path for a given tool, at a given Go version.
* @param tool Object of type `Tool` for the Go tool.
* @param goVersion The current Go version.
*/
export function getImportPath(tool: Tool, goVersion: GoVersion): string {
// For older versions of Go, install the older version of gocode.
if (tool.name === 'gocode' && goVersion?.lt('1.10')) {
return 'github.com/nsf/gocode';
}
return tool.importPath;
}

export function getImportPathWithVersion(
tool: Tool,
version: semver.SemVer | string | undefined | null,
goVersion: GoVersion
): string {
const importPath = getImportPath(tool, goVersion);
const importPath = tool.importPath;
if (version) {
if (version instanceof semver.SemVer) {
return importPath + '@v' + version;
Expand Down Expand Up @@ -125,10 +109,6 @@ export function hasModSuffix(tool: Tool): boolean {
return tool.name.endsWith('-gomod');
}

export function isGocode(tool: Tool): boolean {
return tool.name === 'gocode' || tool.name === 'gocode-gomod';
}

export function getConfiguredTools(goConfig: { [key: string]: any }, goplsConfig: { [key: string]: any }): Tool[] {
// If language server is enabled, don't suggest tools that are replaced by gopls.
// TODO(github.com/golang/vscode-go/issues/388): decide what to do when
Expand Down Expand Up @@ -190,21 +170,3 @@ export function goplsStaticcheckEnabled(
}
return true;
}

export const gocodeClose = async (env: NodeJS.Dict<string>): Promise<string> => {
const toolBinPath = getBinPath('gocode');
if (!path.isAbsolute(toolBinPath)) {
return '';
}
try {
const execFile = util.promisify(cp.execFile);
const { stderr } = await execFile(toolBinPath, ['close'], { env, timeout: 10000 }); // give 10sec.
if (stderr.indexOf("rpc: can't find service Server.") > -1) {
return 'Installing gocode aborted as existing process cannot be closed. Please kill the running process for gocode and try again.';
}
} catch (err) {
// This may fail if gocode isn't already running.
console.log(`gocode close failed: ${err}`);
}
return '';
};
Loading

0 comments on commit 053cd93

Please sign in to comment.