From d4f989db3d053d6f9545f245d81d9fd8552a4a9a Mon Sep 17 00:00:00 2001 From: ZhuzhuNo3 Date: Thu, 26 Dec 2024 18:04:27 +0800 Subject: [PATCH] Fix GoToDefinition issues in non-compliant repositories lacking go.sum in GOMODCACHE This commit addresses the problem where the GoToDefinition feature fails to execute in certain repositories located within the GOMODCACHE path. These specific repositories were not compliant due to the absence of a go.sum file, which is essential for ensuring module integrity and correct dependency resolution. Add `let g:ycm_gopls_excluded_workspace_paths = null` or `let g:ycm_gopls_excluded_workspace_paths = ['PATH_TO_GOMODCACHE', 'NO_GOSUM_REPO_PATH']` to enable this change. --- ycmd/completers/go/go_completer.py | 32 ++++++++++++++++++++++++++++++ ycmd/default_settings.json | 1 + 2 files changed, 33 insertions(+) diff --git a/ycmd/completers/go/go_completer.py b/ycmd/completers/go/go_completer.py index 50990a1df8..f1a9410186 100644 --- a/ycmd/completers/go/go_completer.py +++ b/ycmd/completers/go/go_completer.py @@ -15,6 +15,8 @@ # You should have received a copy of the GNU General Public License # along with ycmd. If not, see . +from pathlib import Path +import subprocess import json import logging import os @@ -34,6 +36,18 @@ utils.ExecutableName( 'gopls' ) ) ) +def GetGoModCachePath(): + try: + result = subprocess.run(['go', 'env', 'GOMODCACHE'], capture_output=True, text=True, check=True) + return [ result.stdout.strip() ] + except subprocess.CalledProcessError as e: + utils.LOGGER.info( 'Error getting GOMODCACHE: %s', e ) + return [] + + +PATHS_TO_GO_MOD_CACHE = GetGoModCachePath() + + def ShouldEnableGoCompleter( user_options ): server_exists = utils.FindExecutableWithFallback( user_options[ 'gopls_binary_path' ], @@ -51,6 +65,12 @@ def __init__( self, user_options ): self._gopls_path = utils.FindExecutableWithFallback( user_options[ 'gopls_binary_path' ], PATH_TO_GOPLS ) + # Exclude paths within the Go module cache or other directories where a go.sum cannot be created. + excluded_workspace_paths = user_options.get('gopls_excluded_workspace_paths') + if isinstance(excluded_workspace_paths, list): + self._excluded_workspace_paths = excluded_workspace_paths + else: + self._excluded_workspace_paths = PATHS_TO_GO_MOD_CACHE def GetServerName( self ): @@ -65,6 +85,18 @@ def GetProjectRootFiles( self ): return [ 'go.mod' ] + def GetWorkspaceForFilepath( self, filepath, strict = False ): + filepath_abs = os.path.abspath(filepath) + if any(excluded_path in filepath_abs for excluded_path in self._excluded_workspace_paths): + return None + project_root_files = self.GetProjectRootFiles() + for folder in utils.PathsToAllParentFolders( filepath ): + for root_file in project_root_files: + if next( Path( folder ).glob( root_file ), [] ): + return folder + return None if strict else os.path.dirname( filepath ) + + def GetCommandLine( self ): cmdline = [ self._gopls_path ] + self._user_supplied_gopls_args + [ '-logfile', diff --git a/ycmd/default_settings.json b/ycmd/default_settings.json index e83595827c..cac647cca3 100644 --- a/ycmd/default_settings.json +++ b/ycmd/default_settings.json @@ -38,6 +38,7 @@ "disable_signature_help": 0, "gopls_binary_path": "", "gopls_args": [], + "gopls_excluded_workspace_paths": [], "rust_toolchain_root": "", "tsserver_binary_path": "", "roslyn_binary_path": "",