diff --git a/source/examples/metacallcli/CMakeLists.txt b/source/examples/metacallcli/CMakeLists.txt index 7babb00f5..1ecbc4b90 100644 --- a/source/examples/metacallcli/CMakeLists.txt +++ b/source/examples/metacallcli/CMakeLists.txt @@ -54,23 +54,6 @@ add_executable(${target} # Create namespaced alias add_executable(${META_PROJECT_NAME}::${target} ALIAS ${target}) -# Configure package manager path -if(MSVC) - set(PROJECT_METACALL_PACK_MAN_DIR "${CMAKE_BINARY_DIR}/${CMAKE_BUILD_TYPE}") -else() - set(PROJECT_METACALL_PACK_MAN_DIR "${CMAKE_BINARY_DIR}") -endif() - -# Copy package manager scripts -add_custom_target(${target}-scripts ALL - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} - COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/package_manager/pip.py ${PROJECT_METACALL_PACK_MAN_DIR} - COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/package_manager/npm.js ${PROJECT_METACALL_PACK_MAN_DIR} -) - -# Set dependency to metacallcli -add_dependencies(${target} ${target}-scripts) - # # Project options # @@ -138,22 +121,11 @@ install(TARGETS ${target} BUNDLE DESTINATION ${INSTALL_BIN} COMPONENT examples ) -# Scripts (Package Managers) -install(FILES - ${CMAKE_CURRENT_SOURCE_DIR}/package_manager/pip.py - ${CMAKE_CURRENT_SOURCE_DIR}/package_manager/npm.js - DESTINATION ${INSTALL_LIB} - COMPONENT runtime -) - # # Define test # -#set(TEST_COMMAND_LINE_ARGS "help") # TODO: Forward all commands, create an adaptor to existing system -set(TEST_COMMAND_LINE_ARGS "load mock test.mock") -#set(TEST_COMMAND_LINE_ARGS "install py numpy") -#set(TEST_COMMAND_LINE_ARGS "install node rambda") # TODO: This segfaults during ctest but not when running it normally +set(TEST_COMMAND_LINE_ARGS "test.mock") if(WIN32) set(TEST_COMMAND cmd /c) @@ -176,19 +148,7 @@ set_property(TEST ${target} include(TestEnvironmentVariables) -if(NOT OPTION_BUILD_GUIX) - # Get node path for npm - execute_process( - COMMAND npm root --quiet -g - OUTPUT_VARIABLE NODE_PATH - ) - set(NODE_PATH "NODE_PATH=${NODE_PATH}") -else() - set(NODE_PATH "NODE_PATH=$ENV{NODE_PATH}") -endif() - test_environment_variables(${target} ${TEST_COMMAND_LINE_ARGS} ${TESTS_ENVIRONMENT_VARIABLES} - ${NODE_PATH} ) diff --git a/source/examples/metacallcli/application.cpp b/source/examples/metacallcli/application.cpp index 14642c34a..aa5ab4f75 100644 --- a/source/examples/metacallcli/application.cpp +++ b/source/examples/metacallcli/application.cpp @@ -315,8 +315,8 @@ bool command_cb_exit(application & app, tokenizer & /*t*/) /* -- Methods -- */ -application::parameter_iterator::parameter_iterator(application & app, const char * command, const char * tag, application::arg_list & arguments) : - app(app), command(command), tag(tag), arguments(arguments) +application::parameter_iterator::parameter_iterator(application & app) : + app(app) { } @@ -328,115 +328,22 @@ application::parameter_iterator::~parameter_iterator() void application::parameter_iterator::operator()(const char * parameter) { - arguments.push_back(parameter); -} - -void application::parameter_iterator::evaluate() -{ - typedef std::function parameter_callback; + std::string script(parameter); - /* List of scripts that run pip/npm/gem */ - static std::unordered_map install_scripts = + static std::unordered_map extension_to_tag = { - { - "py", - - "#!/usr/bin/env python3\n" - "\n" - "try:\n" - " from pip import main as pipmain\n" - "except ImportError:\n" - " from pip._internal import main as pipmain\n" - "\n" - "def package_manager(args):\n" - " return pipmain(args);\n" - }, - { - "node", - - "const path = require('path');\n" - "let npm = { package_manager: function (args) { console.log('NPM could not be found, please set up LOADER_LIBRARY_PATH enviroment variable,'); } };\n" - "try {\n" - " npm = require(path.join(process.env['LOADER_LIBRARY_PATH'], 'npm.js'));\n" - "} catch (e) {\n" - " console.log(e);\n" - "}\n" - "module.exports = npm;\n" - } + { "mock", "mock" }, + { "py", "py" }, + { "js", "node" }, + { "rb", "rb" }, + { "cs", "cs" } }; - /* List of available commands when installing */ - static std::unordered_map parameter_commands = - { - { - "load", [](application & app, const std::string & tag, const std::string &, application::arg_list & args) - { - std::for_each(args.begin(), args.end(), [&app, &tag](const std::string & script) - { - app.load(tag, script); - }); - } - }, - { - "install", [](application & app, const std::string & tag, const std::string & command, application::arg_list & args) - { - const std::string & script = install_scripts[tag]; - - if (script == "") - { - std::cout << "Package manager script not available for tag (" << tag << ")" << std::endl; - - app.shutdown(); - - return; - } - - if (metacall_load_from_memory(tag.c_str(), script.c_str(), script.size(), NULL) != 0) - { - std::cout << "Error when loading (" << tag << ") package manager script" << std::endl; - - app.shutdown(); + const std::string tag = extension_to_tag[script.substr(script.find_last_of(".") + 1)]; - return; - } - - void * args_values[1] = - { - metacall_value_create_array(NULL, args.size() + 1) - }; - - void ** array_value = static_cast(metacall_value_to_array(args_values[0])); - - size_t iterator = 0; - - array_value[iterator++] = metacall_value_create_string(command.c_str(), command.length()); - - std::for_each(args.begin(), args.end(), [&array_value, &iterator](const std::string & arg) - { - array_value[iterator++] = metacall_value_create_string(arg.c_str(), arg.length()); - }); - - void * result = metacallv("package_manager", args_values); - - metacall_value_destroy(args_values[0]); - - /* TODO: Do something with result */ - - if (result != NULL) - { - metacall_value_destroy(result); - } - - app.shutdown(); - } - } - }; - - const parameter_callback cb = parameter_commands[command]; - - if (cb != nullptr) + if (!app.load(tag, script)) { - cb(app, tag, command, arguments); + app.shutdown(); } } @@ -548,16 +455,13 @@ application::application(int argc, char * argv[]) : exit_condition(false), log_p /* Print MetaCall information */ metacall_print_info(); - /* Parse program arguments if any (e.g metacall (0) load (1) py (2) asd.py (3)) */ - if (argc > 3) + /* Parse program arguments if any (e.g metacall (0) a.py (1) b.js (2) c.rb (3)) */ + if (argc > 1) { - parameter_iterator param_it(*this, argv[1], argv[2], arguments); + parameter_iterator param_it(*this); /* Parse program parameters */ - std::for_each(&argv[3], argv + argc, param_it); - - /* Execute the action */ - param_it.evaluate(); + std::for_each(&argv[1], argv + argc, param_it); } /* Define available commands */ diff --git a/source/examples/metacallcli/application.hpp b/source/examples/metacallcli/application.hpp index 6b689087d..c2fa6feba 100644 --- a/source/examples/metacallcli/application.hpp +++ b/source/examples/metacallcli/application.hpp @@ -234,17 +234,8 @@ class application * * @param[in] app * Reference to the application - * - * @param[in] command - * Command to be executed - * - * @param[in] tag - * Loader tag reference - * - * @param[in] arguments - * Reference to list of arguments to be iterated */ - parameter_iterator(application & app, const char * command, const char * tag, arg_list & arguments); + parameter_iterator(application & app); /** * @brief @@ -261,12 +252,6 @@ class application */ void operator()(const char * parameter); - /** - * @brief - * Execute the action parsed by parameters - */ - void evaluate(); - /** * @brief * Assignement operator for parameter iterator @@ -281,9 +266,6 @@ class application /* -- Private Member Data -- */ application & app; /**< Reference to the application */ - std::string command; /**< Command to be executed */ - std::string tag; /**< Loader tag reference */ - arg_list & arguments; /**< Reference to the argument list */ }; /* -- Private Member Data -- */ diff --git a/source/examples/metacallcli/package_manager/npm.js b/source/examples/metacallcli/package_manager/npm.js deleted file mode 100644 index 447a58187..000000000 --- a/source/examples/metacallcli/package_manager/npm.js +++ /dev/null @@ -1,159 +0,0 @@ -#!/usr/bin/env node - -/* This has been ripped off from NPM and adapted to be callable instead of invoked by exec */ - -function package_manager(args) { - // windows: running "npm blah" in this folder will invoke WSH, not node. - // global WScript - if (typeof WScript !== 'undefined') { - WScript.echo( - 'npm does not work when run\n' + - 'with the Windows Scripting Host\n\n' + - "'cd' to a different directory,\n" + - "or type 'npm.cmd ',\n" + - "or type 'node npm '." - ) - WScript.quit(1) - return - } - - var unsupported = require('npm/lib/utils/unsupported.js') - unsupported.checkForBrokenNode() - - var log = require('npm/node_modules/npmlog') - log.pause() // will be unpaused when config is loaded. - log.info('it worked if it ends with', 'ok') - - unsupported.checkForUnsupportedNode() - - var path = require('path') - var npm = require('npm/lib/npm.js') - var npmconf = require('npm/lib/config/core.js') - var errorHandler = require('npm/lib/utils/error-handler.js') - - var configDefs = npmconf.defs - var shorthands = configDefs.shorthands - var types = configDefs.types - var nopt = require('npm/node_modules/nopt') - - // Overwrite process args - process.argv = [ - process.env['NODE_EXE_PATH'] || 'node', - process.env['NODE_PATH'] ? path.join(process.env['NODE_PATH'], 'npm', 'bin', 'npm-cli.js') : 'npm', - ...args, - ]; - - log.verbose('cli', process.argv) - - var conf = nopt(types, shorthands) - npm.argv = conf.argv.remain - if (npm.deref(npm.argv[0])) npm.command = npm.argv.shift() - else conf.usage = true - - if (conf.version) { - console.log(npm.version) - return errorHandler.exit(0) - } - - if (conf.versions) { - npm.command = 'version' - conf.usage = false - npm.argv = [] - } - - log.info('using', 'npm@%s', npm.version) - log.info('using', 'node@%s', process.version) - - process.on('uncaughtException', errorHandler) - - if (conf.usage && npm.command !== 'help') { - npm.argv.unshift(npm.command) - npm.command = 'help' - } - - var isGlobalNpmUpdate = conf.global && ['install', 'update'].includes(npm.command) && npm.argv.includes('npm') - - // now actually fire up npm and run the command. - // this is how to use npm programmatically: - conf._exit = true - npm.load(conf, function (er) { - if (er) return errorHandler(er) - if ( - !isGlobalNpmUpdate && - npm.config.get('update-notifier') && - !unsupported.checkVersion(process.version).unsupported - ) { - const pkg = require('npm/package.json') - let notifier = require('npm/node_modules/update-notifier')({pkg}) - const isCI = require('npm/node_modules/ci-info').isCI - if ( - notifier.update && - notifier.update.latest !== pkg.version && - !isCI - ) { - const color = require('ansicolors') - const useColor = npm.config.get('color') - const useUnicode = npm.config.get('unicode') - const old = notifier.update.current - const latest = notifier.update.latest - let type = notifier.update.type - if (useColor) { - switch (type) { - case 'major': - type = color.red(type) - break - case 'minor': - type = color.yellow(type) - break - case 'patch': - type = color.green(type) - break - } - } - const changelog = `https://github.com/npm/cli/releases/tag/v${latest}` - notifier.notify({ - message: `New ${type} version of ${pkg.name} available! ${ - useColor ? color.red(old) : old - } ${useUnicode ? '→' : '->'} ${ - useColor ? color.green(latest) : latest - }\n` + - `${ - useColor ? color.yellow('Changelog:') : 'Changelog:' - } ${ - useColor ? color.cyan(changelog) : changelog - }\n` + - `Run ${ - useColor - ? color.green(`npm install -g ${pkg.name}`) - : `npm i -g ${pkg.name}` - } to update!` - }) - } - } - npm.commands[npm.command](npm.argv, function (err) { - // https://genius.com/Lin-manuel-miranda-your-obedient-servant-lyrics - if ( - !err && - npm.config.get('ham-it-up') && - !npm.config.get('json') && - !npm.config.get('parseable') && - npm.command !== 'completion' - ) { - console.error( - `\n ${ - npm.config.get('unicode') ? '🎵 ' : '' - } I Have the Honour to Be Your Obedient Servant,${ - npm.config.get('unicode') ? '🎵 ' : '' - } ~ npm ${ - npm.config.get('unicode') ? '📜🖋 ' : '' - }\n` - ) - } - errorHandler.apply(this, arguments) - }) - }) -} - -module.exports = { - package_manager, -}; diff --git a/source/examples/metacallcli/package_manager/pip.py b/source/examples/metacallcli/package_manager/pip.py deleted file mode 100644 index 8b752ffaa..000000000 --- a/source/examples/metacallcli/package_manager/pip.py +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/env python3 - -try: - from pip import main as pipmain -except ImportError: - from pip._internal import main as pipmain - -def package_manager(args): - return pipmain(args);