Skip to content

Commit d18f130

Browse files
committed
Implemented cmd and repl in the cli completely, add also sandboxing plugin in the cmd.
1 parent 799ddb8 commit d18f130

File tree

18 files changed

+674
-114
lines changed

18 files changed

+674
-114
lines changed

source/cli/metacallcli/CMakeLists.txt

Lines changed: 35 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -211,10 +211,8 @@ add_test(NAME ${target}
211211
COMMAND ${CMAKE_COMMAND} -D "EXECUTABLE=$<TARGET_FILE:${target}>" -D "INPUT=${TEST_COMMAND_INPUT}.txt" -P ${TEST_COMMAND_RUNNER}
212212
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
213213
)
214-
set_property(TEST ${target}
215-
PROPERTY LABELS ${target}
216-
)
217214
set_tests_properties(${target} PROPERTIES
215+
LABELS ${target}
218216
PASS_REGULAR_EXPRESSION "function three_str\\(a_str, b_str, c_str\\)"
219217
)
220218
test_environment_variables(${target}
@@ -239,10 +237,8 @@ if(OPTION_BUILD_LOADERS AND OPTION_BUILD_LOADERS_NODE AND OPTION_BUILD_SCRIPTS A
239237
COMMAND ${CMAKE_COMMAND} -D "EXECUTABLE=$<TARGET_FILE:${target}>" -D "INPUT=${TEST_COMMAND_INPUT}-node.txt" -P ${TEST_COMMAND_RUNNER}
240238
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
241239
)
242-
set_property(TEST ${target}-node
243-
PROPERTY LABELS ${target}-node
244-
)
245240
set_tests_properties(${target}-node PROPERTIES
241+
LABELS ${target}-node
246242
PASS_REGULAR_EXPRESSION "4001534"
247243
)
248244
test_environment_variables(${target}-node
@@ -254,10 +250,8 @@ if(OPTION_BUILD_LOADERS AND OPTION_BUILD_LOADERS_NODE AND OPTION_BUILD_SCRIPTS A
254250
COMMAND ${CMAKE_COMMAND} -D "EXECUTABLE=$<TARGET_FILE:${target}>" -D "INPUT=${TEST_COMMAND_INPUT}-node-port-py.txt" -P ${TEST_COMMAND_RUNNER}
255251
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
256252
)
257-
set_property(TEST ${target}-node-port-py
258-
PROPERTY LABELS ${target}-node-port-py
259-
)
260253
set_tests_properties(${target}-node-port-py PROPERTIES
254+
LABELS ${target}-node-port-py
261255
PASS_REGULAR_EXPRESSION "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
262256
)
263257
test_environment_variables(${target}-node-port-py
@@ -284,10 +278,8 @@ if(OPTION_BUILD_LOADERS AND OPTION_BUILD_LOADERS_NODE AND OPTION_BUILD_SCRIPTS A
284278
COMMAND ${CMAKE_COMMAND} -D "EXECUTABLE=$<TARGET_FILE:${target}>" -D "INPUT=${TEST_COMMAND_INPUT}-node-null.txt" -P ${TEST_COMMAND_RUNNER}
285279
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
286280
)
287-
set_property(TEST ${target}-node-null
288-
PROPERTY LABELS ${target}-node-null
289-
)
290281
set_tests_properties(${target}-node-null PROPERTIES
282+
LABELS ${target}-node-null
291283
PASS_REGULAR_EXPRESSION "Hello 342521512461246!"
292284
)
293285
test_environment_variables(${target}-node-null
@@ -299,10 +291,8 @@ if(OPTION_BUILD_LOADERS AND OPTION_BUILD_LOADERS_NODE AND OPTION_BUILD_SCRIPTS A
299291
COMMAND ${CMAKE_COMMAND} -D "EXECUTABLE=$<TARGET_FILE:${target}>" -D "INPUT=${TEST_COMMAND_INPUT}-node-null-empty.txt" -P ${TEST_COMMAND_RUNNER}
300292
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
301293
)
302-
set_property(TEST ${target}-node-null-empty
303-
PROPERTY LABELS ${target}-node-null-empty
304-
)
305294
set_tests_properties(${target}-node-null-empty PROPERTIES
295+
LABELS ${target}-node-null-empty
306296
PASS_REGULAR_EXPRESSION "Hello 342521512461246!"
307297
)
308298
test_environment_variables(${target}-node-null-empty
@@ -314,10 +304,8 @@ if(OPTION_BUILD_LOADERS AND OPTION_BUILD_LOADERS_NODE AND OPTION_BUILD_SCRIPTS A
314304
COMMAND ${CMAKE_COMMAND} -D "EXECUTABLE=$<TARGET_FILE:${target}>" -D "INPUT=${TEST_COMMAND_INPUT}-node-null-undefined.txt" -P ${TEST_COMMAND_RUNNER}
315305
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
316306
)
317-
set_property(TEST ${target}-node-null-undefined
318-
PROPERTY LABELS ${target}-node-null-undefined
319-
)
320307
set_tests_properties(${target}-node-null-undefined PROPERTIES
308+
LABELS ${target}-node-null-undefined
321309
PASS_REGULAR_EXPRESSION "(null)"
322310
)
323311
test_environment_variables(${target}-node-null-undefined
@@ -330,10 +318,8 @@ if(OPTION_BUILD_LOADERS AND OPTION_BUILD_LOADERS_NODE AND OPTION_BUILD_SCRIPTS A
330318
COMMAND ${CMAKE_COMMAND} -D "EXECUTABLE=$<TARGET_FILE:${target}>" -D "INPUT=${TEST_COMMAND_INPUT}-py-port.txt" -P ${TEST_COMMAND_RUNNER}
331319
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
332320
)
333-
set_property(TEST ${target}-py-port
334-
PROPERTY LABELS ${target}-py-port
335-
)
336321
set_tests_properties(${target}-py-port PROPERTIES
322+
LABELS ${target}-py-port
337323
PASS_REGULAR_EXPRESSION "1234"
338324
)
339325
test_environment_variables(${target}-py-port
@@ -346,10 +332,8 @@ if(OPTION_BUILD_LOADERS AND OPTION_BUILD_LOADERS_NODE AND OPTION_BUILD_SCRIPTS A
346332
COMMAND ${CMAKE_COMMAND} -D "EXECUTABLE=$<TARGET_FILE:${target}>" -D "INPUT=${TEST_COMMAND_INPUT}-py-port-rb.txt" -P ${TEST_COMMAND_RUNNER}
347333
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
348334
)
349-
set_property(TEST ${target}-py-port-rb
350-
PROPERTY LABELS ${target}-py-port-rb
351-
)
352335
set_tests_properties(${target}-py-port-rb PROPERTIES
336+
LABELS ${target}-py-port-rb
353337
PASS_REGULAR_EXPRESSION "0123456789ABCDEFasd"
354338
)
355339
test_environment_variables(${target}-py-port-rb
@@ -365,10 +349,8 @@ if(OPTION_BUILD_LOADERS AND OPTION_BUILD_LOADERS_FILE AND OPTION_BUILD_SCRIPTS A
365349
COMMAND ${CMAKE_COMMAND} -D "EXECUTABLE=$<TARGET_FILE:${target}>" -D "INPUT=${TEST_COMMAND_INPUT}-file.txt" -P ${TEST_COMMAND_RUNNER}
366350
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
367351
)
368-
set_property(TEST ${target}-file
369-
PROPERTY LABELS ${target}-file
370-
)
371352
set_tests_properties(${target}-file PROPERTIES
353+
LABELS ${target}-file
372354
PASS_REGULAR_EXPRESSION "${LOADER_SCRIPT_PATH}/template.html"
373355
)
374356
test_environment_variables(${target}-file
@@ -379,10 +361,8 @@ if(OPTION_BUILD_LOADERS AND OPTION_BUILD_LOADERS_FILE AND OPTION_BUILD_SCRIPTS A
379361
COMMAND $<TARGET_FILE:${target}> this-does-not-exist
380362
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
381363
)
382-
set_property(TEST ${target}-file-fail
383-
PROPERTY LABELS ${target}-file-fail
384-
)
385364
set_tests_properties(${target}-file-fail PROPERTIES
365+
LABELS ${target}-file-fail
386366
PASS_REGULAR_EXPRESSION "Error: Failed to load script 'this-does-not-exist' with loader 'file'"
387367
)
388368
test_environment_variables(${target}-file-fail
@@ -396,10 +376,8 @@ if(OPTION_BUILD_LOADERS AND OPTION_BUILD_LOADERS_PY)
396376
COMMAND $<TARGET_FILE:${target}> test.py
397377
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
398378
)
399-
set_property(TEST ${target}-py-naming
400-
PROPERTY LABELS ${target}-py-naming
401-
)
402379
set_tests_properties(${target}-py-naming PROPERTIES
380+
LABELS ${target}-py-naming
403381
PASS_REGULAR_EXPRESSION "Test: 66673332"
404382
)
405383
test_environment_variables(${target}-py-naming
@@ -410,10 +388,8 @@ if(OPTION_BUILD_LOADERS AND OPTION_BUILD_LOADERS_PY)
410388
COMMAND $<TARGET_FILE:${target}> cli-test-argv.py
411389
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
412390
)
413-
set_property(TEST ${target}-py-argv
414-
PROPERTY LABELS ${target}-py-argv
415-
)
416391
set_tests_properties(${target}-py-argv PROPERTIES
392+
LABELS ${target}-py-argv
417393
PASS_REGULAR_EXPRESSION "Test: cli-test-argv.py"
418394
)
419395
test_environment_variables(${target}-py-argv
@@ -424,10 +400,8 @@ if(OPTION_BUILD_LOADERS AND OPTION_BUILD_LOADERS_PY)
424400
COMMAND $<TARGET_FILE:${target}> cli-test-main.py
425401
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
426402
)
427-
set_property(TEST ${target}-py-main
428-
PROPERTY LABELS ${target}-py-main
429-
)
430403
set_tests_properties(${target}-py-main PROPERTIES
404+
LABELS ${target}-py-main
431405
PASS_REGULAR_EXPRESSION "Test: 1234567890abcd"
432406
)
433407
test_environment_variables(${target}-py-main
@@ -438,10 +412,8 @@ if(OPTION_BUILD_LOADERS AND OPTION_BUILD_LOADERS_PY)
438412
COMMAND ${CMAKE_COMMAND} -D "EXECUTABLE=$<TARGET_FILE:${target}>" -D "INPUT=${TEST_COMMAND_INPUT}-py-exception.txt" -P ${TEST_COMMAND_RUNNER}
439413
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
440414
)
441-
set_property(TEST ${target}-py-exception
442-
PROPERTY LABELS ${target}-py-exception
443-
)
444415
set_tests_properties(${target}-py-exception PROPERTIES
416+
LABELS ${target}-py-exception
445417
PASS_REGULAR_EXPRESSION "66"
446418
)
447419
test_environment_variables(${target}-py-exception
@@ -455,10 +427,8 @@ if(OPTION_BUILD_LOADERS AND OPTION_BUILD_LOADERS_TS AND OPTION_BUILD_SCRIPTS AND
455427
COMMAND ${CMAKE_COMMAND} -D "EXECUTABLE=$<TARGET_FILE:${target}>" -D "INPUT=${TEST_COMMAND_INPUT}-ts.txt" -P ${TEST_COMMAND_RUNNER}
456428
WORKING_DIRECTORY ${LOADER_SCRIPT_PATH}/typedfunc
457429
)
458-
set_property(TEST ${target}-ts
459-
PROPERTY LABELS ${target}-ts
460-
)
461430
set_tests_properties(${target}-ts PROPERTIES
431+
LABELS ${target}-ts
462432
PASS_REGULAR_EXPRESSION "51354"
463433
)
464434
test_environment_variables(${target}-ts
@@ -469,10 +439,8 @@ if(OPTION_BUILD_LOADERS AND OPTION_BUILD_LOADERS_TS AND OPTION_BUILD_SCRIPTS AND
469439
COMMAND ${CMAKE_COMMAND} -D "EXECUTABLE=$<TARGET_FILE:${target}>" -D "INPUT=${TEST_COMMAND_INPUT}-tsx-templating.txt" -P ${TEST_COMMAND_RUNNER}
470440
WORKING_DIRECTORY ${LOADER_SCRIPT_PATH}/templating
471441
)
472-
set_property(TEST ${target}-tsx-templating
473-
PROPERTY LABELS ${target}-tsx-templating
474-
)
475442
set_tests_properties(${target}-tsx-templating PROPERTIES
443+
LABELS ${target}-tsx-templating
476444
PASS_REGULAR_EXPRESSION "Hello metaprogrammer"
477445
)
478446
test_environment_variables(${target}-tsx-templating
@@ -506,10 +474,8 @@ if(OPTION_BUILD_LOADERS AND OPTION_BUILD_LOADERS_TS AND OPTION_BUILD_SCRIPTS AND
506474
COMMAND $<TARGET_FILE:${target}> loopfail.tsx
507475
WORKING_DIRECTORY ${LOADER_SCRIPT_PATH}/loopfail
508476
)
509-
set_property(TEST ${target}-tsx-loop-fail
510-
PROPERTY LABELS ${target}-tsx-loop-fail
511-
)
512477
set_tests_properties(${target}-tsx-loop-fail PROPERTIES
478+
LABELS ${target}-tsx-loop-fail
513479
PASS_REGULAR_EXPRESSION "Error: Cannot find module 'yeet-oof/whatever'"
514480
)
515481
test_environment_variables(${target}-tsx-loop-fail
@@ -523,10 +489,8 @@ if(OPTION_BUILD_LOADERS AND OPTION_BUILD_LOADERS_TS AND OPTION_BUILD_SCRIPTS AND
523489
COMMAND ${CMAKE_COMMAND} -D "EXECUTABLE=$<TARGET_FILE:${target}>" -D "INPUT=${TEST_COMMAND_INPUT}-py-tsx.txt" -P ${TEST_COMMAND_RUNNER}
524490
WORKING_DIRECTORY ${LOADER_SCRIPT_PATH}/templating
525491
)
526-
set_property(TEST ${target}-py-tsx
527-
PROPERTY LABELS ${target}-py-tsx
528-
)
529492
set_tests_properties(${target}-py-tsx PROPERTIES
493+
LABELS ${target}-py-tsx
530494
PASS_REGULAR_EXPRESSION "Hello World"
531495
)
532496
test_environment_variables(${target}-py-tsx
@@ -539,3 +503,20 @@ if(OPTION_BUILD_LOADERS AND OPTION_BUILD_LOADERS_TS AND OPTION_BUILD_SCRIPTS AND
539503
)
540504
endif()
541505
endif()
506+
507+
if(OPTION_BUILD_LOADERS AND OPTION_BUILD_LOADERS_EXT AND OPTION_BUILD_EXTENSIONS AND OPTION_BUILD_LOADERS_NODE AND OPTION_BUILD_LOADERS_PY AND OPTION_BUILD_PLUGINS_SANDBOX AND PROJECT_OS_FAMILY STREQUAL unix)
508+
if(NOT OPTION_BUILD_THREAD_SANITIZER AND NOT OPTION_BUILD_ADDRESS_SANITIZER)
509+
add_test(NAME ${target}-cmd-sandboxing
510+
COMMAND ${CMAKE_COMMAND} -E env $<TARGET_FILE:${target}> --sandboxing --disable_time time.py
511+
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
512+
)
513+
set_tests_properties(${target}-cmd-sandboxing PROPERTIES
514+
LABELS ${target}-cmd-sandboxing
515+
WILL_FAIL TRUE
516+
)
517+
test_environment_variables(${target}-cmd-sandboxing
518+
""
519+
${TESTS_ENVIRONMENT_VARIABLES}
520+
)
521+
endif()
522+
endif()

source/cli/metacallcli/source/application.cpp

Lines changed: 76 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,29 @@ bool application::cmd(std::vector<std::string> &arguments)
9898
/* Get the command parsing function */
9999
void *command_parse_func = metacall_handle_function(plugin_cli_handle, "command_parse");
100100

101+
/* By default, when executing the cmd, it will exit of the REPL */
102+
exit_condition = true;
103+
101104
if (command_parse_func == NULL)
105+
{
106+
std::cout << "Warning: CLI Arguments Parser was not loaded, "
107+
"using fallback argument parser with positional arguments only. "
108+
<< std::endl
109+
<< "Any command line option like '--help' will result into error. "
110+
"Only files are allowed: $ metacall a.py b.js c.rb"
111+
<< std::endl;
112+
113+
/* Use fallback parser, it can execute files but does not support command line arguments as options (i.e: -h, --help) */
114+
/* Parse program arguments if any (e.g metacall (0) a.py (1) b.js (2) c.rb (3)) */
115+
arguments_parse(arguments);
116+
117+
return true;
118+
}
119+
120+
/* Check first if the command function is registered */
121+
void *command_function_func = metacall_handle_function(plugin_cli_handle, "command_function");
122+
123+
if (command_function_func == NULL)
102124
{
103125
return false;
104126
}
@@ -149,15 +171,51 @@ bool application::cmd(std::vector<std::string> &arguments)
149171
void **ret_array = metacall_value_to_array(ret);
150172
void **command_map = metacall_value_to_map(ret_array[0]);
151173
size_t command_size = metacall_value_count(ret_array[0]);
152-
void **positional_array = metacall_value_to_map(ret_array[1]);
174+
void **positional_array = metacall_value_to_array(ret_array[1]);
153175
size_t positional_size = metacall_value_count(ret_array[1]);
154176

155177
/* Execute arguments */
156178
for (size_t iterator = 0; iterator < command_size; ++iterator)
157179
{
158180
void **command_pair = metacall_value_to_array(command_map[iterator]);
181+
182+
void *args[] = {
183+
command_pair[0]
184+
};
185+
186+
void *command_func = metacallfv_s(command_function_func, args, sizeof(args) / sizeof(args[0]));
187+
188+
if (metacall_value_id(command_func) == METACALL_FUNCTION)
189+
{
190+
/* Execute the function */
191+
void *command_ret = metacallfv_s(command_func, &command_pair[1], 1);
192+
metacall_value_destroy(command_func);
193+
check_for_exception(command_ret);
194+
continue;
195+
}
196+
else if (metacall_value_id(command_func) == METACALL_DOUBLE)
197+
{
198+
static const double COMMAND_NOT_REGISTERED = 0.0;
199+
200+
/* The command is not registered, skip it */
201+
if (metacall_value_to_double(command_func) == COMMAND_NOT_REGISTERED)
202+
{
203+
metacall_value_destroy(command_func);
204+
continue;
205+
}
206+
207+
/* If the function is undefined, try to match the command with a function in the handle scope */
208+
metacall_value_destroy(command_func);
209+
}
210+
else
211+
{
212+
check_for_exception(command_func);
213+
return false;
214+
}
215+
216+
/* Otherwise use the cmd handle scope for obtaining the function */
159217
const char *command_str = metacall_value_to_string(command_pair[0]);
160-
void *command_func = metacall_handle_function(plugin_cmd_handle, command_str);
218+
command_func = metacall_handle_function(plugin_cmd_handle, command_str);
161219

162220
if (command_func == NULL)
163221
{
@@ -177,6 +235,7 @@ bool application::cmd(std::vector<std::string> &arguments)
177235
{
178236
/* Initialize the REPL */
179237
repl();
238+
exit_condition = false;
180239
}
181240
else
182241
{
@@ -189,7 +248,7 @@ bool application::cmd(std::vector<std::string> &arguments)
189248
positional_arguments.push_back(metacall_value_to_string(positional_array[iterator]));
190249
}
191250

192-
arguments_parse(arguments);
251+
arguments_parse(positional_arguments);
193252
}
194253

195254
metacall_value_destroy(ret);
@@ -233,19 +292,8 @@ application::application(int argc, char *argv[]) :
233292
/* Launch the CMD (parse arguments) */
234293
if (!cmd(arguments))
235294
{
236-
std::cout << "Warning: CLI Arguments Parser was not loaded, "
237-
"using fallback argument parser with positional arguments only. "
238-
<< std::endl
239-
<< "Any command line option like '--help' will result into error. "
240-
"Only files are allowed: $ metacall a.py b.js c.rb"
241-
<< std::endl;
242-
243-
/* Use fallback parser, it can execute files but does not support command line arguments as options (i.e: -h, --help) */
244-
/* Parse program arguments if any (e.g metacall (0) a.py (1) b.js (2) c.rb (3)) */
245-
arguments_parse(arguments);
295+
/* TODO: Report something? */
246296
}
247-
248-
exit_condition = true;
249297
}
250298
}
251299

@@ -472,12 +520,24 @@ void application::run()
472520
metacall_value_destroy(await_data.v);
473521
}
474522

475-
/* Close REPL */
476523
if (plugin_cli_handle != NULL)
477524
{
525+
/* Close REPL */
478526
void *ret = metacallhv_s(plugin_cli_handle, "repl_close", metacall_null_args, 0);
479527

480528
check_for_exception(ret);
529+
530+
/* Get the command destroy function */
531+
void *command_destroy_func = metacall_handle_function(plugin_cli_handle, "command_destroy");
532+
533+
/* Destroy the commands */
534+
if (command_destroy_func != NULL)
535+
{
536+
/* Parse the arguments with the CMD plugin command parse function */
537+
ret = metacallfv_s(command_destroy_func, metacall_null_args, 0);
538+
539+
check_for_exception(ret);
540+
}
481541
}
482542
}
483543

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import time
2+
3+
time.sleep(1)

0 commit comments

Comments
 (0)