pyoxidizerlib/starlark/
python_embedded_resources.rs1use {
6 crate::{
7 py_packaging::binary::PythonBinaryBuilder,
8 starlark::env::{get_context, PyOxidizerEnvironmentContext},
9 },
10 anyhow::{anyhow, Context, Result},
11 log::warn,
12 starlark::{
13 environment::TypeValues,
14 values::{
15 error::{RuntimeError, ValueError},
16 {Mutable, TypedValue, Value, ValueResult},
17 },
18 {
19 starlark_fun, starlark_module, starlark_parse_param_type, starlark_signature,
20 starlark_signature_extraction, starlark_signatures,
21 },
22 },
23 starlark_dialect_build_targets::{ResolvedTarget, ResolvedTargetValue, RunMode},
24 std::sync::Arc,
25};
26
27fn error_context<F, T>(label: &str, f: F) -> Result<T, ValueError>
28where
29 F: FnOnce() -> anyhow::Result<T>,
30{
31 f().map_err(|e| {
32 ValueError::Runtime(RuntimeError {
33 code: "PYOXIDIZER_PYTHON_EMBEDDED_RESOURCES",
34 message: format!("{:?}", e),
35 label: label.to_string(),
36 })
37 })
38}
39
40pub struct PythonEmbeddedResourcesValue {
41 pub exe: Arc<dyn PythonBinaryBuilder>,
42}
43
44impl TypedValue for PythonEmbeddedResourcesValue {
45 type Holder = Mutable<PythonEmbeddedResourcesValue>;
46 const TYPE: &'static str = "PythonEmbeddedResources";
47
48 fn values_for_descendant_check_and_freeze(&self) -> Box<dyn Iterator<Item = Value>> {
49 Box::new(std::iter::empty())
50 }
51}
52
53impl PythonEmbeddedResourcesValue {
54 fn build(
55 &self,
56 type_values: &TypeValues,
57 target: &str,
58 context: &PyOxidizerEnvironmentContext,
59 ) -> Result<ResolvedTarget> {
60 let output_path = context
61 .get_output_path(type_values, target)
62 .map_err(|_| anyhow!("unable to resolve output path"))?;
63
64 warn!(
65 "writing Python embedded artifacts to {}",
66 output_path.display()
67 );
68
69 let embedded = self
70 .exe
71 .to_embedded_python_context(context.env(), &context.build_opt_level)?;
72
73 std::fs::create_dir_all(&output_path)
74 .with_context(|| format!("creating output directory: {}", output_path.display()))?;
75 embedded.write_files(&output_path)?;
76
77 Ok(ResolvedTarget {
78 run_mode: RunMode::None,
79 output_path,
80 })
81 }
82
83 fn build_starlark(&self, type_values: &TypeValues, target: String) -> ValueResult {
84 let pyoxidizer_context_value = get_context(type_values)?;
85 let pyoxidizer_context = pyoxidizer_context_value
86 .downcast_ref::<PyOxidizerEnvironmentContext>()
87 .ok_or(ValueError::IncorrectParameterType)?;
88
89 let inner = error_context("PythonEmbeddedResources.build()", || {
90 self.build(type_values, &target, &pyoxidizer_context)
91 })?;
92
93 Ok(Value::new(ResolvedTargetValue { inner }))
94 }
95}
96
97starlark_module! { python_embedded_resources_module =>
98 PythonEmbeddedResources.build(
99 env env,
100 this,
101 target: String
102 ) {
103 let this = this.downcast_ref::<PythonEmbeddedResourcesValue>().unwrap();
104 this.build_starlark(env, target)
105 }
106}