[Add] Implement build system for user scripts.
This commit is contained in:
parent
20f2e5a104
commit
9b6106f8aa
27
assets/scripts/bin/build.lua
Normal file
27
assets/scripts/bin/build.lua
Normal file
@ -0,0 +1,27 @@
|
||||
-- /bin/build - "Compiles" a .lua file into an executable.
|
||||
local source_filename = arg[1]
|
||||
|
||||
if not source_filename then
|
||||
return "build: missing file operand"
|
||||
end
|
||||
|
||||
-- Check for .lua extension.
|
||||
if not source_filename:match("%.lua$") then
|
||||
return "build: input file must be a .lua file"
|
||||
end
|
||||
|
||||
local current_dir = bettola.get_current_dir(context)
|
||||
local source_node = current_dir.children[source_filename]
|
||||
|
||||
if not source_node then
|
||||
return "build: cannot open '" .. source_filename .."': No such file"
|
||||
end
|
||||
|
||||
if source_node.type ~= 0 then
|
||||
return "build: '" .. source_filename .. "' is not a regular file"
|
||||
end
|
||||
|
||||
local executable_filename = source_filename:gsub("%.lua$", "")
|
||||
local source_content = source_node.content
|
||||
|
||||
return bettola.create_executable(context, executable_filename, source_content)
|
||||
@ -78,6 +78,50 @@ std::string write_file(Session& context, const std::string& path,
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string create_executable(Session& context, const std::string& path,
|
||||
const std::string& content) {
|
||||
vfs_node* parent_dir = nullptr;
|
||||
std::string filename;
|
||||
|
||||
if(path[0] == '/') {
|
||||
Machine* session_machine = context.get_session_machine();
|
||||
vfs_node* root = session_machine->vfs_root;
|
||||
|
||||
size_t last_slash = path.find_last_of('/');
|
||||
if(last_slash == 0) {
|
||||
parent_dir = root;
|
||||
filename = path.substr(1);
|
||||
} else {
|
||||
std::string parent_path = path.substr(0, last_slash);
|
||||
parent_dir = find_node_by_path(root, parent_path);
|
||||
filename = path.substr(last_slash+1);
|
||||
}
|
||||
} else {
|
||||
parent_dir = context.get_current_dir();
|
||||
filename = path;
|
||||
}
|
||||
|
||||
if(!parent_dir) {
|
||||
return "create_executable: cannot create file '" + path + "': No such file or directory";
|
||||
}
|
||||
|
||||
if(parent_dir->type != DIR_NODE) {
|
||||
return "create_executable: cannot create file in '" + get_full_path(parent_dir)
|
||||
+ "': Not a directory";
|
||||
}
|
||||
|
||||
/* Overwrite if exists. */
|
||||
auto it = parent_dir->children.find(filename);
|
||||
if(it != parent_dir->children.end()) {
|
||||
delete it->second;
|
||||
parent_dir->children.erase(it);
|
||||
}
|
||||
vfs_node* new_exec = new_node(filename, EXEC_NODE, parent_dir);
|
||||
new_exec->content = content;
|
||||
parent_dir->children[filename] = new_exec;
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string cd(Session& context, const std::string& path) {
|
||||
vfs_node* current_dir = context.get_current_dir();
|
||||
|
||||
|
||||
@ -13,6 +13,8 @@ vfs_node* get_current_dir(Session& context);
|
||||
std::string rm(Session& context, const std::string& filename);
|
||||
std::string write_file(Session& context, const std::string& path,
|
||||
const std::string& content);
|
||||
std::string create_executable(Session& context, const std::string& path,
|
||||
const std::string& content);
|
||||
std::string ls(Session& context);
|
||||
std::string cd(Session& context, const std::string& path);
|
||||
std::string scp(Session& context, const std::string& source,
|
||||
|
||||
@ -23,16 +23,17 @@ LuaProcessor::LuaProcessor(Session& context) {
|
||||
|
||||
/* Create the 'bettola' API table. */
|
||||
sol::table bettola_api = _lua.create_named_table("bettola");
|
||||
bettola_api.set_function("rm", &api::rm);
|
||||
bettola_api.set_function("ls", &api::ls);
|
||||
bettola_api.set_function("write_file", &api::write_file);
|
||||
bettola_api.set_function("get_current_dir", &api::get_current_dir);
|
||||
bettola_api.set_function("cd", &api::cd);
|
||||
bettola_api.set_function("scp", &api::scp);
|
||||
bettola_api.set_function("close_terminal", &api::close_terminal);
|
||||
bettola_api.set_function("ssh", &api::ssh);
|
||||
bettola_api.set_function("nmap", &api::nmap);
|
||||
bettola_api.set_function("disconnect", &api::disconnect);
|
||||
bettola_api.set_function("rm", &api::rm);
|
||||
bettola_api.set_function("ls", &api::ls);
|
||||
bettola_api.set_function("write_file", &api::write_file);
|
||||
bettola_api.set_function("create_executable", &api::create_executable);
|
||||
bettola_api.set_function("get_current_dir", &api::get_current_dir);
|
||||
bettola_api.set_function("cd", &api::cd);
|
||||
bettola_api.set_function("scp", &api::scp);
|
||||
bettola_api.set_function("close_terminal", &api::close_terminal);
|
||||
bettola_api.set_function("ssh", &api::ssh);
|
||||
bettola_api.set_function("nmap", &api::nmap);
|
||||
bettola_api.set_function("disconnect", &api::disconnect);
|
||||
}
|
||||
|
||||
LuaProcessor::~LuaProcessor(void) {}
|
||||
|
||||
@ -93,23 +93,36 @@ std::string Session::process_command(const std::string& command) {
|
||||
args.push_back(arg);
|
||||
}
|
||||
|
||||
/* Find the /bin directory in the current machine's VFS. */
|
||||
vfs_node* bin_dir = find_node_by_path(_session_machine->vfs_root, "/bin");
|
||||
if(bin_dir && bin_dir->type == DIR_NODE) {
|
||||
auto it = bin_dir->children.find(command_name);
|
||||
if(it != bin_dir->children.end()) {
|
||||
vfs_node* command_node = it->second;
|
||||
if(command_node->type == EXEC_NODE) {
|
||||
/* Execute the script. */
|
||||
bool is_remote = (_session_machine != _home_machine);
|
||||
sol::object result = lua.execute(command_node->content, *this, args, is_remote);
|
||||
return result.is<std::string>() ? result.as<std::string>()
|
||||
: "[Script returned an unexpected type]";
|
||||
vfs_node* command_node = nullptr;
|
||||
if(command_name.find('/') != std::string::npos) {
|
||||
/* Path provided, find node directly. */
|
||||
command_node = find_node_by_path(_session_machine->vfs_root, command_name);
|
||||
} else {
|
||||
/* No path, search current dir then /bin. */
|
||||
vfs_node* current_dir = get_current_dir();
|
||||
if(current_dir->children.count(command_name)) {
|
||||
command_node = current_dir->children.at(command_name);
|
||||
} else {
|
||||
vfs_node* bin_dir = find_node_by_path(_session_machine->vfs_root, "/bin");
|
||||
if(bin_dir && bin_dir->children.count(command_name)) {
|
||||
command_node = bin_dir->children.at(command_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return "Unknown command: " + command_name + "\n";
|
||||
if(command_node) {
|
||||
if(command_node->type == EXEC_NODE) {
|
||||
bool is_remote = (_session_machine != _home_machine);
|
||||
sol::object result = lua.execute(command_node->content, *this, args, is_remote);
|
||||
return result.is<std::string>() ? result.as<std::string>()
|
||||
: "[Script returned non-string value]";
|
||||
} else if(command_node->type == DIR_NODE) {
|
||||
return "Cannot execute '" + command_name + "' It is a directory.";
|
||||
} else {
|
||||
return "Cannot execute '" + command_name + "': Not an executable file.";
|
||||
}
|
||||
}
|
||||
return "Unknown command: " + command_name;
|
||||
}
|
||||
|
||||
std::string Session::write_file(const std::string& path, const std::string& content) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user