plugin.rs 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  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. directory: PathBuf,
  19. tauri_path: Option<PathBuf>,
  20. }
  21. impl Default for Plugin {
  22. fn default() -> Self {
  23. Self {
  24. plugin_name: "".into(),
  25. api: false,
  26. directory: current_dir().expect("failed to read cwd"),
  27. tauri_path: None,
  28. }
  29. }
  30. }
  31. impl Plugin {
  32. pub fn new() -> Self {
  33. Default::default()
  34. }
  35. pub fn plugin_name(mut self, plugin_name: String) -> Self {
  36. self.plugin_name = plugin_name;
  37. self
  38. }
  39. pub fn api(mut self) -> Self {
  40. self.api = true;
  41. self
  42. }
  43. pub fn directory(mut self, directory: impl Into<PathBuf>) -> Self {
  44. self.directory = directory.into();
  45. self
  46. }
  47. pub fn tauri_path(mut self, tauri_path: impl Into<PathBuf>) -> Self {
  48. self.tauri_path = Some(tauri_path.into());
  49. self
  50. }
  51. pub fn run(self) -> crate::Result<()> {
  52. let logger = Logger::new("tauri:init:plugin");
  53. let template_target_path = self.directory.join(&format!(
  54. "tauri-plugin-{}",
  55. self.plugin_name.to_kebab_case()
  56. ));
  57. let metadata = serde_json::from_str::<VersionMetadata>(include_str!("../metadata.json"))?;
  58. if template_target_path.exists() {
  59. logger.warn(format!(
  60. "Plugin dir ({:?}) not empty.",
  61. template_target_path
  62. ));
  63. } else {
  64. let (tauri_dep, tauri_build_dep) = if let Some(tauri_path) = self.tauri_path {
  65. (
  66. format!(
  67. r#"{{ path = {:?}, features = [ "api-all" ] }}"#,
  68. resolve_tauri_path(&tauri_path, "core/tauri")
  69. ),
  70. format!(
  71. "{{ path = {:?} }}",
  72. resolve_tauri_path(&tauri_path, "core/tauri-build")
  73. ),
  74. )
  75. } else {
  76. (
  77. format!(
  78. r#"{{ version = "{}", features = [ "api-all" ] }}"#,
  79. metadata.tauri
  80. ),
  81. format!(r#"{{ version = "{}" }}"#, metadata.tauri_build),
  82. )
  83. };
  84. let _ = remove_dir_all(&template_target_path);
  85. let handlebars = Handlebars::new();
  86. let mut data = BTreeMap::new();
  87. data.insert("plugin_name_original", to_json(&self.plugin_name));
  88. data.insert("plugin_name", to_json(self.plugin_name.to_kebab_case()));
  89. data.insert(
  90. "plugin_name_snake_case",
  91. to_json(self.plugin_name.to_snake_case()),
  92. );
  93. data.insert("tauri_dep", to_json(tauri_dep));
  94. data.insert("tauri_build_dep", to_json(tauri_build_dep));
  95. template::render(
  96. &handlebars,
  97. &data,
  98. if self.api {
  99. &API_PLUGIN_DIR
  100. } else {
  101. &BACKEND_PLUGIN_DIR
  102. },
  103. &template_target_path,
  104. )
  105. .with_context(|| "failed to render Tauri template")?;
  106. }
  107. Ok(())
  108. }
  109. }