Skip to content

Commit ac8e69a

Browse files
authored
feat(cli.rs): add init plugin command, bootstraps a plugin project (#2669)
1 parent 3a59f5f commit ac8e69a

File tree

98 files changed

+1616
-96
lines changed

Some content is hidden

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

98 files changed

+1616
-96
lines changed

.changes/plugin-command.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"cli.rs": patch
3+
---
4+
5+
Added `$ tauri init plugin` command, which initializes a Tauri plugin.

docs/api/cli.md

Lines changed: 80 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -29,30 +29,76 @@ This command is pretty helpful when you need to have a quick overview of your ap
2929
<Command name="init" />
3030

3131
```
32-
Description
33-
Inits the Tauri template. If Tauri cannot find the src-tauri/tauri.conf.json
34-
it will create one.
35-
Usage
36-
$ tauri init
37-
Options
38-
--help, -h Displays this message
39-
--force, -f Force init to overwrite [conf|template|all]
40-
--log, -l Logging [boolean]
41-
--directory, -d Set target directory for init
42-
--tauriPath, -t Path of the Tauri project to use (relative to the cwd)
32+
Initializes a Tauri project
33+
34+
USAGE:
35+
cargo tauri init [FLAGS] [OPTIONS] [SUBCOMMAND]
36+
37+
FLAGS:
38+
--ci Skip prompting for values
39+
-f, --force Force init to overwrite the src-tauri folder
40+
-h, --help Print help information
41+
-l, --log Enables logging
42+
-V, --version Print version information
43+
44+
OPTIONS:
45+
-A, --app-name <app-name> Name of your Tauri application
46+
-d, --directory <directory> Set target directory for init
47+
-D, --dist-dir <dist-dir> Web assets location, relative to <project-dir>/src-tauri
48+
-P, --dev-path <dev-path> Url of your dev server
49+
-t, --tauri-path <tauri-path> Path of the Tauri project to use (relative to the cwd)
50+
-W, --window-title <window-title> Window title of your Tauri application
51+
52+
SUBCOMMANDS:
53+
help Print this message or the help of the given subcommand(s)
54+
plugin Initialize a Tauri plugin.
55+
```
56+
57+
### `init plugin`
58+
59+
<Command name="init plugin" />
60+
61+
```
62+
Initializes a Tauri plugin project.
63+
64+
USAGE:
65+
cargo tauri init plugin [FLAGS] [OPTIONS] --name <name>
66+
67+
FLAGS:
68+
-a, --api Initializes a Tauri plugin with TypeScript API.
69+
-h, --help Print help information
70+
-V, --version Print version information
71+
72+
OPTIONS:
73+
-d, --directory <directory> Set target directory for init
74+
-n, --name <name> Name of your Tauri plugin
75+
-t, --tauri-path <tauri-path> Path of the Tauri project to use (relative to the cwd)
4376
```
4477

4578
## `dev`
4679

4780
<Command name="dev" />
4881

4982
```
50-
Description
51-
Tauri dev.
52-
Usage
53-
$ tauri dev
54-
Options
55-
--help, -h Displays this message
83+
Tauri dev.
84+
85+
USAGE:
86+
cargo tauri dev [FLAGS] [OPTIONS] [--] [args]...
87+
88+
ARGS:
89+
<args>... Args passed to the binary
90+
91+
FLAGS:
92+
-e, --exit-on-panic Exit on panic
93+
-h, --help Print help information
94+
--release Run the code in release mode
95+
-V, --version Print version information
96+
97+
OPTIONS:
98+
-c, --config <config> config JSON to merge with tauri.conf.json
99+
-f, --features <features>... list of cargo features to activate
100+
-r, --runner <runner> binary to use to run the application
101+
-t, --target <target>... target triple to build against
56102
```
57103

58104
This command will open the WebView in development mode. It makes use of the `build.devPath` property from your `src-tauri/tauri.conf.json` file.
@@ -83,13 +129,23 @@ If you're not using `build.beforeDevCommand`, make sure your `build.devPath` is
83129
<Command name="build" />
84130

85131
```
86-
Description
87-
Tauri build.
88-
Usage
89-
$ tauri build
90-
Options
91-
--help, -h Displays this message
92-
--debug, -d Build a tauri app with debugging
132+
Tauri build.
133+
134+
USAGE:
135+
cargo tauri build [FLAGS] [OPTIONS]
136+
137+
FLAGS:
138+
-d, --debug Builds with the debug flag
139+
-h, --help Print help information
140+
-v, --verbose Enables verbose logging
141+
-V, --version Print version information
142+
143+
OPTIONS:
144+
-b, --bundle <bundle>... list of bundles to package
145+
-c, --config <config> config JSON to merge with tauri.conf.json
146+
-f, --features <features>... list of cargo features to activate
147+
-r, --runner <runner> binary to use to build the application
148+
-t, --target <target>... target triple to build against
93149
```
94150

95151
This command will bundle your application, either in production mode or debug mode if you used the `--debug` flag. It makes use of the `build.distDir` property from your `src-tauri/tauri.conf.json` file.
@@ -133,4 +189,3 @@ This command will show the current version of Tauri.
133189
## CLI usage
134190

135191
See more about the usage through this [complete guide](/docs/usage/development/integration).
136-

docs/usage/guides/plugin.md

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,8 @@ title: Write Tauri Plugins
55
import Alert from '@theme/Alert'
66

77
<Alert title="Note" icon="info-alt">
8-
Tauri will soon offer Plugin starter kits so the process of writing a Plugin crate will be simplified.
9-
10-
For now it's recommended to follow the [official Tauri plugins](#official-tauri-plugins).
8+
The Tauri CLI can bootstrap a Plugin project with the `$ tauri init plugin --name your-plugin-name` command.
9+
It setups the recommended folder structure, optionally adding a TypeScript API wrapper with the `--api` flag.
1110
</Alert>
1211

1312
Plugins allow you to hook into the Tauri application lifecycle and introduce new commands.
@@ -94,7 +93,10 @@ fn main() {
9493

9594
## Official Tauri Plugins
9695

97-
- [Stronghold (WIP)](https://github.com/tauri-apps/tauri-plugin-stronghold)
98-
- [Authenticator (WIP)](https://github.com/tauri-apps/tauri-plugin-authenticator)
99-
- [Logging (WIP)](https://github.com/tauri-apps/tauri-plugin-log)
100-
- [SQL (WIP)](https://github.com/tauri-apps/tauri-plugin-sql)
96+
- [Stronghold](https://github.com/tauri-apps/tauri-plugin-stronghold)
97+
- [Authenticator](https://github.com/tauri-apps/tauri-plugin-authenticator)
98+
- [Logging](https://github.com/tauri-apps/tauri-plugin-log)
99+
- [SQL](https://github.com/tauri-apps/tauri-plugin-sql)
100+
- [WebSocket](https://github.com/tauri-apps/tauri-plugin-websocket)
101+
- [Restoring window state](https://github.com/tauri-apps/tauri-plugin-window-state)
102+
- [Store](https://github.com/tauri-apps/tauri-plugin-store)

tooling/cli.rs/Cargo.toml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,12 @@ unicode-width = "0.1"
4747
tempfile = "3"
4848
zeroize = "1.4"
4949
glob = "0.3"
50+
heck = "0.3"
5051

5152
[target."cfg(windows)".dependencies]
5253
winapi = { version = "0.3", features = [ "winbase", "winuser", "consoleapi", "processenv", "wincon" ] }
5354
encode_unicode = "0.3"
5455

55-
[target."cfg(target_os = \"linux\")".dependencies]
56-
heck = "0.3"
57-
5856
[target."cfg(target_os = \"linux\")".build-dependencies]
5957
heck = "0.3"
6058

tooling/cli.rs/src/cli.yml

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ subcommands:
128128
- info:
129129
about: Shows information about Tauri dependencies
130130
- init:
131-
about: Initializes a Tauri project
131+
about: Initializes a Tauri project.
132132
args:
133133
- ci:
134134
long: ci
@@ -171,3 +171,27 @@ subcommands:
171171
long: dev-path
172172
about: Url of your dev server
173173
takes_value: true
174+
subcommands:
175+
- plugin:
176+
about: Initializes a Tauri plugin project.
177+
args:
178+
- name:
179+
short: n
180+
long: name
181+
about: Name of your Tauri plugin
182+
takes_value: true
183+
required: true
184+
- directory:
185+
short: d
186+
long: directory
187+
about: Set target directory for init
188+
takes_value: true
189+
- tauri-path:
190+
short: t
191+
long: tauri-path
192+
about: Path of the Tauri project to use (relative to the cwd)
193+
takes_value: true
194+
- api:
195+
short: a
196+
long: api
197+
about: Initializes a Tauri plugin with TypeScript API.

tooling/cli.rs/src/helpers/mod.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,15 @@ pub mod config;
77
pub mod framework;
88
mod logger;
99
pub mod manifest;
10+
pub mod template;
1011
pub mod updater_signature;
1112

1213
pub use logger::Logger;
1314

1415
use std::{
1516
collections::HashMap,
1617
io::{BufRead, BufReader},
18+
path::{Path, PathBuf},
1719
process::{Command, Stdio},
1820
};
1921

@@ -55,3 +57,12 @@ pub fn command_env() -> HashMap<String, String> {
5557

5658
map
5759
}
60+
61+
pub fn resolve_tauri_path<P: AsRef<Path>>(path: P, crate_name: &str) -> PathBuf {
62+
let path = path.as_ref();
63+
if path.is_absolute() {
64+
path.join(crate_name)
65+
} else {
66+
PathBuf::from("..").join(path).join(crate_name)
67+
}
68+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// Copyright 2019-2021 Tauri Programme within The Commons Conservancy
2+
// SPDX-License-Identifier: Apache-2.0
3+
// SPDX-License-Identifier: MIT
4+
5+
use std::{
6+
collections::BTreeMap,
7+
fs::{create_dir_all, File},
8+
io::Write,
9+
path::Path,
10+
};
11+
12+
use handlebars::Handlebars;
13+
use include_dir::Dir;
14+
15+
pub fn render<P: AsRef<Path>>(
16+
handlebars: &Handlebars,
17+
data: &BTreeMap<&str, serde_json::Value>,
18+
dir: &Dir,
19+
out_dir: P,
20+
) -> crate::Result<()> {
21+
create_dir_all(out_dir.as_ref().join(dir.path()))?;
22+
for file in dir.files() {
23+
let mut file_path = file.path().to_path_buf();
24+
// cargo for some reason ignores the /templates folder packaging when it has a Cargo.toml file inside
25+
// so we rename the extension to `.crate-manifest`
26+
if let Some(extension) = file_path.extension() {
27+
if extension == "crate-manifest" {
28+
file_path.set_extension("toml");
29+
}
30+
}
31+
let mut output_file = File::create(out_dir.as_ref().join(file_path))?;
32+
if let Some(utf8) = file.contents_utf8() {
33+
handlebars
34+
.render_template_to_write(utf8, &data, &mut output_file)
35+
.expect("Failed to render template");
36+
} else {
37+
output_file.write_all(file.contents())?;
38+
}
39+
}
40+
for dir in dir.dirs() {
41+
render(handlebars, data, dir, out_dir.as_ref())?;
42+
}
43+
Ok(())
44+
}

tooling/cli.rs/src/init.rs

Lines changed: 8 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,17 @@
22
// SPDX-License-Identifier: Apache-2.0
33
// SPDX-License-Identifier: MIT
44

5-
use std::{
6-
collections::BTreeMap,
7-
env::current_dir,
8-
fs::{create_dir_all, remove_dir_all, File},
9-
io::Write,
10-
path::{Path, PathBuf},
11-
};
5+
use std::{collections::BTreeMap, env::current_dir, fs::remove_dir_all, path::PathBuf};
126

13-
use crate::helpers::Logger;
7+
use crate::{
8+
helpers::{resolve_tauri_path, template, Logger},
9+
VersionMetadata,
10+
};
1411
use anyhow::Context;
1512
use handlebars::{to_json, Handlebars};
1613
use include_dir::{include_dir, Dir};
17-
use serde::Deserialize;
1814

19-
const TEMPLATE_DIR: Dir = include_dir!("templates");
20-
21-
#[derive(Deserialize)]
22-
struct VersionMetadata {
23-
tauri: String,
24-
#[serde(rename = "tauri-build")]
25-
tauri_build: String,
26-
}
15+
const TEMPLATE_DIR: Dir = include_dir!("templates/app");
2716

2817
pub struct Init {
2918
force: bool,
@@ -95,7 +84,7 @@ impl Init {
9584
let metadata = serde_json::from_str::<VersionMetadata>(include_str!("../metadata.json"))?;
9685
if template_target_path.exists() && !self.force {
9786
logger.warn(format!(
98-
"Tauri dir ({:?}) not empty. Run `init --force template` to overwrite.",
87+
"Tauri dir ({:?}) not empty. Run `init --force` to overwrite.",
9988
template_target_path
10089
));
10190
} else {
@@ -144,50 +133,10 @@ impl Init {
144133
to_json(self.window_title.unwrap_or_else(|| "Tauri".to_string())),
145134
);
146135

147-
render_template(&handlebars, &data, &TEMPLATE_DIR, &self.directory)
136+
template::render(&handlebars, &data, &TEMPLATE_DIR, &self.directory)
148137
.with_context(|| "failed to render Tauri template")?;
149138
}
150139

151140
Ok(())
152141
}
153142
}
154-
155-
fn render_template<P: AsRef<Path>>(
156-
handlebars: &Handlebars,
157-
data: &BTreeMap<&str, serde_json::Value>,
158-
dir: &Dir,
159-
out_dir: P,
160-
) -> crate::Result<()> {
161-
create_dir_all(out_dir.as_ref().join(dir.path()))?;
162-
for file in dir.files() {
163-
let mut file_path = file.path().to_path_buf();
164-
// cargo for some reason ignores the /templates folder packaging when it has a Cargo.toml file inside
165-
// so we rename the extension to `.crate-manifest`
166-
if let Some(extension) = file_path.extension() {
167-
if extension == "crate-manifest" {
168-
file_path.set_extension("toml");
169-
}
170-
}
171-
let mut output_file = File::create(out_dir.as_ref().join(file_path))?;
172-
if let Some(utf8) = file.contents_utf8() {
173-
handlebars
174-
.render_template_to_write(utf8, &data, &mut output_file)
175-
.expect("Failed to render template");
176-
} else {
177-
output_file.write_all(file.contents())?;
178-
}
179-
}
180-
for dir in dir.dirs() {
181-
render_template(handlebars, data, dir, out_dir.as_ref())?;
182-
}
183-
Ok(())
184-
}
185-
186-
fn resolve_tauri_path<P: AsRef<Path>>(path: P, crate_name: &str) -> PathBuf {
187-
let path = path.as_ref();
188-
if path.is_absolute() {
189-
path.join(crate_name)
190-
} else {
191-
PathBuf::from("..").join(path).join(crate_name)
192-
}
193-
}

0 commit comments

Comments
 (0)