Merge pull request #218 from puremourning/installer-upgrade
Upgrade gadgets when they change
This commit is contained in:
commit
db2288c6ed
5 changed files with 162 additions and 70 deletions
|
|
@ -69,6 +69,10 @@ parser.add_argument( '--force-all',
|
||||||
action = 'store_true',
|
action = 'store_true',
|
||||||
help = 'Enable all unsupported completers' )
|
help = 'Enable all unsupported completers' )
|
||||||
|
|
||||||
|
parser.add_argument( '--upgrade',
|
||||||
|
action = 'store_true',
|
||||||
|
help = 'Only update adapters changed from the manifest' )
|
||||||
|
|
||||||
parser.add_argument( '--quiet',
|
parser.add_argument( '--quiet',
|
||||||
action = 'store_true',
|
action = 'store_true',
|
||||||
help = 'Suppress installation output' )
|
help = 'Suppress installation output' )
|
||||||
|
|
@ -175,6 +179,7 @@ failed = []
|
||||||
succeeded = []
|
succeeded = []
|
||||||
all_adapters = installer.ReadAdapters(
|
all_adapters = installer.ReadAdapters(
|
||||||
read_existing = args.update_gadget_config )
|
read_existing = args.update_gadget_config )
|
||||||
|
manifest = installer.Manifest()
|
||||||
|
|
||||||
for name, gadget in gadgets.GADGETS.items():
|
for name, gadget in gadgets.GADGETS.items():
|
||||||
if not gadget.get( 'enabled', True ):
|
if not gadget.get( 'enabled', True ):
|
||||||
|
|
@ -187,15 +192,27 @@ for name, gadget in gadgets.GADGETS.items():
|
||||||
if getattr( args, 'disable_' + gadget[ 'language' ] ):
|
if getattr( args, 'disable_' + gadget[ 'language' ] ):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
if not args.upgrade:
|
||||||
|
manifest.Clear( name )
|
||||||
|
|
||||||
installer.InstallGagdet( name,
|
installer.InstallGagdet( name,
|
||||||
gadget,
|
gadget,
|
||||||
|
manifest,
|
||||||
succeeded,
|
succeeded,
|
||||||
failed,
|
failed,
|
||||||
all_adapters )
|
all_adapters )
|
||||||
|
|
||||||
|
|
||||||
for name, gadget in CUSTOM_GADGETS.items():
|
for name, gadget in CUSTOM_GADGETS.items():
|
||||||
installer.InstallGagdet( name, gadget, succeeded, failed, all_adapters )
|
if not args.upgrade:
|
||||||
|
manifest.Clear( name )
|
||||||
|
|
||||||
|
installer.InstallGagdet( name,
|
||||||
|
gadget,
|
||||||
|
manifest,
|
||||||
|
succeeded,
|
||||||
|
failed,
|
||||||
|
all_adapters )
|
||||||
|
|
||||||
if args.no_gadget_config:
|
if args.no_gadget_config:
|
||||||
print( "" )
|
print( "" )
|
||||||
|
|
@ -204,6 +221,8 @@ if args.no_gadget_config:
|
||||||
else:
|
else:
|
||||||
installer.WriteAdapters( all_adapters )
|
installer.WriteAdapters( all_adapters )
|
||||||
|
|
||||||
|
manifest.Write()
|
||||||
|
|
||||||
if args.basedir:
|
if args.basedir:
|
||||||
print( "" )
|
print( "" )
|
||||||
print( "***NOTE***: You set --basedir to " + args.basedir +
|
print( "***NOTE***: You set --basedir to " + args.basedir +
|
||||||
|
|
|
||||||
|
|
@ -234,8 +234,7 @@ GADGETS = {
|
||||||
},
|
},
|
||||||
'macos': {
|
'macos': {
|
||||||
'file_name': 'netcoredbg-osx-master.tar.gz',
|
'file_name': 'netcoredbg-osx-master.tar.gz',
|
||||||
'checksum':
|
'checksum': '',
|
||||||
'c1dc6ed58c3f5b0473cfb4985a96552999360ceb9795e42d9c9be64af054f821',
|
|
||||||
},
|
},
|
||||||
'linux': {
|
'linux': {
|
||||||
'file_name': 'netcoredbg-linux-master.tar.gz',
|
'file_name': 'netcoredbg-linux-master.tar.gz',
|
||||||
|
|
@ -385,7 +384,7 @@ GADGETS = {
|
||||||
'enabled': False,
|
'enabled': False,
|
||||||
'repo': {
|
'repo': {
|
||||||
'url': 'https://github.com/microsoft/vscode-node-debug2',
|
'url': 'https://github.com/microsoft/vscode-node-debug2',
|
||||||
'ref': 'v1.42.0',
|
'ref': 'v1.42.5'
|
||||||
},
|
},
|
||||||
'do': lambda name, root, gadget: installer.InstallNodeDebug( name,
|
'do': lambda name, root, gadget: installer.InstallNodeDebug( name,
|
||||||
root,
|
root,
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,11 @@ def GetGadgetDir( vimspector_base ):
|
||||||
return os.path.join( os.path.abspath( vimspector_base ), 'gadgets', GetOS() )
|
return os.path.join( os.path.abspath( vimspector_base ), 'gadgets', GetOS() )
|
||||||
|
|
||||||
|
|
||||||
|
def GetManifestFile( vimspector_base ):
|
||||||
|
return os.path.join( GetGadgetDir( vimspector_base ),
|
||||||
|
'.gadgets.manifest.json' )
|
||||||
|
|
||||||
|
|
||||||
def GetGadgetConfigFile( vimspector_base ):
|
def GetGadgetConfigFile( vimspector_base ):
|
||||||
return os.path.join( GetGadgetDir( vimspector_base ), '.gadgets.json' )
|
return os.path.join( GetGadgetDir( vimspector_base ), '.gadgets.json' )
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -162,6 +162,7 @@ def RunUpdate( api_prefix, leave_open, *args ):
|
||||||
insatller_args.extend( FindGadgetForAdapter( adapter_name ) )
|
insatller_args.extend( FindGadgetForAdapter( adapter_name ) )
|
||||||
|
|
||||||
if insatller_args:
|
if insatller_args:
|
||||||
|
insatller_args.append( '--upgrade' )
|
||||||
RunInstaller( api_prefix, leave_open, *insatller_args )
|
RunInstaller( api_prefix, leave_open, *insatller_args )
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -217,6 +218,91 @@ def FindGadgetForAdapter( adapter_name ):
|
||||||
return candidates
|
return candidates
|
||||||
|
|
||||||
|
|
||||||
|
class Manifest:
|
||||||
|
manifest: dict
|
||||||
|
|
||||||
|
def __init__( self ):
|
||||||
|
self.manifest = {}
|
||||||
|
self.Read()
|
||||||
|
|
||||||
|
def Read( self ):
|
||||||
|
try:
|
||||||
|
with open( install.GetManifestFile( options.vimspector_base ), 'r' ) as f:
|
||||||
|
self.manifest = json.load( f )
|
||||||
|
except OSError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def Write( self ):
|
||||||
|
with open( install.GetManifestFile( options.vimspector_base ), 'w' ) as f:
|
||||||
|
json.dump( self.manifest, f )
|
||||||
|
|
||||||
|
|
||||||
|
def Clear( self, name: str ):
|
||||||
|
try:
|
||||||
|
del self.manifest[ name ]
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def Update( self, name: str, gadget_spec: dict ):
|
||||||
|
self.manifest[ name ] = gadget_spec
|
||||||
|
|
||||||
|
|
||||||
|
def RequiresUpdate( self, name: str, gadget_spec: dict ):
|
||||||
|
try:
|
||||||
|
current_spec = self.manifest[ name ]
|
||||||
|
except KeyError:
|
||||||
|
# It's new.
|
||||||
|
return True
|
||||||
|
|
||||||
|
# If anything changed in the spec, update
|
||||||
|
if not current_spec == gadget_spec:
|
||||||
|
return True
|
||||||
|
|
||||||
|
# Always update if the version string is 'master'. Probably a git repo
|
||||||
|
# that pulls master (which tbh we shouldn't have)
|
||||||
|
if current_spec.get( 'version' ) in ( 'master', '' ):
|
||||||
|
return True
|
||||||
|
if current_spec.get( 'repo', {} ).get( 'ref' ) == 'master':
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def ReadAdapters( read_existing = True ):
|
||||||
|
all_adapters = {}
|
||||||
|
if read_existing:
|
||||||
|
try:
|
||||||
|
with open( install.GetGadgetConfigFile( options.vimspector_base ),
|
||||||
|
'r' ) as f:
|
||||||
|
all_adapters = json.load( f ).get( 'adapters', {} )
|
||||||
|
except OSError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Include "built-in" adapter for multi-session mode
|
||||||
|
all_adapters.update( {
|
||||||
|
'multi-session': {
|
||||||
|
'port': '${port}',
|
||||||
|
'host': '${host}'
|
||||||
|
},
|
||||||
|
} )
|
||||||
|
|
||||||
|
return all_adapters
|
||||||
|
|
||||||
|
|
||||||
|
def WriteAdapters( all_adapters, to_file=None ):
|
||||||
|
adapter_config = json.dumps ( { 'adapters': all_adapters },
|
||||||
|
indent=2,
|
||||||
|
sort_keys=True )
|
||||||
|
|
||||||
|
if to_file:
|
||||||
|
to_file.write( adapter_config )
|
||||||
|
else:
|
||||||
|
with open( install.GetGadgetConfigFile( options.vimspector_base ),
|
||||||
|
'w' ) as f:
|
||||||
|
f.write( adapter_config )
|
||||||
|
|
||||||
|
|
||||||
def InstallGeneric( name, root, gadget ):
|
def InstallGeneric( name, root, gadget ):
|
||||||
extension = os.path.join( root, 'extension' )
|
extension = os.path.join( root, 'extension' )
|
||||||
for f in gadget.get( 'make_executable', [] ):
|
for f in gadget.get( 'make_executable', [] ):
|
||||||
|
|
@ -300,52 +386,57 @@ def InstallTclProDebug( name, root, gadget ):
|
||||||
|
|
||||||
|
|
||||||
def InstallNodeDebug( name, root, gadget ):
|
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( 'Node 10 is required to install node debugger (sadly)' )
|
|
||||||
|
|
||||||
with CurrentWorkingDir( root ):
|
with CurrentWorkingDir( root ):
|
||||||
CheckCall( [ 'npm', 'install' ] )
|
CheckCall( [ 'npm', 'install' ] )
|
||||||
CheckCall( [ 'npm', 'run', 'build' ] )
|
CheckCall( [ 'npm', 'run', 'build' ] )
|
||||||
MakeSymlink( name, root )
|
MakeSymlink( name, root )
|
||||||
|
|
||||||
|
|
||||||
def InstallGagdet( name, gadget, succeeded, failed, all_adapters ):
|
def InstallGagdet( name: str,
|
||||||
|
gadget: dict,
|
||||||
|
manifest: Manifest,
|
||||||
|
succeeded: list,
|
||||||
|
failed: list,
|
||||||
|
all_adapters: dict ):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
print( f"Installing {name}..." )
|
# Spec is an os-specific definition of the gadget
|
||||||
v = {}
|
spec = {}
|
||||||
v.update( gadget.get( 'all', {} ) )
|
spec.update( gadget.get( 'all', {} ) )
|
||||||
v.update( gadget.get( install.GetOS(), {} ) )
|
spec.update( gadget.get( install.GetOS(), {} ) )
|
||||||
|
|
||||||
|
def save_adapters():
|
||||||
|
# allow per-os adapter overrides. v already did that for us...
|
||||||
|
all_adapters.update( spec.get( 'adapters', {} ) )
|
||||||
|
# add any other "all" adapters
|
||||||
|
all_adapters.update( gadget.get( 'adapters', {} ) )
|
||||||
|
|
||||||
if 'download' in gadget:
|
if 'download' in gadget:
|
||||||
if 'file_name' not in v:
|
if 'file_name' not in spec:
|
||||||
raise RuntimeError( "Unsupported OS {} for gadget {}".format(
|
raise RuntimeError( "Unsupported OS {} for gadget {}".format(
|
||||||
install.GetOS(),
|
install.GetOS(),
|
||||||
name ) )
|
name ) )
|
||||||
|
|
||||||
|
print( f"Installing {name}@{spec[ 'version' ]}..." )
|
||||||
|
spec[ 'download' ] = gadget[ 'download' ]
|
||||||
|
if not manifest.RequiresUpdate( name, spec ):
|
||||||
|
save_adapters()
|
||||||
|
print( " - Skip - up to date" )
|
||||||
|
return
|
||||||
|
|
||||||
destination = os.path.join(
|
destination = os.path.join(
|
||||||
install.GetGadgetDir( options.vimspector_base ),
|
install.GetGadgetDir( options.vimspector_base ),
|
||||||
'download',
|
'download',
|
||||||
name,
|
name,
|
||||||
v[ 'version' ] )
|
spec[ 'version' ] )
|
||||||
|
|
||||||
url = string.Template( gadget[ 'download' ][ 'url' ] ).substitute( v )
|
url = string.Template( gadget[ 'download' ][ 'url' ] ).substitute( spec )
|
||||||
|
|
||||||
file_path = DownloadFileTo(
|
file_path = DownloadFileTo(
|
||||||
url,
|
url,
|
||||||
destination,
|
destination,
|
||||||
file_name = gadget[ 'download' ].get( 'target' ),
|
file_name = gadget[ 'download' ].get( 'target' ),
|
||||||
checksum = v.get( 'checksum' ),
|
checksum = spec.get( 'checksum' ),
|
||||||
check_certificate = not options.no_check_certificate )
|
check_certificate = not options.no_check_certificate )
|
||||||
|
|
||||||
root = os.path.join( destination, 'root' )
|
root = os.path.join( destination, 'root' )
|
||||||
|
|
@ -354,8 +445,15 @@ def InstallGagdet( name, gadget, succeeded, failed, all_adapters ):
|
||||||
root,
|
root,
|
||||||
format = gadget[ 'download' ].get( 'format', 'zip' ) )
|
format = gadget[ 'download' ].get( 'format', 'zip' ) )
|
||||||
elif 'repo' in gadget:
|
elif 'repo' in gadget:
|
||||||
url = string.Template( gadget[ 'repo' ][ 'url' ] ).substitute( v )
|
url = string.Template( gadget[ 'repo' ][ 'url' ] ).substitute( spec )
|
||||||
ref = string.Template( gadget[ 'repo' ][ 'ref' ] ).substitute( v )
|
ref = string.Template( gadget[ 'repo' ][ 'ref' ] ).substitute( spec )
|
||||||
|
|
||||||
|
print( f"Installing {name}@{gadget[ 'repo' ][ 'ref' ]}..." )
|
||||||
|
spec[ 'repo' ] = gadget[ 'repo' ]
|
||||||
|
if not manifest.RequiresUpdate( name, spec ):
|
||||||
|
save_adapters()
|
||||||
|
print( " - Skip - up to date" )
|
||||||
|
return
|
||||||
|
|
||||||
destination = os.path.join(
|
destination = os.path.join(
|
||||||
install.GetGadgetDir( options.vimspector_base ),
|
install.GetGadgetDir( options.vimspector_base ),
|
||||||
|
|
@ -365,15 +463,12 @@ def InstallGagdet( name, gadget, succeeded, failed, all_adapters ):
|
||||||
root = destination
|
root = destination
|
||||||
|
|
||||||
if 'do' in gadget:
|
if 'do' in gadget:
|
||||||
gadget[ 'do' ]( name, root, v )
|
gadget[ 'do' ]( name, root, spec )
|
||||||
else:
|
else:
|
||||||
InstallGeneric( name, root, v )
|
InstallGeneric( name, root, spec )
|
||||||
|
|
||||||
# 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', {} ) )
|
|
||||||
|
|
||||||
|
save_adapters()
|
||||||
|
manifest.Update( name, spec )
|
||||||
succeeded.append( name )
|
succeeded.append( name )
|
||||||
print( f" - Done installing {name}" )
|
print( f" - Done installing {name}" )
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|
@ -383,40 +478,6 @@ def InstallGagdet( name, gadget, succeeded, failed, all_adapters ):
|
||||||
print( f" - FAILED installing {name}: {e}".format( name, e ) )
|
print( f" - FAILED installing {name}: {e}".format( name, e ) )
|
||||||
|
|
||||||
|
|
||||||
def ReadAdapters( read_existing = True ):
|
|
||||||
all_adapters = {}
|
|
||||||
if read_existing:
|
|
||||||
try:
|
|
||||||
with open( install.GetGadgetConfigFile( options.vimspector_base ),
|
|
||||||
'r' ) as f:
|
|
||||||
all_adapters = json.load( f ).get( 'adapters', {} )
|
|
||||||
except OSError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
# Include "built-in" adapter for multi-session mode
|
|
||||||
all_adapters.update( {
|
|
||||||
'multi-session': {
|
|
||||||
'port': '${port}',
|
|
||||||
'host': '${host}'
|
|
||||||
},
|
|
||||||
} )
|
|
||||||
|
|
||||||
return all_adapters
|
|
||||||
|
|
||||||
|
|
||||||
def WriteAdapters( all_adapters, to_file=None ):
|
|
||||||
adapter_config = json.dumps ( { 'adapters': all_adapters },
|
|
||||||
indent=2,
|
|
||||||
sort_keys=True )
|
|
||||||
|
|
||||||
if to_file:
|
|
||||||
to_file.write( adapter_config )
|
|
||||||
else:
|
|
||||||
with open( install.GetGadgetConfigFile( options.vimspector_base ),
|
|
||||||
'w' ) as f:
|
|
||||||
f.write( adapter_config )
|
|
||||||
|
|
||||||
|
|
||||||
@contextlib.contextmanager
|
@contextlib.contextmanager
|
||||||
def CurrentWorkingDir( d ):
|
def CurrentWorkingDir( d ):
|
||||||
cur_d = os.getcwd()
|
cur_d = os.getcwd()
|
||||||
|
|
|
||||||
|
|
@ -4,10 +4,18 @@ endif
|
||||||
|
|
||||||
let b:current_syntax = 'vimspector-installer'
|
let b:current_syntax = 'vimspector-installer'
|
||||||
|
|
||||||
|
syn match VimspectorGadget /[^ ]*\ze@/
|
||||||
|
syn match VimspectorGadgetVersion /@\@<=[^ ]*\ze\.\.\./
|
||||||
|
|
||||||
|
|
||||||
syn keyword VimspectorInstalling Installing
|
syn keyword VimspectorInstalling Installing
|
||||||
syn keyword VimspectorDone Done
|
syn keyword VimspectorDone Done
|
||||||
|
syn keyword VimspectorSkip Skip
|
||||||
syn keyword VimspectorError Failed FAILED
|
syn keyword VimspectorError Failed FAILED
|
||||||
|
|
||||||
hi default link VimspectorInstalling Constant
|
hi default link VimspectorInstalling Constant
|
||||||
hi default link VimspectorDone DiffAdd
|
hi default link VimspectorDone DiffAdd
|
||||||
|
hi default link VimspectorSkip DiffAdd
|
||||||
hi default link VimspectorError WarningMsg
|
hi default link VimspectorError WarningMsg
|
||||||
|
hi default link VimspectorGadget String
|
||||||
|
hi default link VimspectorGadgetVersion Identifier
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue