forked from andreassommer/ifdiff
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathspeedtracker.m
More file actions
145 lines (129 loc) · 5.08 KB
/
speedtracker.m
File metadata and controls
145 lines (129 loc) · 5.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
function [result, status] = speedtracker(varargin)
% Entry point for speedtracker, which runs performance benchmarks against various previous states of the
% project, called snapshots.
%% init: set constants
[SRC_BASEDIR, ~, ~] = fileparts(mfilename('fullpath'));
SRC_ST_DIR = fullfile(SRC_BASEDIR, 'speedtracker');
OS_TEMP_DIR = tempdir();
ST_DIR = 'speedtracker_temp';
ST_TEMP_DIR = fullfile(OS_TEMP_DIR, ST_DIR);
% Ensure we are in the project root directory
oldPwd = pwd();
cd(SRC_BASEDIR);
%% setup: create temp dir and put all of Speedtracker's files there
% Ensures that speedtracker does not get messed up when a different snapshot is loaded (because its own files could
% change)
if (exist(ST_TEMP_DIR, 'dir'))
rmdir(ST_TEMP_DIR, 's');
end
copyfile(SRC_ST_DIR, ST_TEMP_DIR);
addpath(genpath(ST_TEMP_DIR));
%% to avoid clashes, ensure that the original speedtracker folder is not on the path
if (contains(path, SRC_ST_DIR))
rmpath(genpath(SRC_ST_DIR));
rehash();
end
%% Global configuration required for the business code
% The available subcommands (`speedtracker('list-snapshots')`, `speedtracker('run')`, etc.). They implement the
% interface UserCommand, which makes adding new commands easy and clean.
help = HelpCommand();
commands = {help, RunBenchmarksCommand(), ListBenchmarksCommand(), ...
CreateSnapshotCommand(), DeleteSnapshotCommand(), ListSnapshotsCommand(), ShowSnapshotCommand(), ...
RestoreStateCommand()};
config = SpeedtrackerConfig();
config.baseDir = SRC_BASEDIR;
config.speedtrackerDir = SRC_ST_DIR;
config.tempDir = ST_TEMP_DIR;
config.userCommands = commands;
config.debug = Configuration.Debug;
config.hideErrors = Configuration.HideErrors;
ConfigProvider.setSpeedtrackerConfig(config);
ConfigProvider.setUserConfig(UserConfig());
% An extra logger to log system commands in debug mode
systemLogger = makeSystemLogger();
if (config.debug)
systemLogger.level = Logger.LEVEL_DEBUG;
end
SystemUtil.setGetLogger(systemLogger);
try
% Handle args. If there are none, print the output of the HelpCommand
if nargin == 0
varargin = {help.getName()};
end
command = getCommand(commands, varargin);
commandConfig = command.handleArgs(varargin);
catch argError % can be either an unknown command or bad arguments to that command
status = 1;
helpMessage = sprintf('%s\n\nERROR: %s', help.generalHelp(), argError.message);
teardown();
if config.hideErrors
result = helpMessage;
return;
else
disp(helpMessage);
rethrow(argError);
end
end
%% Business code: execute the selected command
try
commandLogger = makeCommandLogger(command.getName());
if (config.debug)
commandLogger.level = Logger.LEVEL_DEBUG;
end
result = command.execute(commandLogger, commandConfig);
status = 0;
catch error
status = 1;
if strcmp(error.identifier, UserCommand.ERROR_EXPECTED_EXCEPTION)
helpMessage = sprintf('ERROR: %s: %s', command.getName(), error.message);
else
helpMessage = sprintf('unexpected error in %s\n\n%s', command.getName(), getReport(error));
end
teardown();
if config.hideErrors
result = helpMessage;
return;
else
disp(helpMessage);
rethrow(error);
end
end
teardown();
%% teardown
function teardown()
rmpath(genpath(ST_TEMP_DIR));
rmdir(ST_TEMP_DIR, 's');
cd(oldPwd);
rehash();
end
end
function command = getCommand(commands, argCell)
% Given a cell array of UserCommand objects and a cell array of program arguments,
% select the correct UserCommand based on the first argument.
% If the argument list is empty or the first argument does not match any command, throw an exception.
if isempty(argCell)
throw(MException('speedtracker:main', 'no inputs'));
end
arg1 = argCell{1};
command = UserCommand.getCommand(commands, arg1);
if isempty(command)
throw(MException('speedtracker:main', ['unknown command: ' StringUtil.toStr(arg1)]));
end
end
function logger = makeCommandLogger(commandName)
% Make a logger for a UserCommand.
% Prepends the command as a prefix and logs everything except debug messages.
logger = SimpleLogger(1);
logger.debugPrefix = ['DEBUG(' commandName '): '];
logger.infoPrefix = ['INFO (' commandName '): '];
logger.warnPrefix = ['WARN (' commandName '): '];
logger.errorPrefix = ['ERROR(' commandName '): '];
end
function logger = makeSystemLogger()
% Make an extra logger for the SystemUtil, which handles calls to the host OS
logger = SimpleLogger(1);
logger.debugPrefix = 'DEBUG(SystemUtil): ';
logger.infoPrefix = 'INFO (SystemUtil): ';
logger.warnPrefix = 'WARN (SystemUtil): ';
logger.errorPrefix = 'ERROR(SystemUtil): ';
end