18
18
import keyword
19
19
import threading
20
20
from inspect import getcallargs
21
- from functools import wraps
21
+ from functools import wraps , lru_cache
22
22
23
23
# Notes for v3
24
24
#
@@ -3194,6 +3194,18 @@ def _file_watcher_callback(name, info, event):
3194
3194
3195
3195
_file_watcher = FileWatcher (_file_watcher_callback )
3196
3196
3197
+ @lru_cache (None )
3198
+ def _have_vcs (vcs ):
3199
+ try :
3200
+ subprocess .check_output ([vcs , '--version' ])
3201
+ return True
3202
+ except FileNotFoundError :
3203
+ msg = f"""Warning: Cannot run { vcs } commands, { vcs } info for labscriptlib files
3204
+ will not be saved. You can disable this warning by setting
3205
+ [labscript]/save_{ vcs } _info = False in labconfig."""
3206
+ sys .stderr .write (dedent (msg ) + '\n ' )
3207
+ return False
3208
+
3197
3209
def _run_vcs_commands (path ):
3198
3210
"""Run some VCS commands on a file and return their output.
3199
3211
@@ -3221,7 +3233,7 @@ def _run_vcs_commands(path):
3221
3233
# Gather together a list of commands to run.
3222
3234
module_directory , module_filename = os .path .split (path )
3223
3235
vcs_commands = []
3224
- if compiler .save_hg_info :
3236
+ if compiler .save_hg_info and _have_vcs ( 'hg' ) :
3225
3237
hg_commands = [
3226
3238
['log' , '--limit' , '1' ],
3227
3239
['status' ],
@@ -3230,7 +3242,7 @@ def _run_vcs_commands(path):
3230
3242
for command in hg_commands :
3231
3243
command = tuple (['hg' ] + command + [module_filename ])
3232
3244
vcs_commands .append ((command , module_directory ))
3233
- if compiler .save_git_info :
3245
+ if compiler .save_git_info and _have_vcs ( 'git' ) :
3234
3246
git_commands = [
3235
3247
['branch' , '--show-current' ],
3236
3248
['describe' , '--tags' , '--always' , 'HEAD' ],
@@ -3280,34 +3292,33 @@ def save_labscripts(hdf5_file):
3280
3292
script .attrs ['path' ] = os .path .dirname (compiler .labscript_file ).encode () if compiler .labscript_file is not None else sys .path [0 ]
3281
3293
try :
3282
3294
import labscriptlib
3283
- prefix = os .path .dirname (labscriptlib .__file__ )
3284
- for module in sys .modules .values ():
3285
- if getattr (module , '__file__' , None ) is not None :
3286
- path = os .path .abspath (module .__file__ )
3287
- if path .startswith (prefix ) and (path .endswith ('.pyc' ) or path .endswith ('.py' )):
3288
- path = path .replace ('.pyc' , '.py' )
3289
- save_path = 'labscriptlib/' + path .replace (prefix , '' ).replace ('\\ ' , '/' ).replace ('//' , '/' )
3290
- if save_path in hdf5_file :
3291
- # Don't try to save the same module script twice!
3292
- # (seems to at least double count __init__.py when you import an entire module as in from labscriptlib.stages import * where stages is a folder with an __init__.py file.
3293
- # Doesn't seem to want to double count files if you just import the contents of a file within a module
3294
- continue
3295
- hdf5_file .create_dataset (save_path , data = open (path ).read ())
3296
- with _vcs_cache_rlock :
3297
- already_cached = path in _vcs_cache
3298
- if not already_cached :
3295
+ except ImportError :
3296
+ return
3297
+ prefix = os .path .dirname (labscriptlib .__file__ )
3298
+ for module in sys .modules .values ():
3299
+ if getattr (module , '__file__' , None ) is not None :
3300
+ path = os .path .abspath (module .__file__ )
3301
+ if path .startswith (prefix ) and (path .endswith ('.pyc' ) or path .endswith ('.py' )):
3302
+ path = path .replace ('.pyc' , '.py' )
3303
+ save_path = 'labscriptlib/' + path .replace (prefix , '' ).replace ('\\ ' , '/' ).replace ('//' , '/' )
3304
+ if save_path in hdf5_file :
3305
+ # Don't try to save the same module script twice! (seems to at least
3306
+ # double count __init__.py when you import an entire module as in
3307
+ # from labscriptlib.stages import * where stages is a folder with an
3308
+ # __init__.py file. Doesn't seem to want to double count files if
3309
+ # you just import the contents of a file within a module
3310
+ continue
3311
+ hdf5_file .create_dataset (save_path , data = open (path ).read ())
3312
+ with _vcs_cache_rlock :
3313
+ if not path in _vcs_cache :
3299
3314
# Add file to watch list and create its entry in the cache.
3300
3315
_file_watcher .add_file (path )
3301
3316
_file_watcher_callback (path , None , None )
3302
- with _vcs_cache_rlock :
3303
- # Save the cached vcs output to the file.
3304
- for command , info , err in _vcs_cache [path ]:
3305
- attribute_str = command [0 ] + ' ' + command [1 ]
3306
- hdf5_file [save_path ].attrs [attribute_str ] = (info + '\n ' + err )
3307
- except ImportError :
3308
- pass
3309
- except WindowsError if os .name == 'nt' else None :
3310
- sys .stderr .write ('Warning: Cannot save version control data for imported scripts. Check that the hg and/or git command can be run from the command line.\n ' )
3317
+ # Save the cached vcs output to the file.
3318
+ for command , info , err in _vcs_cache [path ]:
3319
+ attribute_str = command [0 ] + ' ' + command [1 ]
3320
+ hdf5_file [save_path ].attrs [attribute_str ] = (info + '\n ' + err )
3321
+
3311
3322
3312
3323
3313
3324
def write_device_properties (hdf5_file ):
0 commit comments