1 use crate::util::*;
2 use anyhow::{Context, Result};
3 use std::io::Write;
4
5 const TEMPLATE: &str = include_str!("../install-template.sh");
6
7 actor! {
8 #[derive(Debug)]
9 pub struct Scripter {
10 /// The name of the product, for display
11 #[arg(value_name = "NAME")]
12 product_name: String = "Product",
13
14 /// The directory under lib/ where the manifest lives
15 #[arg(value_name = "DIR")]
16 rel_manifest_dir: String = "manifestlib",
17
18 /// The string to print after successful installation
19 #[arg(value_name = "MESSAGE")]
20 success_message: String = "Installed.",
21
22 /// Places to look for legacy manifests to uninstall
23 #[arg(value_name = "DIRS")]
24 legacy_manifest_dirs: String = "",
25
26 /// The name of the output script
27 #[arg(value_name = "FILE")]
28 output_script: String = "install.sh",
29 }
30 }
31
32 impl Scripter {
33 /// Generates the actual installer script
run(self) -> Result<()>34 pub fn run(self) -> Result<()> {
35 // Replace dashes in the product name with spaces (our arg handling botches spaces)
36 // FIXME: still needed? Kept for compatibility for now.
37 let product_name = self.product_name.replace('-', " ");
38
39 // Replace dashes in the success message with spaces (our arg handling botches spaces)
40 // FIXME: still needed? Kept for compatibility for now.
41 let success_message = self.success_message.replace('-', " ");
42
43 let script = TEMPLATE
44 .replace("%%TEMPLATE_PRODUCT_NAME%%", &sh_quote(&product_name))
45 .replace("%%TEMPLATE_REL_MANIFEST_DIR%%", &self.rel_manifest_dir)
46 .replace("%%TEMPLATE_SUCCESS_MESSAGE%%", &sh_quote(&success_message))
47 .replace("%%TEMPLATE_LEGACY_MANIFEST_DIRS%%", &sh_quote(&self.legacy_manifest_dirs))
48 .replace(
49 "%%TEMPLATE_RUST_INSTALLER_VERSION%%",
50 &sh_quote(&crate::RUST_INSTALLER_VERSION),
51 );
52
53 create_new_executable(&self.output_script)?
54 .write_all(script.as_ref())
55 .with_context(|| format!("failed to write output script '{}'", self.output_script))?;
56
57 Ok(())
58 }
59 }
60
sh_quote<T: ToString>(s: &T) -> String61 fn sh_quote<T: ToString>(s: &T) -> String {
62 // We'll single-quote the whole thing, so first replace single-quotes with
63 // '"'"' (leave quoting, double-quote one `'`, re-enter single-quoting)
64 format!("'{}'", s.to_string().replace('\'', r#"'"'"'"#))
65 }
66