init.rs 4.4 KB

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