1use anyhow::Result;
2use cargo_generate::{GenerateArgs, TemplatePath};
3use std::{env, path::PathBuf};
4
5const TEMPLATES_BRANCH_ENV_VAR: &str = "SAILS_CLI_TEMPLATES_BRANCH";
6const TEMPLATES_REPO: &str = "https://github.com/gear-tech/sails.git";
7const PROGRAM_TEMPLATE_PATH: &str = "templates/program";
8
9pub struct ProgramGenerator {
10 path: String,
11 name: Option<String>,
12 with_client: bool,
13 with_gtest: bool,
14 sails_version: Option<String>,
15}
16
17impl ProgramGenerator {
18 pub fn new(path: String) -> Self {
19 Self {
20 path,
21 name: None,
22 with_client: false,
23 with_gtest: false,
24 sails_version: None,
25 }
26 }
27
28 pub fn with_name(self, name: Option<String>) -> Self {
29 Self { name, ..self }
30 }
31
32 pub fn with_client(self, with_client: bool) -> Self {
33 Self {
34 with_client,
35 ..self
36 }
37 }
38
39 pub fn with_gtest(self, with_gtest: bool) -> Self {
40 Self { with_gtest, ..self }
41 }
42
43 pub fn with_sails_version(self, sails_version: Option<String>) -> Self {
44 Self {
45 sails_version,
46 ..self
47 }
48 }
49
50 pub fn generate(self) -> Result<()> {
51 let template_path = TemplatePath {
52 auto_path: Some(PROGRAM_TEMPLATE_PATH.into()),
53 git: Some(TEMPLATES_REPO.into()),
54 branch: env::var(TEMPLATES_BRANCH_ENV_VAR).ok(),
55 ..TemplatePath::default()
56 };
57
58 let (path, name) = if self.name.is_none() {
59 let path_buf = PathBuf::from(&self.path);
60 let path = path_buf.parent().map(|p| p.to_path_buf());
61 let name = path_buf.file_name().map(|n| {
62 n.to_str()
63 .expect("unreachable as was built from UTF-8")
64 .to_string()
65 });
66 (path, name)
67 } else {
68 (Some(PathBuf::from(&self.path)), self.name)
69 };
70
71 let generate_args = GenerateArgs {
72 template_path,
73 name,
74 destination: path,
75 silent: true,
76 define: vec![
77 format!("sails-cli-version={}", env!("CARGO_PKG_VERSION")),
78 format!("with-client={}", self.with_client),
79 format!("with-gtest={}", self.with_gtest),
80 format!("sails-version={}", self.sails_version.unwrap_or_default()),
81 ],
82 ..GenerateArgs::default()
83 };
84 cargo_generate::generate(generate_args)?;
85 Ok(())
86 }
87}