Skip to content

Commit 14d03d4

Browse files
authored
refactor(cli): enhance plugin commands for mobile (#6289)
1 parent f5e272b commit 14d03d4

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

87 files changed

+406
-401
lines changed

.changes/add-mobile-to-plugin.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"cli.rs": minor
3+
"cli.js": minor
4+
---
5+
6+
Added `plugin android add` and `plugin ios add` commands to add mobile plugin functionality to existing projects.

.changes/plugin-init-refactor.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"cli.rs": minor
3+
"cli.js": minor
4+
---
5+
6+
Changed the `--api` flag on `plugin init` to `--no-api`.

tooling/cli/src/helpers/template.rs

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -42,27 +42,21 @@ pub fn render<P: AsRef<Path>, D: Serialize>(
4242
) -> crate::Result<()> {
4343
let out_dir = out_dir.as_ref();
4444
let mut created_dirs = Vec::new();
45-
render_with_generator(
46-
handlebars,
47-
data,
48-
dir,
49-
out_dir,
50-
&mut |file_path: &PathBuf| {
51-
let path = out_dir.join(file_path);
52-
let parent = path.parent().unwrap().to_path_buf();
53-
if !created_dirs.contains(&parent) {
54-
create_dir_all(&parent)?;
55-
created_dirs.push(parent);
56-
}
57-
File::create(path).map(Some)
58-
},
59-
)
45+
render_with_generator(handlebars, data, dir, out_dir, &mut |file_path: PathBuf| {
46+
let path = out_dir.join(file_path);
47+
let parent = path.parent().unwrap().to_path_buf();
48+
if !created_dirs.contains(&parent) {
49+
create_dir_all(&parent)?;
50+
created_dirs.push(parent);
51+
}
52+
File::create(path).map(Some)
53+
})
6054
}
6155

6256
pub fn render_with_generator<
6357
P: AsRef<Path>,
6458
D: Serialize,
65-
F: FnMut(&PathBuf) -> std::io::Result<Option<File>>,
59+
F: FnMut(PathBuf) -> std::io::Result<Option<File>>,
6660
>(
6761
handlebars: &Handlebars<'_>,
6862
data: &D,
@@ -80,7 +74,7 @@ pub fn render_with_generator<
8074
file_path.set_extension("toml");
8175
}
8276
}
83-
if let Some(mut output_file) = out_file_generator(&file_path)? {
77+
if let Some(mut output_file) = out_file_generator(file_path)? {
8478
if let Some(utf8) = file.contents_utf8() {
8579
handlebars
8680
.render_template_to_write(utf8, &data, &mut output_file)

tooling/cli/src/mobile/android/project.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ pub fn gen(
9797
map.inner(),
9898
&TEMPLATE_DIR,
9999
&dest,
100-
&mut |path| generate_out_file(path, &dest, &package_path, &mut created_dirs),
100+
&mut |path| generate_out_file(&path, &dest, &package_path, &mut created_dirs),
101101
)
102102
.with_context(|| "failed to process template")?;
103103

tooling/cli/src/plugin.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ use clap::{Parser, Subcommand};
66

77
use crate::Result;
88

9+
mod android;
910
mod init;
11+
mod ios;
1012

1113
#[derive(Parser)]
1214
#[clap(
@@ -24,11 +26,15 @@ pub struct Cli {
2426
#[derive(Subcommand)]
2527
enum Commands {
2628
Init(init::Options),
29+
Android(android::Cli),
30+
Ios(ios::Cli),
2731
}
2832

2933
pub fn command(cli: Cli) -> Result<()> {
3034
match cli.command {
3135
Commands::Init(options) => init::command(options)?,
36+
Commands::Android(cli) => android::command(cli)?,
37+
Commands::Ios(cli) => ios::command(cli)?,
3238
}
3339

3440
Ok(())

tooling/cli/src/plugin/android.rs

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
// Copyright 2019-2022 Tauri Programme within The Commons Conservancy
2+
// SPDX-License-Identifier: Apache-2.0
3+
// SPDX-License-Identifier: MIT
4+
5+
use crate::{helpers::template, Result};
6+
use clap::{Parser, Subcommand};
7+
use handlebars::Handlebars;
8+
9+
use std::{
10+
collections::BTreeMap,
11+
env::current_dir,
12+
ffi::OsStr,
13+
path::{Component, PathBuf},
14+
};
15+
16+
#[derive(Parser)]
17+
#[clap(
18+
author,
19+
version,
20+
about = "Manage the Android project for Tauri plugins",
21+
subcommand_required(true),
22+
arg_required_else_help(true)
23+
)]
24+
pub struct Cli {
25+
#[clap(subcommand)]
26+
command: Commands,
27+
}
28+
29+
#[derive(Subcommand)]
30+
enum Commands {
31+
Add(AddOptions),
32+
}
33+
34+
#[derive(Debug, Parser)]
35+
#[clap(about = "Adds the Android project to an existing Tauri plugin")]
36+
pub struct AddOptions {
37+
/// Name of your Tauri plugin. Must match the current plugin's name.
38+
#[clap(short = 'n', long = "name")]
39+
plugin_name: String,
40+
/// The output directory.
41+
#[clap(short, long)]
42+
#[clap(default_value_t = current_dir().expect("failed to read cwd").to_string_lossy().into_owned())]
43+
out_dir: String,
44+
}
45+
46+
pub fn command(cli: Cli) -> Result<()> {
47+
match cli.command {
48+
Commands::Add(options) => {
49+
let out_dir = PathBuf::from(options.out_dir);
50+
if out_dir.join("android").exists() {
51+
return Err(anyhow::anyhow!("android folder already exists"));
52+
}
53+
54+
let plugin_id = super::init::request_input(
55+
"What should be the Android Package ID for your plugin?",
56+
Some(format!("com.plugin.{}", options.plugin_name)),
57+
false,
58+
false,
59+
)?
60+
.unwrap();
61+
62+
let handlebars = Handlebars::new();
63+
64+
let mut data = BTreeMap::new();
65+
super::init::plugin_name_data(&mut data, &options.plugin_name);
66+
67+
let mut created_dirs = Vec::new();
68+
template::render_with_generator(
69+
&handlebars,
70+
&data,
71+
&super::init::TEMPLATE_DIR,
72+
&out_dir,
73+
&mut |path| {
74+
let mut components = path.components();
75+
let root = components.next().unwrap();
76+
if let Component::Normal(component) = root {
77+
if component == OsStr::new("android") {
78+
return super::init::generate_android_out_file(
79+
&path,
80+
&out_dir,
81+
&plugin_id.replace('.', "/"),
82+
&mut created_dirs,
83+
);
84+
}
85+
}
86+
87+
Ok(None)
88+
},
89+
)?;
90+
91+
let metadata = super::init::crates_metadata()?;
92+
93+
let cargo_toml_addition = format!(
94+
r#"
95+
[build-dependencies]
96+
tauri-build = "{}"
97+
"#,
98+
metadata.tauri_build
99+
);
100+
let build_file = super::init::TEMPLATE_DIR
101+
.get_file("build.rs")
102+
.unwrap()
103+
.contents_utf8()
104+
.unwrap();
105+
let init_fn = format!(
106+
r#"
107+
pub fn init<R: Runtime>() -> TauriPlugin<R> {{
108+
Builder::new("{name}")
109+
.setup(|app| {{
110+
#[cfg(target_os = "android")]
111+
app.initialize_android_plugin("{name}", "{identifier}, "ExamplePlugin")?;
112+
Ok(())
113+
}})
114+
.build()
115+
}}
116+
"#,
117+
name = options.plugin_name,
118+
identifier = plugin_id
119+
);
120+
121+
log::info!("Android project added");
122+
println!("You must add the following to the Cargo.toml file:\n{cargo_toml_addition}",);
123+
println!("You must add the following code to the build.rs file:\n\n{build_file}",);
124+
println!("Your plugin's init function under src/lib.rs must initialize the Android plugin:\n{init_fn}");
125+
}
126+
}
127+
128+
Ok(())
129+
}

0 commit comments

Comments
 (0)