Skip to content

Commit c6989fa

Browse files
committed
Install: Add hooks functions
1 parent 3e0895a commit c6989fa

2 files changed

Lines changed: 224 additions & 0 deletions

File tree

Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
function success = execute(hook_name, spec, logger)
2+
% Execute platform-specific hooks from spec.json
3+
%
4+
% Parameters:
5+
% hook_name (string): Name of the hook to execute ('pre_install', 'post_install', 'environment_setup')
6+
% spec (struct): Specification structure from spec.json
7+
% logger (struct): Logger instance
8+
%
9+
% Returns:
10+
% success (logical): True if all hook commands succeeded
11+
12+
success = true;
13+
14+
% Check if hooks section exists
15+
if ~isfield(spec, 'hooks')
16+
logger.debug('No hooks section found in spec');
17+
return;
18+
end
19+
20+
% Check if specific hook exists
21+
if ~isfield(spec.hooks, hook_name)
22+
logger.debug('Hook "%s" not found in spec.hooks', hook_name);
23+
return;
24+
end
25+
26+
% Determine platform
27+
platform = mhkit.sys.get_platform();
28+
hook_section = spec.hooks.(hook_name);
29+
30+
logger.info('Executing %s hooks for platform "%s"...', hook_name, platform);
31+
32+
% Execute environment variables first
33+
if isfield(hook_section, 'environment_variables')
34+
success = execute_environment_variables(hook_section.environment_variables, platform, spec, logger);
35+
if ~success
36+
logger.error('Environment variable setup failed');
37+
return;
38+
end
39+
end
40+
41+
% Execute commands
42+
if isfield(hook_section, 'commands')
43+
success = execute_commands(hook_section.commands, platform, spec, logger);
44+
if ~success
45+
logger.error('Command execution failed');
46+
return;
47+
end
48+
end
49+
50+
logger.info('Successfully completed %s hooks for platform "%s"', hook_name, platform);
51+
end
52+
53+
function success = execute_environment_variables(env_vars_section, platform, spec, logger)
54+
% Execute environment variable setup for a platform
55+
%
56+
% Parameters:
57+
% env_vars_section (struct): Environment variables section from spec
58+
% platform (string): Target platform
59+
% spec (struct): Specification structure
60+
% logger (struct): Logger instance
61+
%
62+
% Returns:
63+
% success (logical): True if all environment variables were set
64+
65+
success = true;
66+
67+
% Check if platform-specific environment variables exist
68+
if ~isfield(env_vars_section, platform)
69+
logger.debug('No environment variables found for platform "%s"', platform);
70+
return;
71+
end
72+
73+
platform_env_vars = env_vars_section.(platform);
74+
75+
% Skip if empty
76+
if isempty(platform_env_vars) || (isstruct(platform_env_vars) && isempty(fieldnames(platform_env_vars)))
77+
logger.debug('No environment variables to set for platform "%s"', platform);
78+
return;
79+
end
80+
81+
% Set each environment variable
82+
var_names = fieldnames(platform_env_vars);
83+
for i = 1:length(var_names)
84+
var_name = var_names{i};
85+
var_value = platform_env_vars.(var_name);
86+
87+
% Perform variable substitution
88+
processed_value = substitute_variables(var_value, spec);
89+
90+
logger.debug('Setting environment variable: %s=%s', var_name, processed_value);
91+
92+
try
93+
setenv(var_name, processed_value);
94+
logger.info('Set environment variable: %s=%s', var_name, processed_value);
95+
catch ME
96+
logger.error('Failed to set environment variable %s: %s', var_name, ME.message);
97+
success = false;
98+
return;
99+
end
100+
end
101+
end
102+
103+
function success = execute_commands(commands_section, platform, spec, logger)
104+
% Execute shell commands for a platform
105+
%
106+
% Parameters:
107+
% commands_section (struct): Commands section from spec
108+
% platform (string): Target platform
109+
% spec (struct): Specification structure
110+
% logger (struct): Logger instance
111+
%
112+
% Returns:
113+
% success (logical): True if all commands succeeded
114+
115+
success = true;
116+
117+
% Check if platform-specific commands exist
118+
if ~isfield(commands_section, platform)
119+
logger.debug('No commands found for platform "%s"', platform);
120+
return;
121+
end
122+
123+
platform_commands = commands_section.(platform);
124+
125+
% Skip if empty
126+
if isempty(platform_commands)
127+
logger.debug('No commands to execute for platform "%s"', platform);
128+
return;
129+
end
130+
131+
% Execute each command
132+
for i = 1:length(platform_commands)
133+
command = platform_commands{i};
134+
success = execute_single_command(command, spec, logger);
135+
if ~success
136+
logger.error('Command failed: %s', command);
137+
return;
138+
end
139+
end
140+
end
141+
142+
function success = execute_single_command(command, spec, logger)
143+
% Execute a single command with variable substitution
144+
%
145+
% Parameters:
146+
% command (string): Command to execute
147+
% spec (struct): Specification structure for variable substitution
148+
% logger (struct): Logger instance
149+
%
150+
% Returns:
151+
% success (logical): True if command succeeded
152+
153+
% Perform variable substitution
154+
processed_command = substitute_variables(command, spec);
155+
156+
logger.debug('Executing command: %s', processed_command);
157+
158+
% Execute command
159+
[status, result] = mhkit.sys(processed_command);
160+
161+
if status == 0
162+
logger.debug('Command succeeded: %s', processed_command);
163+
success = true;
164+
else
165+
logger.error('Command failed with status %d: %s', status, processed_command);
166+
if ~isempty(result)
167+
logger.error('Error output: %s', result);
168+
end
169+
success = false;
170+
end
171+
end
172+
173+
function result = substitute_variables(text, spec)
174+
% Substitute variables in text using spec values
175+
%
176+
% Parameters:
177+
% text (string): Text with variables to substitute
178+
% spec (struct): Specification structure
179+
%
180+
% Returns:
181+
% result (string): Text with variables substituted
182+
183+
result = text;
184+
185+
% Standard substitutions
186+
if contains(result, '<conda_env>')
187+
result = strrep(result, '<conda_env>', spec.conda.environment_name);
188+
end
189+
190+
if contains(result, '<python_version>')
191+
result = strrep(result, '<python_version>', spec.python.install_version);
192+
end
193+
194+
if contains(result, '<mhkit_python_version>')
195+
result = strrep(result, '<mhkit_python_version>', spec.mhkit_python.version);
196+
end
197+
198+
% Platform-specific substitutions
199+
if contains(result, '<conda_lib_path>')
200+
% Get conda library path dynamically
201+
conda_env = spec.conda.environment_name;
202+
[status, conda_info] = mhkit.sys(sprintf('conda run -n %s python -c "import sys; import os; print(os.path.join(os.path.dirname(sys.executable), ''lib''))"', conda_env));
203+
if status == 0
204+
conda_lib_path = strtrim(conda_info);
205+
result = strrep(result, '<conda_lib_path>', conda_lib_path);
206+
end
207+
end
208+
end
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
function platform = get_platform()
2+
% Get platform string for hook execution
3+
%
4+
% Returns:
5+
% platform (string): Platform identifier ('windows', 'linux', 'mac')
6+
7+
if ispc
8+
platform = 'windows';
9+
elseif ismac
10+
platform = 'mac';
11+
elseif isunix
12+
platform = 'linux';
13+
else
14+
platform = 'unknown';
15+
end
16+
end

0 commit comments

Comments
 (0)