Skip to content

Commit 427b2bf

Browse files
Better catch when vcs programs not installed.
Check if vcs commands exist before running commands. Cache the result so that the check doesn't happen for every file (if the user installs git or hg, they will need to restart runmanager or the compiler subprocess for saving of vcs info to start working). Should address labscript-suite/labscript-suite#66
1 parent f6409e0 commit 427b2bf

File tree

1 file changed

+39
-28
lines changed

1 file changed

+39
-28
lines changed

labscript/labscript.py

Lines changed: 39 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
import keyword
1919
import threading
2020
from inspect import getcallargs
21-
from functools import wraps
21+
from functools import wraps, lru_cache
2222

2323
# Notes for v3
2424
#
@@ -3194,6 +3194,18 @@ def _file_watcher_callback(name, info, event):
31943194

31953195
_file_watcher = FileWatcher(_file_watcher_callback)
31963196

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+
31973209
def _run_vcs_commands(path):
31983210
"""Run some VCS commands on a file and return their output.
31993211
@@ -3221,7 +3233,7 @@ def _run_vcs_commands(path):
32213233
# Gather together a list of commands to run.
32223234
module_directory, module_filename = os.path.split(path)
32233235
vcs_commands = []
3224-
if compiler.save_hg_info:
3236+
if compiler.save_hg_info and _have_vcs('hg'):
32253237
hg_commands = [
32263238
['log', '--limit', '1'],
32273239
['status'],
@@ -3230,7 +3242,7 @@ def _run_vcs_commands(path):
32303242
for command in hg_commands:
32313243
command = tuple(['hg'] + command + [module_filename])
32323244
vcs_commands.append((command, module_directory))
3233-
if compiler.save_git_info:
3245+
if compiler.save_git_info and _have_vcs('git'):
32343246
git_commands = [
32353247
['branch', '--show-current'],
32363248
['describe', '--tags', '--always', 'HEAD'],
@@ -3280,34 +3292,33 @@ def save_labscripts(hdf5_file):
32803292
script.attrs['path'] = os.path.dirname(compiler.labscript_file).encode() if compiler.labscript_file is not None else sys.path[0]
32813293
try:
32823294
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:
32993314
# Add file to watch list and create its entry in the cache.
33003315
_file_watcher.add_file(path)
33013316
_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+
33113322

33123323

33133324
def write_device_properties(hdf5_file):

0 commit comments

Comments
 (0)