Skip to content

Commit

Permalink
Merge pull request #20 from sublimelsp/f/gopls.vulncheck
Browse files Browse the repository at this point in the history
  • Loading branch information
TerminalFi committed Aug 3, 2022
2 parents e9978fa + 37fc2aa commit 2a608cc
Show file tree
Hide file tree
Showing 6 changed files with 355 additions and 62 deletions.
6 changes: 5 additions & 1 deletion LSP-gopls.sublime-commands
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,8 @@
"default": "// Settings in here override those in \"LSP-gopls/LSP-gopls.sublime-settings\"\n\n{\n\t$0\n}\n",
},
},
]
{
"caption": "LSP-gopls: Run Vuln Check (Experimental)",
"command": "gopls_run_vuln_check"
},
]
133 changes: 117 additions & 16 deletions plugin.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,31 @@
# Packages/LSP-gopls/plugin.py

import sublime

from LSP.plugin import AbstractPlugin, Session, parse_uri, register_plugin, unregister_plugin
from LSP.plugin.core.typing import Any, Optional, Tuple, Mapping, Callable, List, Union
import sublime_plugin


from .types import GoplsVulnerabilities
from .vulnerabilities import Vulnerabilities

from LSP.plugin import (
AbstractPlugin,
Session,
Request,
parse_uri,
register_plugin,
unregister_plugin,
)
from LSP.plugin.core.typing import (
Any,
Optional,
Tuple,
Mapping,
Callable,
List,
Union,
)
from LSP.plugin.core.registry import LspTextCommand
from LSP.plugin.core.views import uri_from_view

from shutil import which
import subprocess
Expand All @@ -26,9 +48,13 @@

RE_VER = re.compile(r'go(\d+)\.(\d+)(?:\.(\d+))?')

SESSION_NAME = 'gopls'


def open_tests_in_terminus(
session: Session, window: Optional[sublime.Window], arguments: Tuple[str, List[str], None]
session: Session,
window: Optional[sublime.Window],
arguments: Tuple[str, List[str], None],
) -> None:
if not window:
return
Expand All @@ -43,12 +69,16 @@ def open_tests_in_terminus(
go_test_directory = os.path.dirname(parse_uri(arguments[0])[1])
args = [go_test_directory]
for test_command in arguments[1]:
command_to_run = ['go', 'test'] + args + ['-v', '-count=1', '-run', '^{0}\\$'.format(test_command)]
command_to_run = (
['go', 'test']
+ args
+ ['-v', '-count=1', '-run', '^{0}\\$'.format(test_command)]
)
terminus_args = {
'title': 'Go Test',
'cmd': command_to_run,
'cwd': go_test_directory,
'auto_close': get_setting(session, 'closeTestResultsWhenFinished', False)
'auto_close': get_setting(session, 'closeTestResultsWhenFinished', False),
}
if get_setting(session, 'runTestsInPanel', True):
terminus_args['panel_name'] = 'Go Test'
Expand Down Expand Up @@ -81,7 +111,9 @@ def _is_gopls_installed(cls) -> bool:
binary = 'gopls.exe' if sublime.platform() == 'windows' else 'gopls'
command = [os.path.join(cls.basedir(), 'bin', binary)]

gopls_binary = sublime.expand_variables(command[0], {'storage_path': cls.storage_path()})
gopls_binary = sublime.expand_variables(
command[0], {'storage_path': cls.storage_path()}
)
if sublime.platform() == 'windows' and not gopls_binary.endswith('.exe'):
gopls_binary = gopls_binary + '.exe'
return _is_binary_available(gopls_binary)
Expand All @@ -93,11 +125,10 @@ def _is_go_installed(cls) -> bool:
@classmethod
def _get_go_version(cls) -> Tuple[int, int, int]:
stdout, stderr, return_code = run_go_command(
sub_command='version',
env_vars=cls._set_env_vars())
sub_command='version', env_vars=cls._set_env_vars()
)
if return_code != 0:
raise ValueError(
'go version error', stderr, 'returncode', return_code)
raise ValueError('go version error', stderr, 'returncode', return_code)

if stdout == '':
return (0, 0, 0)
Expand Down Expand Up @@ -141,13 +172,14 @@ def install_or_update(cls) -> None:
env_vars=cls._set_env_vars(),
)
if return_code != 0:
raise ValueError(
'go installation error', stderr, 'returncode', return_code)
raise ValueError('go installation error', stderr, 'returncode', return_code)

with open(os.path.join(cls.basedir(), 'VERSION'), 'w') as fp:
fp.write(cls.server_version())

def on_pre_server_command(self, command: Mapping[str, Any], done_callback: Callable[[], None]) -> bool:
def on_pre_server_command(
self, command: Mapping[str, Any], done_callback: Callable[[], None]
) -> bool:
if not Terminus:
return False

Expand All @@ -157,7 +189,9 @@ def on_pre_server_command(self, command: Mapping[str, Any], done_callback: Calla
if not session:
return False
try:
open_tests_in_terminus(session, sublime.active_window(), command['arguments'])
open_tests_in_terminus(
session, sublime.active_window(), command['arguments']
)
done_callback()
return True
except Exception as ex:
Expand Down Expand Up @@ -197,6 +231,69 @@ def run_go_command(
)


class GoplsOpenFileCommand(sublime_plugin.WindowCommand):
def run(self, uri: str) -> None:
self.window.open_file('{uri}'.format(uri=uri), sublime.ENCODED_POSITION)


class GoplsCommand(LspTextCommand):
session_name = SESSION_NAME


class GoplsRunVulnCheckCommand(GoplsCommand):
def run(self, edit: sublime.Edit) -> None:
self.edit = edit
session = self.session_by_name(self.session_name)
if session is None:
return

view = self.view
if not view:
return

folders = session.get_workspace_folders()
if len(folders) < 1:
path = os.path.dirname(uri_from_view(self.view))
self.run_gopls_vulncheck(path)
elif len(folders) == 1:
self.run_gopls_vulncheck(folders[0].uri())
else:
window = self.view.window()
if not window:
return
window.show_quick_panel(
[
sublime.QuickPanelItem(folder.name, folder.uri())
for folder in folders
],
on_select=lambda x: self.run_gopls_vulncheck(folders[x].uri()) if x != -1 else None,
)

def run_gopls_vulncheck(self, path: str) -> None:
session = self.session_by_name(self.session_name)
if session is None:
return

session.send_request(
Request(
'workspace/executeCommand',
{'command': 'gopls.run_vulncheck_exp', 'arguments': [{'dir': path}]},
),
on_result=lambda x: self.show_results_async(x.get('Vuln')),
)

def show_results_async(
self, vulnerabilities: Optional[GoplsVulnerabilities]
) -> None:
if vulnerabilities is None:
sublime.message_dialog('No vulnerabilities found')
return

Vulnerabilities(
window=self.view.window(), vulnerabilities=vulnerabilities
).show()


def to_int(value: Optional[str]) -> int:
if value is None:
return 0
Expand All @@ -207,7 +304,11 @@ def _is_binary_available(path) -> bool:
return bool(which(path))


def get_setting(session: Session, key: str, default: Optional[Union[str, bool, List[str]]] = None) -> Any:
def get_setting(
session: Session,
key: str,
default: Optional[Union[str, bool, List[str]]] = None,
) -> Any:
value = session.config.settings.get(key)
if value is None:
return default
Expand Down
Loading

0 comments on commit 2a608cc

Please sign in to comment.