Skip to content

Commit

Permalink
refactor(cli): enhance plugin commands for mobile (#6289)
Browse files Browse the repository at this point in the history
  • Loading branch information
lucasfernog authored Feb 16, 2023
1 parent f5e272b commit 14d03d4
Show file tree
Hide file tree
Showing 87 changed files with 406 additions and 401 deletions.
6 changes: 6 additions & 0 deletions .changes/add-mobile-to-plugin.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"cli.rs": minor
"cli.js": minor
---

Added `plugin android add` and `plugin ios add` commands to add mobile plugin functionality to existing projects.
6 changes: 6 additions & 0 deletions .changes/plugin-init-refactor.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"cli.rs": minor
"cli.js": minor
---

Changed the `--api` flag on `plugin init` to `--no-api`.
28 changes: 11 additions & 17 deletions tooling/cli/src/helpers/template.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,27 +42,21 @@ pub fn render<P: AsRef<Path>, D: Serialize>(
) -> crate::Result<()> {
let out_dir = out_dir.as_ref();
let mut created_dirs = Vec::new();
render_with_generator(
handlebars,
data,
dir,
out_dir,
&mut |file_path: &PathBuf| {
let path = out_dir.join(file_path);
let parent = path.parent().unwrap().to_path_buf();
if !created_dirs.contains(&parent) {
create_dir_all(&parent)?;
created_dirs.push(parent);
}
File::create(path).map(Some)
},
)
render_with_generator(handlebars, data, dir, out_dir, &mut |file_path: PathBuf| {
let path = out_dir.join(file_path);
let parent = path.parent().unwrap().to_path_buf();
if !created_dirs.contains(&parent) {
create_dir_all(&parent)?;
created_dirs.push(parent);
}
File::create(path).map(Some)
})
}

pub fn render_with_generator<
P: AsRef<Path>,
D: Serialize,
F: FnMut(&PathBuf) -> std::io::Result<Option<File>>,
F: FnMut(PathBuf) -> std::io::Result<Option<File>>,
>(
handlebars: &Handlebars<'_>,
data: &D,
Expand All @@ -80,7 +74,7 @@ pub fn render_with_generator<
file_path.set_extension("toml");
}
}
if let Some(mut output_file) = out_file_generator(&file_path)? {
if let Some(mut output_file) = out_file_generator(file_path)? {
if let Some(utf8) = file.contents_utf8() {
handlebars
.render_template_to_write(utf8, &data, &mut output_file)
Expand Down
2 changes: 1 addition & 1 deletion tooling/cli/src/mobile/android/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ pub fn gen(
map.inner(),
&TEMPLATE_DIR,
&dest,
&mut |path| generate_out_file(path, &dest, &package_path, &mut created_dirs),
&mut |path| generate_out_file(&path, &dest, &package_path, &mut created_dirs),
)
.with_context(|| "failed to process template")?;

Expand Down
6 changes: 6 additions & 0 deletions tooling/cli/src/plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ use clap::{Parser, Subcommand};

use crate::Result;

mod android;
mod init;
mod ios;

#[derive(Parser)]
#[clap(
Expand All @@ -24,11 +26,15 @@ pub struct Cli {
#[derive(Subcommand)]
enum Commands {
Init(init::Options),
Android(android::Cli),
Ios(ios::Cli),
}

pub fn command(cli: Cli) -> Result<()> {
match cli.command {
Commands::Init(options) => init::command(options)?,
Commands::Android(cli) => android::command(cli)?,
Commands::Ios(cli) => ios::command(cli)?,
}

Ok(())
Expand Down
129 changes: 129 additions & 0 deletions tooling/cli/src/plugin/android.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
// Copyright 2019-2022 Tauri Programme within The Commons Conservancy
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT

use crate::{helpers::template, Result};
use clap::{Parser, Subcommand};
use handlebars::Handlebars;

use std::{
collections::BTreeMap,
env::current_dir,
ffi::OsStr,
path::{Component, PathBuf},
};

#[derive(Parser)]
#[clap(
author,
version,
about = "Manage the Android project for Tauri plugins",
subcommand_required(true),
arg_required_else_help(true)
)]
pub struct Cli {
#[clap(subcommand)]
command: Commands,
}

#[derive(Subcommand)]
enum Commands {
Add(AddOptions),
}

#[derive(Debug, Parser)]
#[clap(about = "Adds the Android project to an existing Tauri plugin")]
pub struct AddOptions {
/// Name of your Tauri plugin. Must match the current plugin's name.
#[clap(short = 'n', long = "name")]
plugin_name: String,
/// The output directory.
#[clap(short, long)]
#[clap(default_value_t = current_dir().expect("failed to read cwd").to_string_lossy().into_owned())]
out_dir: String,
}

pub fn command(cli: Cli) -> Result<()> {
match cli.command {
Commands::Add(options) => {
let out_dir = PathBuf::from(options.out_dir);
if out_dir.join("android").exists() {
return Err(anyhow::anyhow!("android folder already exists"));
}

let plugin_id = super::init::request_input(
"What should be the Android Package ID for your plugin?",
Some(format!("com.plugin.{}", options.plugin_name)),
false,
false,
)?
.unwrap();

let handlebars = Handlebars::new();

let mut data = BTreeMap::new();
super::init::plugin_name_data(&mut data, &options.plugin_name);

let mut created_dirs = Vec::new();
template::render_with_generator(
&handlebars,
&data,
&super::init::TEMPLATE_DIR,
&out_dir,
&mut |path| {
let mut components = path.components();
let root = components.next().unwrap();
if let Component::Normal(component) = root {
if component == OsStr::new("android") {
return super::init::generate_android_out_file(
&path,
&out_dir,
&plugin_id.replace('.', "/"),
&mut created_dirs,
);
}
}

Ok(None)
},
)?;

let metadata = super::init::crates_metadata()?;

let cargo_toml_addition = format!(
r#"
[build-dependencies]
tauri-build = "{}"
"#,
metadata.tauri_build
);
let build_file = super::init::TEMPLATE_DIR
.get_file("build.rs")
.unwrap()
.contents_utf8()
.unwrap();
let init_fn = format!(
r#"
pub fn init<R: Runtime>() -> TauriPlugin<R> {{
Builder::new("{name}")
.setup(|app| {{
#[cfg(target_os = "android")]
app.initialize_android_plugin("{name}", "{identifier}, "ExamplePlugin")?;
Ok(())
}})
.build()
}}
"#,
name = options.plugin_name,
identifier = plugin_id
);

log::info!("Android project added");
println!("You must add the following to the Cargo.toml file:\n{cargo_toml_addition}",);
println!("You must add the following code to the build.rs file:\n\n{build_file}",);
println!("Your plugin's init function under src/lib.rs must initialize the Android plugin:\n{init_fn}");
}
}

Ok(())
}
Loading

0 comments on commit 14d03d4

Please sign in to comment.