Skip to content

Commit 149cfba

Browse files
authored
V3.2.5 release (#1334)
CMX/CM: V3.2.5 release - CMX: improved logging - CMX: improved error handling (show module path and line number) - CMX: fixed bug when detecting unknown control flag - CMX: do not change output to json if -j or --json just print json in the end ...
2 parents f75478e + ce4738a commit 149cfba

File tree

3 files changed

+71
-13
lines changed

3 files changed

+71
-13
lines changed

cm/CHANGES.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1-
## V3.2.4
1+
## V3.2.5
22
- CMX: improved logging
33
- CMX: improved error handling (show module path and line number)
4+
- CMX: fixed bug when detecting unknown control flag
5+
- CMX: do not change output to json if -j or --json
6+
just print json in the end ...
47

58
## V3.2.3
69
- added --new_branch to `cm pull repo` and `cm checkout repo`

cm/cmind/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
#
33
# Written by Grigori Fursin
44

5-
__version__ = "3.2.4"
5+
__version__ = "3.2.5"
66

77
from cmind.core import access
88
from cmind.core import x

cm/cmind/core.py

Lines changed: 66 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -616,7 +616,7 @@ def access(self, i, out = None):
616616
if automation=='':
617617
return {'return':4, 'error':'automation was not specified'}
618618
else:
619-
return {'return':4, 'error':'automation {} not found'.format(automation)}
619+
return {'return':4, 'error':'automation "{}" not found'.format(automation)}
620620

621621
# If no automation was found or we force common automation
622622
if use_common_automation or len(automation_lst)==0:
@@ -842,19 +842,30 @@ def x(self, i, out = None):
842842
'h', 'help', 'version', 'out', 'j', 'json',
843843
'save_to_json_file', 'save_to_yaml_file', 'common',
844844
'ignore_inheritance', 'log', 'logfile', 'raise', 'repro',
845-
'f']]
845+
'f', 'time', 'profile']]
846846

847+
delayed_error = ''
848+
847849
if len(unknown_control_flags)>0:
848850
unknown_control_flags_str = ','.join(unknown_control_flags)
849851

850-
print (f'Unknown control flag(s): {unknown_control_flags_str}')
851-
print ('')
852+
delayed_error = f'Unknown control flag(s): {unknown_control_flags_str}'
853+
852854
# Force print help
853855
control['h'] = True
854856

855857
if control.pop('f', ''):
856858
i['f'] = True
857859

860+
output_json = (control.get('j', False) or control.get('json', False))
861+
862+
self_time = control.get('time', False)
863+
if not x_was_called and self_time:
864+
import time
865+
self_time1 = time.time()
866+
867+
self_profile = control.get('profile', False)
868+
858869
# Check repro
859870
use_log = str(control_flags.pop('log', '')).strip().lower()
860871
log_file = control_flags.pop('logfile', '')
@@ -928,18 +939,48 @@ def x(self, i, out = None):
928939
self.log(f"x input: {spaces} ({i})", "debug")
929940

930941
# Call access helper
942+
if not x_was_called and self_profile:
943+
# https://docs.python.org/3/library/profile.html#module-cProfile
944+
import cProfile, pstats, io
945+
from pstats import SortKey
946+
profile = cProfile.Profile()
947+
profile.enable()
948+
931949
r = self._x(i, control)
932-
950+
951+
if delayed_error != '' and r['return'] == 0:
952+
r['return'] = 1
953+
r['error'] = delayed_error
954+
933955
if not self.logger == None:
934956
self.log(f"x output: {r}", "debug")
935957

936958
self.state['recursion'] = recursion
937959

938960
if not x_was_called:
961+
if self_profile:
962+
profile.disable()
963+
s = io.StringIO()
964+
sortby = SortKey.CUMULATIVE
965+
ps = pstats.Stats(profile, stream=s).sort_stats(sortby)
966+
ps.print_stats(32)
967+
print ('')
968+
print ('CMX profile:')
969+
print ('')
970+
print (s.getvalue())
971+
939972
# Very first call (not recursive)
940973
# Check if output to json and save file
941974

942-
if self.output == 'json':
975+
if self_time:
976+
self_time = time.time() - self_time1
977+
r['self_time'] = self_time
978+
979+
if self.output == 'con':
980+
print ('')
981+
print ('CMX elapsed time: {:.3f} sec.'.format(self_time))
982+
983+
if output_json:
943984
utils.dump_safe_json(r)
944985

945986
# Restore directory of call
@@ -975,9 +1016,10 @@ def _x(self, i, control):
9751016
if output == True:
9761017
output = 'con'
9771018

978-
# Check and force json console output
979-
if control.get('j', False) or control.get('json', False):
980-
output = 'json'
1019+
# Changed in v3.2.5
1020+
# # Check and force json console output
1021+
# if control.get('j', False) or control.get('json', False):
1022+
# output = 'json'
9811023

9821024
# Set self.output to the output of the very first access
9831025
# to print error in the end if needed
@@ -1011,6 +1053,17 @@ def _x(self, i, control):
10111053
elif action == 'init' and automation == '':
10121054
automation = 'core'
10131055

1056+
# Can add popular shortcuts
1057+
elif action == 'ff':
1058+
task = ''
1059+
if automation != '' and (' ' in automation or ',' in automation):
1060+
task = automation
1061+
if ' ' in automation: task = automation.replace(' ',',')
1062+
i['task'] = task
1063+
automation = 'flex.flow'
1064+
action = 'run'
1065+
i['automation'] = automation
1066+
i['action'] = action
10141067

10151068
# Print basic help if action == ''
10161069
extra_help = True if action == 'help' and automation == '' else False
@@ -1038,6 +1091,8 @@ def _x(self, i, control):
10381091
print (' -log={info (default) | debug | warning | error} - log level')
10391092
print (' -logfile={path to log file} - record log to file instead of console')
10401093
print (' -raise - raise Python error when automation action fails')
1094+
print (' -time - print elapsed time for a given automation')
1095+
print (' -profile - profile a given automation')
10411096
print (' -repro - record various info to the cmx-repro directory to replay CMX command')
10421097
print ('')
10431098
print ('Check https://github.com/mlcommons/ck/tree/master/cm/docs/cmx for more details.')
@@ -1211,7 +1266,7 @@ def _x(self, i, control):
12111266
return {'return':4, 'error':'automation meta not found in {}'.format(automation_path)}
12121267

12131268
# Load artifact class
1214-
r=utils.load_yaml_and_json(automation_path_meta)
1269+
r = utils.load_yaml_and_json(automation_path_meta)
12151270
if r['return']>0: return r
12161271

12171272
automation_meta = r['meta']
@@ -1250,7 +1305,7 @@ def _x(self, i, control):
12501305
if automation=='':
12511306
return {'return':4, 'error':'automation was not specified'}
12521307
else:
1253-
return {'return':4, 'error':f'automation {automation} not found'}
1308+
return {'return':4, 'error':f'automation "{automation}" not found'}
12541309

12551310
# If no automation was found or we force common automation
12561311
loaded_common_automation = False

0 commit comments

Comments
 (0)