1use super::functions;
2use crate::{pkg::types, utils};
3use anyhow::{Result, anyhow};
4use mlua::{self, Lua, LuaSerdeExt, Table, Value};
5use std::fs;
6
7pub fn parse_lua_package_for_platform(
8 file_path: &str,
9 platform: &str,
10 version_override: Option<&str>,
11 quiet: bool,
12) -> Result<types::Package> {
13 let lua_code = fs::read_to_string(file_path)?;
14 let lua = Lua::new();
15
16 let pkg_meta_table = lua.create_table().map_err(|e| anyhow!(e.to_string()))?;
17 let pkg_deps_table = lua.create_table().map_err(|e| anyhow!(e.to_string()))?;
18 let pkg_updates_table = lua.create_table().map_err(|e| anyhow!(e.to_string()))?;
19 let pkg_hooks_table = lua.create_table().map_err(|e| anyhow!(e.to_string()))?;
20 lua.globals()
21 .set("__ZoiPackageMeta", pkg_meta_table)
22 .map_err(|e| anyhow!(e.to_string()))?;
23 lua.globals()
24 .set("__ZoiPackageDeps", pkg_deps_table)
25 .map_err(|e| anyhow!(e.to_string()))?;
26 lua.globals()
27 .set("__ZoiPackageUpdates", pkg_updates_table)
28 .map_err(|e| anyhow!(e.to_string()))?;
29 lua.globals()
30 .set("__ZoiPackageHooks", pkg_hooks_table)
31 .map_err(|e| anyhow!(e.to_string()))?;
32
33 let pkg_table = lua.create_table().map_err(|e| anyhow!(e.to_string()))?;
34 lua.globals()
35 .set("PKG", pkg_table)
36 .map_err(|e| anyhow!(e.to_string()))?;
37
38 functions::setup_lua_environment(
39 &lua,
40 platform,
41 version_override,
42 Some(file_path),
43 None,
44 None,
45 quiet,
46 )
47 .map_err(|e| anyhow!("Failed to setup Lua environment for '{}': {}", file_path, e))?;
48
49 lua.load(&lua_code).exec().map_err(|e| {
50 anyhow!(
51 "Failed to execute Lua package file '{}':
52{}",
53 file_path,
54 e
55 )
56 })?;
57
58 let final_pkg_meta: Table = lua
59 .globals()
60 .get("__ZoiPackageMeta")
61 .map_err(|e| anyhow!(e.to_string()))?;
62 let final_pkg_deps: Table = lua
63 .globals()
64 .get("__ZoiPackageDeps")
65 .map_err(|e| anyhow!(e.to_string()))?;
66 let final_pkg_updates: Table = lua
67 .globals()
68 .get("__ZoiPackageUpdates")
69 .map_err(|e| anyhow!(e.to_string()))?;
70 let final_pkg_hooks: Table = lua
71 .globals()
72 .get("__ZoiPackageHooks")
73 .map_err(|e| anyhow!(e.to_string()))?;
74
75 let mut package: types::Package =
76 lua.from_value(Value::Table(final_pkg_meta)).map_err(|e| {
77 anyhow!(
78 "Failed to parse 'metadata' block in package file '{}':
79{}",
80 file_path,
81 e
82 )
83 })?;
84
85 package.dependencies = if final_pkg_deps.is_empty() {
86 None
87 } else {
88 Some(lua.from_value(Value::Table(final_pkg_deps)).map_err(|e| {
89 anyhow!(
90 "Failed to parse 'dependencies' block in package file '{}':
91{}",
92 file_path,
93 e
94 )
95 })?)
96 };
97
98 package.updates = if final_pkg_updates.is_empty() {
99 None
100 } else {
101 Some(
102 lua.from_value(Value::Table(final_pkg_updates))
103 .map_err(|e| {
104 anyhow!(
105 "Failed to parse 'updates' block in package file '{}':
106{}",
107 file_path,
108 e
109 )
110 })?,
111 )
112 };
113
114 package.hooks = if final_pkg_hooks.is_empty() {
115 None
116 } else {
117 Some(lua.from_value(Value::Table(final_pkg_hooks)).map_err(|e| {
118 anyhow!(
119 "Failed to parse 'hooks' block in package file '{}':
120{}",
121 file_path,
122 e
123 )
124 })?)
125 };
126
127 Ok(package)
128}
129
130pub fn parse_lua_package(
131 file_path: &str,
132 version_override: Option<&str>,
133 quiet: bool,
134) -> Result<types::Package> {
135 let platform = utils::get_platform()?;
136 parse_lua_package_for_platform(file_path, &platform, version_override, quiet)
137}