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
#
@@ -3255,6 +3255,18 @@ def _file_watcher_callback(name, info, event):
3255
3255
3256
3256
_file_watcher = FileWatcher (_file_watcher_callback )
3257
3257
3258
+ @lru_cache (None )
3259
+ def _have_vcs (vcs ):
3260
+ try :
3261
+ subprocess .check_output ([vcs , '--version' ])
3262
+ return True
3263
+ except FileNotFoundError :
3264
+ msg = f"""Warning: Cannot run { vcs } commands, { vcs } info for labscriptlib files
3265
+ will not be saved. You can disable this warning by setting
3266
+ [labscript]/save_{ vcs } _info = False in labconfig."""
3267
+ sys .stderr .write (dedent (msg ) + '\n ' )
3268
+ return False
3269
+
3258
3270
def _run_vcs_commands (path ):
3259
3271
"""Run some VCS commands on a file and return their output.
3260
3272
@@ -3282,7 +3294,7 @@ def _run_vcs_commands(path):
3282
3294
# Gather together a list of commands to run.
3283
3295
module_directory , module_filename = os .path .split (path )
3284
3296
vcs_commands = []
3285
- if compiler .save_hg_info :
3297
+ if compiler .save_hg_info and _have_vcs ( 'hg' ) :
3286
3298
hg_commands = [
3287
3299
['log' , '--limit' , '1' ],
3288
3300
['status' ],
@@ -3291,7 +3303,7 @@ def _run_vcs_commands(path):
3291
3303
for command in hg_commands :
3292
3304
command = tuple (['hg' ] + command + [module_filename ])
3293
3305
vcs_commands .append ((command , module_directory ))
3294
- if compiler .save_git_info :
3306
+ if compiler .save_git_info and _have_vcs ( 'git' ) :
3295
3307
git_commands = [
3296
3308
['branch' , '--show-current' ],
3297
3309
['describe' , '--tags' , '--always' , 'HEAD' ],
@@ -3341,34 +3353,33 @@ def save_labscripts(hdf5_file):
3341
3353
script .attrs ['path' ] = os .path .dirname (compiler .labscript_file ).encode () if compiler .labscript_file is not None else sys .path [0 ]
3342
3354
try :
3343
3355
import labscriptlib
3344
- prefix = os .path .dirname (labscriptlib .__file__ )
3345
- for module in sys .modules .values ():
3346
- if getattr (module , '__file__' , None ) is not None :
3347
- path = os .path .abspath (module .__file__ )
3348
- if path .startswith (prefix ) and (path .endswith ('.pyc' ) or path .endswith ('.py' )):
3349
- path = path .replace ('.pyc' , '.py' )
3350
- save_path = 'labscriptlib/' + path .replace (prefix , '' ).replace ('\\ ' , '/' ).replace ('//' , '/' )
3351
- if save_path in hdf5_file :
3352
- # Don't try to save the same module script twice!
3353
- # (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.
3354
- # Doesn't seem to want to double count files if you just import the contents of a file within a module
3355
- continue
3356
- hdf5_file .create_dataset (save_path , data = open (path ).read ())
3357
- with _vcs_cache_rlock :
3358
- already_cached = path in _vcs_cache
3359
- if not already_cached :
3356
+ except ImportError :
3357
+ return
3358
+ prefix = os .path .dirname (labscriptlib .__file__ )
3359
+ for module in sys .modules .values ():
3360
+ if getattr (module , '__file__' , None ) is not None :
3361
+ path = os .path .abspath (module .__file__ )
3362
+ if path .startswith (prefix ) and (path .endswith ('.pyc' ) or path .endswith ('.py' )):
3363
+ path = path .replace ('.pyc' , '.py' )
3364
+ save_path = 'labscriptlib/' + path .replace (prefix , '' ).replace ('\\ ' , '/' ).replace ('//' , '/' )
3365
+ if save_path in hdf5_file :
3366
+ # Don't try to save the same module script twice! (seems to at least
3367
+ # double count __init__.py when you import an entire module as in
3368
+ # from labscriptlib.stages import * where stages is a folder with an
3369
+ # __init__.py file. Doesn't seem to want to double count files if
3370
+ # you just import the contents of a file within a module
3371
+ continue
3372
+ hdf5_file .create_dataset (save_path , data = open (path ).read ())
3373
+ with _vcs_cache_rlock :
3374
+ if not path in _vcs_cache :
3360
3375
# Add file to watch list and create its entry in the cache.
3361
3376
_file_watcher .add_file (path )
3362
3377
_file_watcher_callback (path , None , None )
3363
- with _vcs_cache_rlock :
3364
- # Save the cached vcs output to the file.
3365
- for command , info , err in _vcs_cache [path ]:
3366
- attribute_str = command [0 ] + ' ' + command [1 ]
3367
- hdf5_file [save_path ].attrs [attribute_str ] = (info + '\n ' + err )
3368
- except ImportError :
3369
- pass
3370
- except WindowsError if os .name == 'nt' else None :
3371
- 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 ' )
3378
+ # Save the cached vcs output to the file.
3379
+ for command , info , err in _vcs_cache [path ]:
3380
+ attribute_str = command [0 ] + ' ' + command [1 ]
3381
+ hdf5_file [save_path ].attrs [attribute_str ] = (info + '\n ' + err )
3382
+
3372
3383
3373
3384
3374
3385
def write_device_properties (hdf5_file ):
0 commit comments