diff --git a/install_gadget.py b/install_gadget.py index f805e80..af2794e 100755 --- a/install_gadget.py +++ b/install_gadget.py @@ -23,9 +23,6 @@ if sys.version_info.major < 3: import argparse import os -import string -import subprocess -import traceback import json import functools import operator @@ -35,628 +32,9 @@ import glob sys.path.insert( 1, os.path.join( os.path.dirname( __file__ ), 'python3' ) ) -from vimspector import install, installer +from vimspector import install, installer, gadgets from vimspector.vendor.json_minify import minify -GADGETS = { - 'vscode-cpptools': { - 'language': 'c', - 'download': { - 'url': 'https://github.com/Microsoft/vscode-cpptools/releases/download/' - '${version}/${file_name}', - }, - 'do': lambda name, root, gadget: InstallCppTools( name, root, gadget ), - 'all': { - 'version': '0.27.0', - "adapters": { - "vscode-cpptools": { - "name": "cppdbg", - "command": [ - "${gadgetDir}/vscode-cpptools/debugAdapters/OpenDebugAD7" - ], - "attach": { - "pidProperty": "processId", - "pidSelect": "ask" - }, - "configuration": { - "type": "cppdbg", - "args": [], - "cwd": "${workspaceRoot}", - "environment": [], - } - }, - }, - }, - 'linux': { - 'file_name': 'cpptools-linux.vsix', - 'checksum': - '3695202e1e75a03de18049323b66d868165123f26151f8c974a480eaf0205435', - }, - 'macos': { - 'file_name': 'cpptools-osx.vsix', - 'checksum': - 'cb061e3acd7559a539e5586f8d3f535101c4ec4e8a48195856d1d39380b5cf3c', - }, - 'windows': { - 'file_name': 'cpptools-win32.vsix', - 'checksum': - 'aa294368ed16d48c59e49c8000e146eae5a19ad07b654efed5db8ec93b24229e', - "adapters": { - "vscode-cpptools": { - "name": "cppdbg", - "command": [ - "${gadgetDir}/vscode-cpptools/debugAdapters/bin/OpenDebugAD7.exe" - ], - "attach": { - "pidProperty": "processId", - "pidSelect": "ask" - }, - "configuration": { - "type": "cppdbg", - "args": [], - "cwd": "${workspaceRoot}", - "environment": [], - "MIMode": "gdb", - "MIDebuggerPath": "gdb.exe" - } - }, - }, - }, - }, - 'vscode-python': { - 'language': 'python.legacy', - 'enabled': False, - 'download': { - 'url': 'https://github.com/Microsoft/vscode-python/releases/download/' - '${version}/${file_name}', - }, - 'all': { - 'version': '2019.11.50794', - 'file_name': 'ms-python-release.vsix', - 'checksum': - '6a9edf9ecabed14aac424e6007858068204a3638bf3bb4f235bd6035d823acc6', - }, - 'adapters': { - "vscode-python": { - "name": "vscode-python", - "command": [ - "node", - "${gadgetDir}/vscode-python/out/client/debugger/debugAdapter/main.js", - ], - } - }, - }, - 'debugpy': { - 'language': 'python', - 'download': { - 'url': 'https://github.com/microsoft/debugpy/archive/${file_name}' - }, - 'all': { - 'version': '1.0.0b12', - 'file_name': 'v1.0.0b12.zip', - 'checksum': - '210632bba2221fbb841c9785a615258819ceec401d1abdbeb5f2326f12cc72a1' - }, - 'do': lambda name, root, gadget: InstallDebugpy( name, root, gadget ), - 'adapters': { - 'debugpy': { - "command": [ - sys.executable, - "${gadgetDir}/debugpy/build/lib/debugpy/adapter" - ], - "name": "debugpy", - "configuration": { - "python": sys.executable, - # Don't debug into subprocesses, as this leads to problems (vimspector - # doesn't support the custom messages) - # https://github.com/puremourning/vimspector/issues/141 - "subProcess": False, - } - } - }, - }, - 'vscode-java-debug': { - 'language': 'java', - 'enabled': False, - 'download': { - 'url': 'https://github.com/microsoft/vscode-java-debug/releases/download/' - '${version}/${file_name}', - }, - 'all': { - 'version': '0.26.0', - 'file_name': 'vscjava.vscode-java-debug-0.26.0.vsix', - 'checksum': - 'de49116ff3a3c941dad0c36d9af59baa62cd931e808a2ab392056cbb235ad5ef', - }, - 'adapters': { - "vscode-java": { - "name": "vscode-java", - "port": "${DAPPort}", - } - }, - }, - 'java-language-server': { - 'language': 'javac', - 'enabled': False, - 'download': { - 'url': 'https://marketplace.visualstudio.com/_apis/public/gallery/' - 'publishers/georgewfraser/vsextensions/vscode-javac/${version}/' - 'vspackage', - 'target': 'georgewfraser.vscode-javac-0.2.31.vsix.gz', - 'format': 'zip.gz', - }, - 'all': { - 'version': '0.2.31', - 'file_name': 'georgewfraser.vscode-javac-0.2.31.vsix.gz', - 'checksum': - '5b0248ec1198d3ece9a9c6b9433b30c22e308f0ae6e4c7bd09cd943c454e3e1d', - }, - 'adapters': { - "vscode-javac": { - "name": "vscode-javac", - "type": "vscode-javac", - "command": [ - "${gadgetDir}/java-language-server/dist/debug_adapter_mac.sh" - ], - "attach": { - "pidSelect": "none" - } - } - }, - }, - 'tclpro': { - 'language': 'tcl', - 'repo': { - 'url': 'https://github.com/puremourning/TclProDebug', - 'ref': 'master' - }, - 'do': lambda name, root, gadget: InstallTclProDebug( name, root, gadget ), - 'adapters': { - "tclpro": { - "name": "tclpro", - "type": "tclpro", - "command": [ - "${gadgetDir}/tclpro/bin/debugadapter" - ], - "attach": { - "pidSelect": "none" - }, - "configuration": { - "target": "${file}", - "args": [ "*${args}" ], - "tclsh": "tclsh", - "cwd": "${workspaceRoot}", - "extensionDirs": [ - "${workspaceRoot}/.tclpro/extensions", - "${HOME}/.tclpro/extensions", - ] - } - } - }, - }, - 'netcoredbg': { - 'language': 'csharp', - 'enabled': False, - 'download': { - 'url': 'https://github.com/Samsung/netcoredbg/releases/download/latest/' - '${file_name}', - 'format': 'tar', - }, - 'all': { - 'version': 'master' - }, - 'macos': { - 'file_name': 'netcoredbg-osx-master.tar.gz', - 'checksum': - 'c1dc6ed58c3f5b0473cfb4985a96552999360ceb9795e42d9c9be64af054f821', - }, - 'linux': { - 'file_name': 'netcoredbg-linux-master.tar.gz', - 'checksum': '', - }, - 'windows': { - 'file_name': 'netcoredbg-win64-master.zip', - 'checksum': '', - }, - 'do': lambda name, root, gadget: installer.MakeSymlink( - gadget_dir, - name, - os.path.join( root, 'netcoredbg' ) ), - 'adapters': { - 'netcoredbg': { - "name": "netcoredbg", - "command": [ - "${gadgetDir}/netcoredbg/netcoredbg", - "--interpreter=vscode" - ], - "attach": { - "pidProperty": "processId", - "pidSelect": "ask" - }, - }, - } - }, - 'vscode-mono-debug': { - 'language': 'csharp', - 'enabled': False, - 'download': { - 'url': 'https://marketplace.visualstudio.com/_apis/public/gallery/' - 'publishers/ms-vscode/vsextensions/mono-debug/${version}/' - 'vspackage', - 'target': 'vscode-mono-debug.vsix.gz', - 'format': 'zip.gz', - }, - 'all': { - 'file_name': 'vscode-mono-debug.vsix', - 'version': '0.15.8', - 'checksum': - '723eb2b621b99d65a24f215cb64b45f5fe694105613a900a03c859a62a810470', - }, - 'adapters': { - 'vscode-mono-debug': { - "name": "mono-debug", - "command": [ - "mono", - "${gadgetDir}/vscode-mono-debug/bin/Release/mono-debug.exe" - ], - "attach": { - "pidSelect": "none" - }, - }, - } - }, - 'vscode-bash-debug': { - 'language': 'bash', - 'download': { - 'url': 'https://github.com/rogalmic/vscode-bash-debug/releases/' - 'download/${version}/${file_name}', - }, - 'all': { - 'file_name': 'bash-debug-0.3.7.vsix', - 'version': 'v0.3.7', - 'checksum': - '7b73e5b4604375df8658fb5a72c645c355785a289aa785a986e508342c014bb4', - }, - 'do': lambda name, root, gadget: InstallBashDebug( name, root, gadget ), - 'adapters': { - "vscode-bash": { - "name": "bashdb", - "command": [ - "node", - "${gadgetDir}/vscode-bash-debug/out/bashDebug.js" - ], - "variables": { - "BASHDB_HOME": "${gadgetDir}/vscode-bash-debug/bashdb_dir" - }, - "configuration": { - "request": "launch", - "type": "bashdb", - "program": "${file}", - "args": [], - "env": {}, - "pathBash": "bash", - "pathBashdb": "${BASHDB_HOME}/bashdb", - "pathBashdbLib": "${BASHDB_HOME}", - "pathCat": "cat", - "pathMkfifo": "mkfifo", - "pathPkill": "pkill", - "cwd": "${workspaceRoot}", - "terminalKind": "integrated", - } - } - } - }, - 'vscode-go': { - 'language': 'go', - 'download': { - 'url': 'https://github.com/microsoft/vscode-go/releases/download/' - '${version}/${file_name}' - }, - 'all': { - 'version': '0.11.4', - 'file_name': 'Go-0.11.4.vsix', - 'checksum': - 'ff7d7b944da5448974cb3a0086f4a2fd48e2086742d9c013d6964283d416027e' - }, - 'adapters': { - 'vscode-go': { - 'name': 'delve', - 'command': [ - 'node', - '${gadgetDir}/vscode-go/out/src/debugAdapter/goDebug.js' - ], - }, - }, - }, - 'vscode-php-debug': { - 'language': 'php', - 'enabled': False, - 'download': { - 'url': - 'https://github.com/felixfbecker/vscode-php-debug/releases/download/' - '${version}/${file_name}', - }, - 'all': { - 'version': 'v1.13.0', - 'file_name': 'php-debug.vsix', - 'checksum': - '8a51e593458fd14623c1c89ebab87347b087d67087717f18bcf77bb788052718', - }, - 'adapters': { - 'vscode-php-debug': { - 'name': "php-debug", - 'command': [ - 'node', - "${gadgetDir}/vscode-php-debug/out/phpDebug.js", - ] - } - } - }, - 'vscode-node-debug2': { - 'language': 'node', - 'enabled': False, - 'repo': { - 'url': 'https://github.com/microsoft/vscode-node-debug2', - 'ref': 'v1.42.0', - }, - 'do': lambda name, root, gadget: InstallNodeDebug( name, root, gadget ), - 'adapters': { - 'vscode-node': { - 'name': 'node2', - 'type': 'node2', - 'command': [ - 'node', - '${gadgetDir}/vscode-node-debug2/out/src/nodeDebug.js' - ] - }, - }, - }, - 'debugger-for-chrome': { - 'language': 'chrome', - 'enabled': False, - 'download': { - 'url': 'https://marketplace.visualstudio.com/_apis/public/gallery/' - 'publishers/msjsdiag/vsextensions/' - 'debugger-for-chrome/${version}/vspackage', - 'target': 'msjsdiag.debugger-for-chrome-4.12.0.vsix.gz', - 'format': 'zip.gz', - }, - 'all': { - 'version': '4.12.0', - 'file_name': 'msjsdiag.debugger-for-chrome-4.12.0.vsix', - 'checksum': - '0df2fe96d059a002ebb0936b0003e6569e5a5c35260dc3791e1657d27d82ccf5' - }, - 'adapters': { - 'chrome': { - 'name': 'debugger-for-chrome', - 'type': 'chrome', - 'command': [ - 'node', - '${gadgetDir}/debugger-for-chrome/out/src/chromeDebug.js' - ], - }, - }, - }, - 'CodeLLDB': { - 'language': 'rust', - 'enabled': False, - 'download': { - 'url': 'https://github.com/vadimcn/vscode-lldb/releases/download/' - '${version}/${file_name}', - }, - 'all': { - 'version': 'v1.5.3', - }, - 'macos': { - 'file_name': 'codelldb-x86_64-darwin.vsix', - 'checksum': - '7505bc1cdfcfd1cb981e2996aec62d63577440709bac31dcadb41a3b4b44631a', - 'make_executable': [ - 'adapter/codelldb', - 'lldb/bin/debugserver', - 'lldb/bin/lldb', - 'lldb/bin/lldb-argdumper', - ], - }, - 'linux': { - 'file_name': 'codelldb-x86_64-linux.vsix', - 'checksum': - 'ce7efc3e94d775368e5942a02bf5c326b6809a0b4c389f79ffa6a8f6f6b72139', - 'make_executable': [ - 'adapter/codelldb', - 'lldb/bin/lldb', - 'lldb/bin/lldb-server', - 'lldb/bin/lldb-argdumper', - ], - }, - 'windows': { - 'file_name': 'codelldb-x86_64-windows.vsix', - 'checksum': - '', - 'make_executable': [] - }, - 'adapters': { - 'CodeLLDB': { - 'name': 'CodeLLDB', - 'type': 'CodeLLDB', - "command": [ - "${gadgetDir}/CodeLLDB/adapter/codelldb", - "--port", "${unusedLocalPort}" - ], - "port": "${unusedLocalPort}", - "configuration": { - "type": "lldb", - "name": "lldb", - "cargo": {}, - "args": [], - "cwd": "${workspaceRoot}", - "env": {}, - "terminal": "integrated", - } - }, - }, - }, -} - - -def InstallGeneric( name, root, gadget ): - extension = os.path.join( root, 'extension' ) - for f in gadget.get( 'make_executable', [] ): - installer.MakeExecutable( os.path.join( extension, f ) ) - - installer.MakeExtensionSymlink( vimspector_base, name, root ) - - -def InstallCppTools( name, root, gadget ): - extension = os.path.join( root, 'extension' ) - - # It's hilarious, but the execute bits aren't set in the vsix. So they - # actually have javascript code which does this. It's just a horrible horrible - # hack that really is not funny. - installer.MakeExecutable( os.path.join( extension, - 'debugAdapters', - 'OpenDebugAD7' ) ) - with open( os.path.join( extension, 'package.json' ) ) as f: - package = json.load( f ) - runtime_dependencies = package[ 'runtimeDependencies' ] - for dependency in runtime_dependencies: - for binary in dependency.get( 'binaries' ): - file_path = os.path.abspath( os.path.join( extension, binary ) ) - if os.path.exists( file_path ): - installer.MakeExecutable( os.path.join( extension, binary ) ) - - installer.MakeExtensionSymlink( vimspector_base, name, root ) - - -def InstallBashDebug( name, root, gadget ): - installer.MakeExecutable( os.path.join( root, - 'extension', - 'bashdb_dir', - 'bashdb' ) ) - installer.MakeExtensionSymlink( vimspector_base, name, root ) - - -def InstallDebugpy( name, root, gadget ): - wd = os.getcwd() - root = os.path.join( root, 'debugpy-{}'.format( gadget[ 'version' ] ) ) - os.chdir( root ) - try: - subprocess.check_call( [ sys.executable, 'setup.py', 'build' ] ) - finally: - os.chdir( wd ) - - installer.MakeSymlink( gadget_dir, name, root ) - - -def InstallTclProDebug( name, root, gadget ): - configure = [ './configure' ] - - if OS == 'macos': - # Apple removed the headers from system frameworks because they are - # determined to make life difficult. And the TCL configure scripts are super - # old so don't know about this. So we do their job for them and try and find - # a tclConfig.sh. - # - # NOTE however that in Apple's infinite wisdom, installing the "headers" in - # the other location is actually broken because the paths in the - # tclConfig.sh are pointing at the _old_ location. You actually do have to - # run the package installation which puts the headers back in order to work. - # This is why the below list is does not contain stuff from - # /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform - # '/Applications/Xcode.app/Contents/Developer/Platforms' - # '/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System' - # '/Library/Frameworks/Tcl.framework', - # '/Applications/Xcode.app/Contents/Developer/Platforms' - # '/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System' - # '/Library/Frameworks/Tcl.framework/Versions' - # '/Current', - for p in [ '/usr/local/opt/tcl-tk/lib' ]: - if os.path.exists( os.path.join( p, 'tclConfig.sh' ) ): - configure.append( '--with-tcl=' + p ) - break - - - with installer.CurrentWorkingDir( os.path.join( root, 'lib', 'tclparser' ) ): - subprocess.check_call( configure ) - subprocess.check_call( [ 'make' ] ) - - installer.MakeSymlink( gadget_dir, name, root ) - - -def InstallNodeDebug( name, root, gadget ): - node_version = subprocess.check_output( [ 'node', '--version' ], - universal_newlines=True ).strip() - print( "Node.js version: {}".format( node_version ) ) - if list( map( int, node_version[ 1: ].split( '.' ) ) ) >= [ 12, 0, 0 ]: - print( "Can't install vscode-debug-node2:" ) - print( "Sorry, you appear to be running node 12 or later. That's not " - "compatible with the build system for this extension, and as far as " - "we know, there isn't a pre-built independent package." ) - print( "My advice is to install nvm, then do:" ) - print( " $ nvm install --lts 10" ) - print( " $ nvm use --lts 10" ) - print( " $ ./install_gadget.py --enable-node ..." ) - raise RuntimeError( 'Invalid node environent for node debugger' ) - - with installer.CurrentWorkingDir( root ): - subprocess.check_call( [ 'npm', 'install' ] ) - subprocess.check_call( [ 'npm', 'run', 'build' ] ) - installer.MakeSymlink( gadget_dir, name, root ) - - -def InstallGagdet( name, gadget, failed, all_adapters ): - try: - v = {} - v.update( gadget.get( 'all', {} ) ) - v.update( gadget.get( OS, {} ) ) - - if 'download' in gadget: - if 'file_name' not in v: - raise RuntimeError( "Unsupported OS {} for gadget {}".format( OS, - name ) ) - - destination = os.path.join( gadget_dir, 'download', name, v[ 'version' ] ) - - url = string.Template( gadget[ 'download' ][ 'url' ] ).substitute( v ) - - file_path = installer.DownloadFileTo( - url, - destination, - file_name = gadget[ 'download' ].get( 'target' ), - checksum = v.get( 'checksum' ), - check_certificate = not args.no_check_certificate ) - - root = os.path.join( destination, 'root' ) - installer.ExtractZipTo( - file_path, - root, - format = gadget[ 'download' ].get( 'format', 'zip' ) ) - elif 'repo' in gadget: - url = string.Template( gadget[ 'repo' ][ 'url' ] ).substitute( v ) - ref = string.Template( gadget[ 'repo' ][ 'ref' ] ).substitute( v ) - - destination = os.path.join( gadget_dir, 'download', name ) - installer.CloneRepoTo( url, ref, destination ) - root = destination - - if 'do' in gadget: - gadget[ 'do' ]( name, root, v ) - else: - InstallGeneric( name, root, v ) - - # Allow per-OS adapter overrides. v already did that for us... - all_adapters.update( v.get( 'adapters', {} ) ) - # Add any other "all" adapters - all_adapters.update( gadget.get( 'adapters', {} ) ) - - print( "Done installing {}".format( name ) ) - except Exception as e: - traceback.print_exc() - failed.append( name ) - print( "FAILED installing {}: {}".format( name, e ) ) - - # ------------------------------------------------------------------------------ # Entry point # ------------------------------------------------------------------------------ @@ -723,7 +101,7 @@ parser.add_argument( '--sudo', "run this as root via sudo, pass this flag." ) done_languages = set() -for name, gadget in GADGETS.items(): +for name, gadget in gadgets.GADGETS.items(): lang = gadget[ 'language' ] if lang in done_languages: continue @@ -766,12 +144,8 @@ if args.basedir: vimspector_base = os.path.abspath( args.basedir ) install.MakeInstallDirs( vimspector_base ) - -OS = install.GetOS() -gadget_dir = install.GetGadgetDir( vimspector_base, OS ) - -print( 'OS = ' + OS ) -print( 'gadget_dir = ' + gadget_dir ) +installer.Configure( vimspector_base = vimspector_base, + no_check_certificate = args.no_check_certificate ) if args.force_all and not args.all: args.all = True @@ -803,7 +177,7 @@ all_adapters.update( { }, } ) -for name, gadget in GADGETS.items(): +for name, gadget in gadgets.GADGETS.items(): if not gadget.get( 'enabled', True ): if ( not args.force_all and not getattr( args, 'force_enable_' + gadget[ 'language' ] ) ): @@ -814,14 +188,14 @@ for name, gadget in GADGETS.items(): if getattr( args, 'disable_' + gadget[ 'language' ] ): continue - InstallGagdet( name, - gadget, - failed, - all_adapters ) + installer.InstallGagdet( name, + gadget, + failed, + all_adapters ) for name, gadget in CUSTOM_GADGETS.items(): - InstallGagdet( name, gadget, failed, all_adapters ) + installer.InstallGagdet( name, gadget, failed, all_adapters ) adapter_config = json.dumps ( { 'adapters': all_adapters }, indent=2, diff --git a/python3/vimspector/gadgets.py b/python3/vimspector/gadgets.py new file mode 100644 index 0000000..a96c9f5 --- /dev/null +++ b/python3/vimspector/gadgets.py @@ -0,0 +1,490 @@ +# vimspector - A multi-language debugging system for Vim +# Copyright 2020 Ben Jackson +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +from vimspector import installer +import sys +import os + + +GADGETS = { + 'vscode-cpptools': { + 'language': 'c', + 'download': { + 'url': 'https://github.com/Microsoft/vscode-cpptools/releases/download/' + '${version}/${file_name}', + }, + 'do': lambda name, root, gadget: installer.InstallCppTools( name, + root, + gadget ), + 'all': { + 'version': '0.27.0', + "adapters": { + "vscode-cpptools": { + "name": "cppdbg", + "command": [ + "${gadgetDir}/vscode-cpptools/debugAdapters/OpenDebugAD7" + ], + "attach": { + "pidProperty": "processId", + "pidSelect": "ask" + }, + "configuration": { + "type": "cppdbg", + "args": [], + "cwd": "${workspaceRoot}", + "environment": [], + } + }, + }, + }, + 'linux': { + 'file_name': 'cpptools-linux.vsix', + 'checksum': + '3695202e1e75a03de18049323b66d868165123f26151f8c974a480eaf0205435', + }, + 'macos': { + 'file_name': 'cpptools-osx.vsix', + 'checksum': + 'cb061e3acd7559a539e5586f8d3f535101c4ec4e8a48195856d1d39380b5cf3c', + }, + 'windows': { + 'file_name': 'cpptools-win32.vsix', + 'checksum': + 'aa294368ed16d48c59e49c8000e146eae5a19ad07b654efed5db8ec93b24229e', + "adapters": { + "vscode-cpptools": { + "name": "cppdbg", + "command": [ + "${gadgetDir}/vscode-cpptools/debugAdapters/bin/OpenDebugAD7.exe" + ], + "attach": { + "pidProperty": "processId", + "pidSelect": "ask" + }, + "configuration": { + "type": "cppdbg", + "args": [], + "cwd": "${workspaceRoot}", + "environment": [], + "MIMode": "gdb", + "MIDebuggerPath": "gdb.exe" + } + }, + }, + }, + }, + 'vscode-python': { + 'language': 'python.legacy', + 'enabled': False, + 'download': { + 'url': 'https://github.com/Microsoft/vscode-python/releases/download/' + '${version}/${file_name}', + }, + 'all': { + 'version': '2019.11.50794', + 'file_name': 'ms-python-release.vsix', + 'checksum': + '6a9edf9ecabed14aac424e6007858068204a3638bf3bb4f235bd6035d823acc6', + }, + 'adapters': { + "vscode-python": { + "name": "vscode-python", + "command": [ + "node", + "${gadgetDir}/vscode-python/out/client/debugger/debugAdapter/main.js", + ], + } + }, + }, + 'debugpy': { + 'language': 'python', + 'download': { + 'url': 'https://github.com/microsoft/debugpy/archive/${file_name}' + }, + 'all': { + 'version': '1.0.0b12', + 'file_name': 'v1.0.0b12.zip', + 'checksum': + '210632bba2221fbb841c9785a615258819ceec401d1abdbeb5f2326f12cc72a1' + }, + 'do': lambda name, root, gadget: installer.InstallDebugpy( name, + root, + gadget ), + 'adapters': { + 'debugpy': { + "command": [ + sys.executable, # TODO: Will this work from within Vim ? + "${gadgetDir}/debugpy/build/lib/debugpy/adapter" + ], + "name": "debugpy", + "configuration": { + "python": sys.executable, # TODO: Will this work from within Vim ? + # Don't debug into subprocesses, as this leads to problems (vimspector + # doesn't support the custom messages) + # https://github.com/puremourning/vimspector/issues/141 + "subProcess": False, + } + } + }, + }, + 'vscode-java-debug': { + 'language': 'java', + 'enabled': False, + 'download': { + 'url': 'https://github.com/microsoft/vscode-java-debug/releases/download/' + '${version}/${file_name}', + }, + 'all': { + 'version': '0.26.0', + 'file_name': 'vscjava.vscode-java-debug-0.26.0.vsix', + 'checksum': + 'de49116ff3a3c941dad0c36d9af59baa62cd931e808a2ab392056cbb235ad5ef', + }, + 'adapters': { + "vscode-java": { + "name": "vscode-java", + "port": "${DAPPort}", + } + }, + }, + 'java-language-server': { + 'language': 'javac', + 'enabled': False, + 'download': { + 'url': 'https://marketplace.visualstudio.com/_apis/public/gallery/' + 'publishers/georgewfraser/vsextensions/vscode-javac/${version}/' + 'vspackage', + 'target': 'georgewfraser.vscode-javac-0.2.31.vsix.gz', + 'format': 'zip.gz', + }, + 'all': { + 'version': '0.2.31', + 'file_name': 'georgewfraser.vscode-javac-0.2.31.vsix.gz', + 'checksum': + '5b0248ec1198d3ece9a9c6b9433b30c22e308f0ae6e4c7bd09cd943c454e3e1d', + }, + 'adapters': { + "vscode-javac": { + "name": "vscode-javac", + "type": "vscode-javac", + "command": [ + "${gadgetDir}/java-language-server/dist/debug_adapter_mac.sh" + ], + "attach": { + "pidSelect": "none" + } + } + }, + }, + 'tclpro': { + 'language': 'tcl', + 'repo': { + 'url': 'https://github.com/puremourning/TclProDebug', + 'ref': 'master' + }, + 'do': lambda name, root, gadget: installer.InstallTclProDebug( name, + root, + gadget ), + 'adapters': { + "tclpro": { + "name": "tclpro", + "type": "tclpro", + "command": [ + "${gadgetDir}/tclpro/bin/debugadapter" + ], + "attach": { + "pidSelect": "none" + }, + "configuration": { + "target": "${file}", + "args": [ "*${args}" ], + "tclsh": "tclsh", + "cwd": "${workspaceRoot}", + "extensionDirs": [ + "${workspaceRoot}/.tclpro/extensions", + "${HOME}/.tclpro/extensions", + ] + } + } + }, + }, + 'netcoredbg': { + 'language': 'csharp', + 'enabled': False, + 'download': { + 'url': 'https://github.com/Samsung/netcoredbg/releases/download/latest/' + '${file_name}', + 'format': 'tar', + }, + 'all': { + 'version': 'master' + }, + 'macos': { + 'file_name': 'netcoredbg-osx-master.tar.gz', + 'checksum': + 'c1dc6ed58c3f5b0473cfb4985a96552999360ceb9795e42d9c9be64af054f821', + }, + 'linux': { + 'file_name': 'netcoredbg-linux-master.tar.gz', + 'checksum': '', + }, + 'windows': { + 'file_name': 'netcoredbg-win64-master.zip', + 'checksum': '', + }, + 'do': lambda name, root, gadget: installer.MakeSymlink( + name, + os.path.join( root, 'netcoredbg' ) ), + 'adapters': { + 'netcoredbg': { + "name": "netcoredbg", + "command": [ + "${gadgetDir}/netcoredbg/netcoredbg", + "--interpreter=vscode" + ], + "attach": { + "pidProperty": "processId", + "pidSelect": "ask" + }, + }, + } + }, + 'vscode-mono-debug': { + 'language': 'csharp', + 'enabled': False, + 'download': { + 'url': 'https://marketplace.visualstudio.com/_apis/public/gallery/' + 'publishers/ms-vscode/vsextensions/mono-debug/${version}/' + 'vspackage', + 'target': 'vscode-mono-debug.vsix.gz', + 'format': 'zip.gz', + }, + 'all': { + 'file_name': 'vscode-mono-debug.vsix', + 'version': '0.15.8', + 'checksum': + '723eb2b621b99d65a24f215cb64b45f5fe694105613a900a03c859a62a810470', + }, + 'adapters': { + 'vscode-mono-debug': { + "name": "mono-debug", + "command": [ + "mono", + "${gadgetDir}/vscode-mono-debug/bin/Release/mono-debug.exe" + ], + "attach": { + "pidSelect": "none" + }, + }, + } + }, + 'vscode-bash-debug': { + 'language': 'bash', + 'download': { + 'url': 'https://github.com/rogalmic/vscode-bash-debug/releases/' + 'download/${version}/${file_name}', + }, + 'all': { + 'file_name': 'bash-debug-0.3.7.vsix', + 'version': 'v0.3.7', + 'checksum': + '7b73e5b4604375df8658fb5a72c645c355785a289aa785a986e508342c014bb4', + }, + 'do': lambda name, root, gadget: installer.InstallBashDebug( name, + root, + gadget ), + 'adapters': { + "vscode-bash": { + "name": "bashdb", + "command": [ + "node", + "${gadgetDir}/vscode-bash-debug/out/bashDebug.js" + ], + "variables": { + "BASHDB_HOME": "${gadgetDir}/vscode-bash-debug/bashdb_dir" + }, + "configuration": { + "request": "launch", + "type": "bashdb", + "program": "${file}", + "args": [], + "env": {}, + "pathBash": "bash", + "pathBashdb": "${BASHDB_HOME}/bashdb", + "pathBashdbLib": "${BASHDB_HOME}", + "pathCat": "cat", + "pathMkfifo": "mkfifo", + "pathPkill": "pkill", + "cwd": "${workspaceRoot}", + "terminalKind": "integrated", + } + } + } + }, + 'vscode-go': { + 'language': 'go', + 'download': { + 'url': 'https://github.com/microsoft/vscode-go/releases/download/' + '${version}/${file_name}' + }, + 'all': { + 'version': '0.11.4', + 'file_name': 'Go-0.11.4.vsix', + 'checksum': + 'ff7d7b944da5448974cb3a0086f4a2fd48e2086742d9c013d6964283d416027e' + }, + 'adapters': { + 'vscode-go': { + 'name': 'delve', + 'command': [ + 'node', + '${gadgetDir}/vscode-go/out/src/debugAdapter/goDebug.js' + ], + }, + }, + }, + 'vscode-php-debug': { + 'language': 'php', + 'enabled': False, + 'download': { + 'url': + 'https://github.com/felixfbecker/vscode-php-debug/releases/download/' + '${version}/${file_name}', + }, + 'all': { + 'version': 'v1.13.0', + 'file_name': 'php-debug.vsix', + 'checksum': + '8a51e593458fd14623c1c89ebab87347b087d67087717f18bcf77bb788052718', + }, + 'adapters': { + 'vscode-php-debug': { + 'name': "php-debug", + 'command': [ + 'node', + "${gadgetDir}/vscode-php-debug/out/phpDebug.js", + ] + } + } + }, + 'vscode-node-debug2': { + 'language': 'node', + 'enabled': False, + 'repo': { + 'url': 'https://github.com/microsoft/vscode-node-debug2', + 'ref': 'v1.42.0', + }, + 'do': lambda name, root, gadget: installer.InstallNodeDebug( name, + root, + gadget ), + 'adapters': { + 'vscode-node': { + 'name': 'node2', + 'type': 'node2', + 'command': [ + 'node', + '${gadgetDir}/vscode-node-debug2/out/src/nodeDebug.js' + ] + }, + }, + }, + 'debugger-for-chrome': { + 'language': 'chrome', + 'enabled': False, + 'download': { + 'url': 'https://marketplace.visualstudio.com/_apis/public/gallery/' + 'publishers/msjsdiag/vsextensions/' + 'debugger-for-chrome/${version}/vspackage', + 'target': 'msjsdiag.debugger-for-chrome-4.12.0.vsix.gz', + 'format': 'zip.gz', + }, + 'all': { + 'version': '4.12.0', + 'file_name': 'msjsdiag.debugger-for-chrome-4.12.0.vsix', + 'checksum': + '0df2fe96d059a002ebb0936b0003e6569e5a5c35260dc3791e1657d27d82ccf5' + }, + 'adapters': { + 'chrome': { + 'name': 'debugger-for-chrome', + 'type': 'chrome', + 'command': [ + 'node', + '${gadgetDir}/debugger-for-chrome/out/src/chromeDebug.js' + ], + }, + }, + }, + 'CodeLLDB': { + 'language': 'rust', + 'enabled': False, + 'download': { + 'url': 'https://github.com/vadimcn/vscode-lldb/releases/download/' + '${version}/${file_name}', + }, + 'all': { + 'version': 'v1.5.3', + }, + 'macos': { + 'file_name': 'codelldb-x86_64-darwin.vsix', + 'checksum': + '7505bc1cdfcfd1cb981e2996aec62d63577440709bac31dcadb41a3b4b44631a', + 'make_executable': [ + 'adapter/codelldb', + 'lldb/bin/debugserver', + 'lldb/bin/lldb', + 'lldb/bin/lldb-argdumper', + ], + }, + 'linux': { + 'file_name': 'codelldb-x86_64-linux.vsix', + 'checksum': + 'ce7efc3e94d775368e5942a02bf5c326b6809a0b4c389f79ffa6a8f6f6b72139', + 'make_executable': [ + 'adapter/codelldb', + 'lldb/bin/lldb', + 'lldb/bin/lldb-server', + 'lldb/bin/lldb-argdumper', + ], + }, + 'windows': { + 'file_name': 'codelldb-x86_64-windows.vsix', + 'checksum': + '', + 'make_executable': [] + }, + 'adapters': { + 'CodeLLDB': { + 'name': 'CodeLLDB', + 'type': 'CodeLLDB', + "command": [ + "${gadgetDir}/CodeLLDB/adapter/codelldb", + "--port", "${unusedLocalPort}" + ], + "port": "${unusedLocalPort}", + "configuration": { + "type": "lldb", + "name": "lldb", + "cargo": {}, + "args": [], + "cwd": "${workspaceRoot}", + "env": {}, + "terminal": "integrated", + } + }, + }, + }, +} diff --git a/python3/vimspector/installer.py b/python3/vimspector/installer.py index 1afea27..c767aa5 100644 --- a/python3/vimspector/installer.py +++ b/python3/vimspector/installer.py @@ -16,22 +16,195 @@ # limitations under the License. from urllib import request -import io import contextlib -import zipfile -import gzip -import shutil -import tarfile -import hashlib -import time -import ssl -import subprocess import functools +import gzip +import hashlib +import io import os +import shutil +import ssl +import string +import subprocess import sys +import tarfile +import time +import traceback +import zipfile +import json from vimspector import install +class Options: + vimspector_base = None + no_check_certificate = False + + +options = Options() + + +def Configure( **kwargs ): + for k, v in kwargs.items(): + setattr( options, k, v ) + + +def InstallGeneric( name, root, gadget ): + extension = os.path.join( root, 'extension' ) + for f in gadget.get( 'make_executable', [] ): + MakeExecutable( os.path.join( extension, f ) ) + + MakeExtensionSymlink( name, root ) + + +def InstallCppTools( name, root, gadget ): + extension = os.path.join( root, 'extension' ) + + # It's hilarious, but the execute bits aren't set in the vsix. So they + # actually have javascript code which does this. It's just a horrible horrible + # hack that really is not funny. + MakeExecutable( os.path.join( extension, 'debugAdapters', 'OpenDebugAD7' ) ) + with open( os.path.join( extension, 'package.json' ) ) as f: + package = json.load( f ) + runtime_dependencies = package[ 'runtimeDependencies' ] + for dependency in runtime_dependencies: + for binary in dependency.get( 'binaries' ): + file_path = os.path.abspath( os.path.join( extension, binary ) ) + if os.path.exists( file_path ): + MakeExecutable( os.path.join( extension, binary ) ) + + MakeExtensionSymlink( name, root ) + + +def InstallBashDebug( name, root, gadget ): + MakeExecutable( os.path.join( root, + 'extension', + 'bashdb_dir', + 'bashdb' ) ) + MakeExtensionSymlink( name, root ) + + +def InstallDebugpy( name, root, gadget ): + wd = os.getcwd() + root = os.path.join( root, 'debugpy-{}'.format( gadget[ 'version' ] ) ) + os.chdir( root ) + try: + subprocess.check_call( [ sys.executable, 'setup.py', 'build' ] ) + finally: + os.chdir( wd ) + + MakeSymlink( name, root ) + + +def InstallTclProDebug( name, root, gadget ): + configure = [ './configure' ] + + if install.GetOS() == 'macos': + # Apple removed the headers from system frameworks because they are + # determined to make life difficult. And the TCL configure scripts are super + # old so don't know about this. So we do their job for them and try and find + # a tclConfig.sh. + # + # NOTE however that in Apple's infinite wisdom, installing the "headers" in + # the other location is actually broken because the paths in the + # tclConfig.sh are pointing at the _old_ location. You actually do have to + # run the package installation which puts the headers back in order to work. + # This is why the below list is does not contain stuff from + # /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform + # '/Applications/Xcode.app/Contents/Developer/Platforms' + # '/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System' + # '/Library/Frameworks/Tcl.framework', + # '/Applications/Xcode.app/Contents/Developer/Platforms' + # '/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System' + # '/Library/Frameworks/Tcl.framework/Versions' + # '/Current', + for p in [ '/usr/local/opt/tcl-tk/lib' ]: + if os.path.exists( os.path.join( p, 'tclConfig.sh' ) ): + configure.append( '--with-tcl=' + p ) + break + + + with CurrentWorkingDir( os.path.join( root, 'lib', 'tclparser' ) ): + subprocess.check_call( configure ) + subprocess.check_call( [ 'make' ] ) + + MakeSymlink( name, root ) + + +def InstallNodeDebug( name, root, gadget ): + node_version = subprocess.check_output( [ 'node', '--version' ], + universal_newlines=True ).strip() + print( "Node.js version: {}".format( node_version ) ) + if list( map( int, node_version[ 1: ].split( '.' ) ) ) >= [ 12, 0, 0 ]: + print( "Can't install vscode-debug-node2:" ) + print( "Sorry, you appear to be running node 12 or later. That's not " + "compatible with the build system for this extension, and as far as " + "we know, there isn't a pre-built independent package." ) + print( "My advice is to install nvm, then do:" ) + print( " $ nvm install --lts 10" ) + print( " $ nvm use --lts 10" ) + print( " $ ./install_gadget.py --enable-node ..." ) + raise RuntimeError( 'Invalid node environent for node debugger' ) + + with CurrentWorkingDir( root ): + subprocess.check_call( [ 'npm', 'install' ] ) + subprocess.check_call( [ 'npm', 'run', 'build' ] ) + MakeSymlink( name, root ) + + +def InstallGagdet( name, gadget, failed, all_adapters ): + try: + v = {} + v.update( gadget.get( 'all', {} ) ) + v.update( gadget.get( install.GetOS(), {} ) ) + + if 'download' in gadget: + if 'file_name' not in v: + raise RuntimeError( "Unsupported OS {} for gadget {}".format( + install.GetOS(), + name ) ) + + destination = os.path.join( _GetGadgetDir(), + 'download', + name, v[ 'version' ] ) + + url = string.Template( gadget[ 'download' ][ 'url' ] ).substitute( v ) + + file_path = DownloadFileTo( + url, + destination, + file_name = gadget[ 'download' ].get( 'target' ), + checksum = v.get( 'checksum' ), + check_certificate = not options.no_check_certificate ) + + root = os.path.join( destination, 'root' ) + ExtractZipTo( + file_path, + root, + format = gadget[ 'download' ].get( 'format', 'zip' ) ) + elif 'repo' in gadget: + url = string.Template( gadget[ 'repo' ][ 'url' ] ).substitute( v ) + ref = string.Template( gadget[ 'repo' ][ 'ref' ] ).substitute( v ) + + destination = os.path.join( _GetGadgetDir(), 'download', name ) + CloneRepoTo( url, ref, destination ) + root = destination + + if 'do' in gadget: + gadget[ 'do' ]( name, root, v ) + else: + InstallGeneric( name, root, v ) + + # Allow per-OS adapter overrides. v already did that for us... + all_adapters.update( v.get( 'adapters', {} ) ) + # Add any other "all" adapters + all_adapters.update( gadget.get( 'adapters', {} ) ) + + print( "Done installing {}".format( name ) ) + except Exception as e: + traceback.print_exc() + failed.append( name ) + print( "FAILED installing {}: {}".format( name, e ) ) + @contextlib.contextmanager def CurrentWorkingDir( d ): @@ -212,14 +385,18 @@ def ExtractZipTo( file_path, destination, format ): subprocess.check_call( [ 'tar', 'zxvf', file_path ] ) -def MakeExtensionSymlink( vimspector_base, name, root ): - MakeSymlink( install.GetGadgetDir( vimspector_base, - install.GetOS() ), - name, - os.path.join( root, 'extension' ) ), +def _GetGadgetDir(): + return install.GetGadgetDir( options.vimspector_base, install.GetOS() ) -def MakeSymlink( in_folder, link, pointing_to ): +def MakeExtensionSymlink( name, root ): + MakeSymlink( name, os.path.join( root, 'extension' ) ), + + +def MakeSymlink( link, pointing_to, in_folder = None ): + if not in_folder: + in_folder = _GetGadgetDir() + RemoveIfExists( os.path.join( in_folder, link ) ) in_folder = os.path.abspath( in_folder )