plugin.rs 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. // Copyright 2019-2021 Tauri Programme within The Commons Conservancy
  2. // SPDX-License-Identifier: Apache-2.0
  3. // SPDX-License-Identifier: MIT
  4. use crate::{
  5. helpers::{resolve_tauri_path, template, Logger},
  6. VersionMetadata,
  7. };
  8. use anyhow::Context;
  9. use handlebars::{to_json, Handlebars};
  10. use heck::{KebabCase, SnakeCase};
  11. use include_dir::{include_dir, Dir};
  12. use std::{collections::BTreeMap, env::current_dir, fs::remove_dir_all, path::PathBuf};
  13. const BACKEND_PLUGIN_DIR: Dir<'_> = include_dir!("templates/plugin/backend");
  14. const API_PLUGIN_DIR: Dir<'_> = include_dir!("templates/plugin/with-api");
  15. pub struct Plugin {
  16. plugin_name: String,
  17. api: bool,
  18. tauri: bool,
  19. directory: PathBuf,
  20. tauri_path: Option<PathBuf>,
  21. author: String,
  22. }
  23. impl Default for Plugin {
  24. fn default() -> Self {
  25. Self {
  26. plugin_name: "".into(),
  27. api: false,
  28. tauri: false,
  29. directory: current_dir().expect("failed to read cwd"),
  30. tauri_path: None,
  31. author: "".into(),
  32. }
  33. }
  34. }
  35. impl Plugin {
  36. pub fn new() -> Self {
  37. Default::default()
  38. }
  39. pub fn plugin_name(mut self, plugin_name: String) -> Self {
  40. self.plugin_name = plugin_name;
  41. self
  42. }
  43. pub fn api(mut self) -> Self {
  44. self.api = true;
  45. self
  46. }
  47. pub fn tauri(mut self) -> Self {
  48. self.tauri = true;
  49. self
  50. }
  51. pub fn directory(mut self, directory: impl Into<PathBuf>) -> Self {
  52. self.directory = directory.into();
  53. self
  54. }
  55. pub fn tauri_path(mut self, tauri_path: impl Into<PathBuf>) -> Self {
  56. self.tauri_path = Some(tauri_path.into());
  57. self
  58. }
  59. pub fn author(mut self, author: String) -> Self {
  60. self.author = author;
  61. self
  62. }
  63. pub fn run(self) -> crate::Result<()> {
  64. let logger = Logger::new("tauri:init:plugin");
  65. let template_target_path = self.directory.join(&format!(
  66. "tauri-plugin-{}",
  67. self.plugin_name.to_kebab_case()
  68. ));
  69. let metadata = serde_json::from_str::<VersionMetadata>(include_str!("../metadata.json"))?;
  70. if template_target_path.exists() {
  71. logger.warn(format!(
  72. "Plugin dir ({:?}) not empty.",
  73. template_target_path
  74. ));
  75. } else {
  76. let (tauri_dep, tauri_example_dep, tauri_build_dep) =
  77. if let Some(tauri_path) = self.tauri_path {
  78. (
  79. format!(
  80. r#"{{ path = {:?} }}"#,
  81. resolve_tauri_path(&tauri_path, "core/tauri")
  82. ),
  83. format!(
  84. r#"{{ path = {:?}, features = [ "api-all" ] }}"#,
  85. resolve_tauri_path(&tauri_path, "core/tauri")
  86. ),
  87. format!(
  88. "{{ path = {:?} }}",
  89. resolve_tauri_path(&tauri_path, "core/tauri-build")
  90. ),
  91. )
  92. } else {
  93. (
  94. format!(r#"{{ version = "{}" }}"#, metadata.tauri),
  95. format!(
  96. r#"{{ version = "{}", features = [ "api-all" ] }}"#,
  97. metadata.tauri
  98. ),
  99. format!(r#"{{ version = "{}" }}"#, metadata.tauri_build),
  100. )
  101. };
  102. let _ = remove_dir_all(&template_target_path);
  103. let handlebars = Handlebars::new();
  104. let mut data = BTreeMap::new();
  105. data.insert("plugin_name_original", to_json(&self.plugin_name));
  106. data.insert("plugin_name", to_json(self.plugin_name.to_kebab_case()));
  107. data.insert(
  108. "plugin_name_snake_case",
  109. to_json(self.plugin_name.to_snake_case()),
  110. );
  111. data.insert("tauri_dep", to_json(tauri_dep));
  112. data.insert("tauri_example_dep", to_json(tauri_example_dep));
  113. data.insert("tauri_build_dep", to_json(tauri_build_dep));
  114. data.insert("author", to_json(self.author));
  115. if self.tauri {
  116. data.insert(
  117. "license_template",
  118. to_json(
  119. "// Copyright {20\\d{2}(-20\\d{2})?} Tauri Programme within The Commons Conservancy
  120. // SPDX-License-Identifier: Apache-2.0
  121. // SPDX-License-Identifier: MIT\n\n"
  122. .replace(" ", "")
  123. .replace(" //", "//"),
  124. ),
  125. );
  126. data.insert(
  127. "license_header",
  128. to_json(
  129. "// Copyright 2019-2021 Tauri Programme within The Commons Conservancy
  130. // SPDX-License-Identifier: Apache-2.0
  131. // SPDX-License-Identifier: MIT\n\n"
  132. .replace(" ", "")
  133. .replace(" //", "//"),
  134. ),
  135. );
  136. }
  137. template::render(
  138. &handlebars,
  139. &data,
  140. if self.api {
  141. &API_PLUGIN_DIR
  142. } else {
  143. &BACKEND_PLUGIN_DIR
  144. },
  145. &template_target_path,
  146. )
  147. .with_context(|| "failed to render Tauri template")?;
  148. }
  149. Ok(())
  150. }
  151. }