| /*--------------------------------------------------------- |
| * Copyright (C) Microsoft Corporation. All rights reserved. |
| * Licensed under the MIT License. See License.txt in the project root for license information. |
| *--------------------------------------------------------*/ |
| |
| 'use strict'; |
| |
| import cp = require('child_process'); |
| import path = require('path'); |
| import vscode = require('vscode'); |
| import { getAllPackages } from './goPackages'; |
| import { envPath } from './goPath'; |
| import { getBinPath, getCurrentGoPath, getImportPath } from './util'; |
| |
| export function browsePackages() { |
| let workDir = ''; |
| let selectedText = ''; |
| const editor = vscode.window.activeTextEditor; |
| if (editor) { |
| const currentUri = editor.document.uri; |
| workDir = path.dirname(currentUri.fsPath); |
| const selection = editor.selection; |
| if (!selection.isEmpty) { |
| // get selected text |
| selectedText = editor.document.getText(selection); |
| } else { |
| // if selection is empty, then get the whole line the cursor is currently on. |
| selectedText = editor.document.lineAt(selection.active.line).text; |
| } |
| selectedText = getImportPath(selectedText) || selectedText.trim(); |
| } else if (vscode.workspace.workspaceFolders && vscode.workspace.workspaceFolders.length === 1) { |
| const currentUri = vscode.workspace.workspaceFolders[0].uri; |
| workDir = currentUri.fsPath; |
| } |
| |
| showPackageFiles(selectedText, true, workDir); |
| } |
| |
| function showPackageFiles(pkg: string, showAllPkgsIfPkgNotFound: boolean, workDir: string) { |
| const goRuntimePath = getBinPath('go'); |
| if (!goRuntimePath) { |
| return vscode.window.showErrorMessage( |
| `Failed to run "go list" to fetch packages as the "go" binary cannot be found in either GOROOT(${process.env['GOROOT']}) or PATH(${envPath})` |
| ); |
| } |
| |
| if (!pkg && showAllPkgsIfPkgNotFound) { |
| return showPackageList(workDir); |
| } |
| |
| const options: { [key: string]: any } = { |
| env: Object.assign({}, process.env, { GOPATH: getCurrentGoPath() }) |
| }; |
| |
| if (workDir) { |
| options['cwd'] = workDir; |
| } |
| |
| cp.execFile( |
| goRuntimePath, |
| ['list', '-f', '{{.Dir}}:{{.GoFiles}}:{{.TestGoFiles}}:{{.XTestGoFiles}}', pkg], |
| options, |
| (err, stdout, stderr) => { |
| if (!stdout || stdout.indexOf(':') === -1) { |
| if (showAllPkgsIfPkgNotFound) { |
| return showPackageList(workDir); |
| } |
| |
| return; |
| } |
| |
| const matches = stdout && stdout.match(/(.*):\[(.*)\]:\[(.*)\]:\[(.*)\]/); |
| if (matches) { |
| const dir = matches[1]; |
| let files = matches[2] ? matches[2].split(' ') : []; |
| const testfiles = matches[3] ? matches[3].split(' ') : []; |
| const xtestfiles = matches[4] ? matches[4].split(' ') : []; |
| files = files.concat(testfiles); |
| files = files.concat(xtestfiles); |
| vscode.window.showQuickPick(files, { placeHolder: `Below are Go files from ${pkg}` }).then((file) => { |
| // if user abandoned list, file will be null and path.join will error out. |
| // therefore return. |
| if (!file) { |
| return; |
| } |
| |
| vscode.workspace.openTextDocument(path.join(dir, file)).then((document) => { |
| vscode.window.showTextDocument(document); |
| }); |
| }); |
| } |
| } |
| ); |
| } |
| |
| function showPackageList(workDir: string) { |
| return getAllPackages(workDir).then((pkgMap) => { |
| const pkgs: string[] = Array.from(pkgMap.keys()); |
| if (pkgs.length === 0) { |
| return vscode.window.showErrorMessage( |
| 'Could not find packages. Ensure `gopkgs -format {{.Name}};{{.ImportPath}}` runs successfully.' |
| ); |
| } |
| |
| vscode.window |
| .showQuickPick(pkgs.sort(), { placeHolder: 'Select a package to browse' }) |
| .then((pkgFromDropdown) => { |
| if (!pkgFromDropdown) { |
| return; |
| } |
| showPackageFiles(pkgFromDropdown, false, workDir); |
| }); |
| }); |
| } |