• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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