Skip to content

Commit

Permalink
feat(cli.rs): add init plugin command, bootstraps a plugin project (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
lucasfernog authored Sep 27, 2021
1 parent 3a59f5f commit ac8e69a
Show file tree
Hide file tree
Showing 98 changed files with 1,616 additions and 96 deletions.
5 changes: 5 additions & 0 deletions .changes/plugin-command.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"cli.rs": patch
---

Added `$ tauri init plugin` command, which initializes a Tauri plugin.
105 changes: 80 additions & 25 deletions docs/api/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,30 +29,76 @@ This command is pretty helpful when you need to have a quick overview of your ap
<Command name="init" />

```
Description
Inits the Tauri template. If Tauri cannot find the src-tauri/tauri.conf.json
it will create one.
Usage
$ tauri init
Options
--help, -h Displays this message
--force, -f Force init to overwrite [conf|template|all]
--log, -l Logging [boolean]
--directory, -d Set target directory for init
--tauriPath, -t Path of the Tauri project to use (relative to the cwd)
Initializes a Tauri project
USAGE:
cargo tauri init [FLAGS] [OPTIONS] [SUBCOMMAND]
FLAGS:
--ci Skip prompting for values
-f, --force Force init to overwrite the src-tauri folder
-h, --help Print help information
-l, --log Enables logging
-V, --version Print version information
OPTIONS:
-A, --app-name <app-name> Name of your Tauri application
-d, --directory <directory> Set target directory for init
-D, --dist-dir <dist-dir> Web assets location, relative to <project-dir>/src-tauri
-P, --dev-path <dev-path> Url of your dev server
-t, --tauri-path <tauri-path> Path of the Tauri project to use (relative to the cwd)
-W, --window-title <window-title> Window title of your Tauri application
SUBCOMMANDS:
help Print this message or the help of the given subcommand(s)
plugin Initialize a Tauri plugin.
```

### `init plugin`

<Command name="init plugin" />

```
Initializes a Tauri plugin project.
USAGE:
cargo tauri init plugin [FLAGS] [OPTIONS] --name <name>
FLAGS:
-a, --api Initializes a Tauri plugin with TypeScript API.
-h, --help Print help information
-V, --version Print version information
OPTIONS:
-d, --directory <directory> Set target directory for init
-n, --name <name> Name of your Tauri plugin
-t, --tauri-path <tauri-path> Path of the Tauri project to use (relative to the cwd)
```

## `dev`

<Command name="dev" />

```
Description
Tauri dev.
Usage
$ tauri dev
Options
--help, -h Displays this message
Tauri dev.
USAGE:
cargo tauri dev [FLAGS] [OPTIONS] [--] [args]...
ARGS:
<args>... Args passed to the binary
FLAGS:
-e, --exit-on-panic Exit on panic
-h, --help Print help information
--release Run the code in release mode
-V, --version Print version information
OPTIONS:
-c, --config <config> config JSON to merge with tauri.conf.json
-f, --features <features>... list of cargo features to activate
-r, --runner <runner> binary to use to run the application
-t, --target <target>... target triple to build against
```

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.
Expand Down Expand Up @@ -83,13 +129,23 @@ If you're not using `build.beforeDevCommand`, make sure your `build.devPath` is
<Command name="build" />

```
Description
Tauri build.
Usage
$ tauri build
Options
--help, -h Displays this message
--debug, -d Build a tauri app with debugging
Tauri build.
USAGE:
cargo tauri build [FLAGS] [OPTIONS]
FLAGS:
-d, --debug Builds with the debug flag
-h, --help Print help information
-v, --verbose Enables verbose logging
-V, --version Print version information
OPTIONS:
-b, --bundle <bundle>... list of bundles to package
-c, --config <config> config JSON to merge with tauri.conf.json
-f, --features <features>... list of cargo features to activate
-r, --runner <runner> binary to use to build the application
-t, --target <target>... target triple to build against
```

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.
Expand Down Expand Up @@ -133,4 +189,3 @@ This command will show the current version of Tauri.
## CLI usage

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

16 changes: 9 additions & 7 deletions docs/usage/guides/plugin.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@ title: Write Tauri Plugins
import Alert from '@theme/Alert'

<Alert title="Note" icon="info-alt">
Tauri will soon offer Plugin starter kits so the process of writing a Plugin crate will be simplified.

For now it's recommended to follow the [official Tauri plugins](#official-tauri-plugins).
The Tauri CLI can bootstrap a Plugin project with the `$ tauri init plugin --name your-plugin-name` command.
It setups the recommended folder structure, optionally adding a TypeScript API wrapper with the `--api` flag.
</Alert>

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

## Official Tauri Plugins

- [Stronghold (WIP)](https://github.com/tauri-apps/tauri-plugin-stronghold)
- [Authenticator (WIP)](https://github.com/tauri-apps/tauri-plugin-authenticator)
- [Logging (WIP)](https://github.com/tauri-apps/tauri-plugin-log)
- [SQL (WIP)](https://github.com/tauri-apps/tauri-plugin-sql)
- [Stronghold](https://github.com/tauri-apps/tauri-plugin-stronghold)
- [Authenticator](https://github.com/tauri-apps/tauri-plugin-authenticator)
- [Logging](https://github.com/tauri-apps/tauri-plugin-log)
- [SQL](https://github.com/tauri-apps/tauri-plugin-sql)
- [WebSocket](https://github.com/tauri-apps/tauri-plugin-websocket)
- [Restoring window state](https://github.com/tauri-apps/tauri-plugin-window-state)
- [Store](https://github.com/tauri-apps/tauri-plugin-store)
4 changes: 1 addition & 3 deletions tooling/cli.rs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,12 @@ unicode-width = "0.1"
tempfile = "3"
zeroize = "1.4"
glob = "0.3"
heck = "0.3"

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

[target."cfg(target_os = \"linux\")".dependencies]
heck = "0.3"

[target."cfg(target_os = \"linux\")".build-dependencies]
heck = "0.3"

Expand Down
26 changes: 25 additions & 1 deletion tooling/cli.rs/src/cli.yml
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ subcommands:
- info:
about: Shows information about Tauri dependencies
- init:
about: Initializes a Tauri project
about: Initializes a Tauri project.
args:
- ci:
long: ci
Expand Down Expand Up @@ -171,3 +171,27 @@ subcommands:
long: dev-path
about: Url of your dev server
takes_value: true
subcommands:
- plugin:
about: Initializes a Tauri plugin project.
args:
- name:
short: n
long: name
about: Name of your Tauri plugin
takes_value: true
required: true
- directory:
short: d
long: directory
about: Set target directory for init
takes_value: true
- tauri-path:
short: t
long: tauri-path
about: Path of the Tauri project to use (relative to the cwd)
takes_value: true
- api:
short: a
long: api
about: Initializes a Tauri plugin with TypeScript API.
11 changes: 11 additions & 0 deletions tooling/cli.rs/src/helpers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@ pub mod config;
pub mod framework;
mod logger;
pub mod manifest;
pub mod template;
pub mod updater_signature;

pub use logger::Logger;

use std::{
collections::HashMap,
io::{BufRead, BufReader},
path::{Path, PathBuf},
process::{Command, Stdio},
};

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

map
}

pub fn resolve_tauri_path<P: AsRef<Path>>(path: P, crate_name: &str) -> PathBuf {
let path = path.as_ref();
if path.is_absolute() {
path.join(crate_name)
} else {
PathBuf::from("..").join(path).join(crate_name)
}
}
44 changes: 44 additions & 0 deletions tooling/cli.rs/src/helpers/template.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright 2019-2021 Tauri Programme within The Commons Conservancy
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT

use std::{
collections::BTreeMap,
fs::{create_dir_all, File},
io::Write,
path::Path,
};

use handlebars::Handlebars;
use include_dir::Dir;

pub fn render<P: AsRef<Path>>(
handlebars: &Handlebars,
data: &BTreeMap<&str, serde_json::Value>,
dir: &Dir,
out_dir: P,
) -> crate::Result<()> {
create_dir_all(out_dir.as_ref().join(dir.path()))?;
for file in dir.files() {
let mut file_path = file.path().to_path_buf();
// cargo for some reason ignores the /templates folder packaging when it has a Cargo.toml file inside
// so we rename the extension to `.crate-manifest`
if let Some(extension) = file_path.extension() {
if extension == "crate-manifest" {
file_path.set_extension("toml");
}
}
let mut output_file = File::create(out_dir.as_ref().join(file_path))?;
if let Some(utf8) = file.contents_utf8() {
handlebars
.render_template_to_write(utf8, &data, &mut output_file)
.expect("Failed to render template");
} else {
output_file.write_all(file.contents())?;
}
}
for dir in dir.dirs() {
render(handlebars, data, dir, out_dir.as_ref())?;
}
Ok(())
}
67 changes: 8 additions & 59 deletions tooling/cli.rs/src/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,17 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT

use std::{
collections::BTreeMap,
env::current_dir,
fs::{create_dir_all, remove_dir_all, File},
io::Write,
path::{Path, PathBuf},
};
use std::{collections::BTreeMap, env::current_dir, fs::remove_dir_all, path::PathBuf};

use crate::helpers::Logger;
use crate::{
helpers::{resolve_tauri_path, template, Logger},
VersionMetadata,
};
use anyhow::Context;
use handlebars::{to_json, Handlebars};
use include_dir::{include_dir, Dir};
use serde::Deserialize;

const TEMPLATE_DIR: Dir = include_dir!("templates");

#[derive(Deserialize)]
struct VersionMetadata {
tauri: String,
#[serde(rename = "tauri-build")]
tauri_build: String,
}
const TEMPLATE_DIR: Dir = include_dir!("templates/app");

pub struct Init {
force: bool,
Expand Down Expand Up @@ -95,7 +84,7 @@ impl Init {
let metadata = serde_json::from_str::<VersionMetadata>(include_str!("../metadata.json"))?;
if template_target_path.exists() && !self.force {
logger.warn(format!(
"Tauri dir ({:?}) not empty. Run `init --force template` to overwrite.",
"Tauri dir ({:?}) not empty. Run `init --force` to overwrite.",
template_target_path
));
} else {
Expand Down Expand Up @@ -144,50 +133,10 @@ impl Init {
to_json(self.window_title.unwrap_or_else(|| "Tauri".to_string())),
);

render_template(&handlebars, &data, &TEMPLATE_DIR, &self.directory)
template::render(&handlebars, &data, &TEMPLATE_DIR, &self.directory)
.with_context(|| "failed to render Tauri template")?;
}

Ok(())
}
}

fn render_template<P: AsRef<Path>>(
handlebars: &Handlebars,
data: &BTreeMap<&str, serde_json::Value>,
dir: &Dir,
out_dir: P,
) -> crate::Result<()> {
create_dir_all(out_dir.as_ref().join(dir.path()))?;
for file in dir.files() {
let mut file_path = file.path().to_path_buf();
// cargo for some reason ignores the /templates folder packaging when it has a Cargo.toml file inside
// so we rename the extension to `.crate-manifest`
if let Some(extension) = file_path.extension() {
if extension == "crate-manifest" {
file_path.set_extension("toml");
}
}
let mut output_file = File::create(out_dir.as_ref().join(file_path))?;
if let Some(utf8) = file.contents_utf8() {
handlebars
.render_template_to_write(utf8, &data, &mut output_file)
.expect("Failed to render template");
} else {
output_file.write_all(file.contents())?;
}
}
for dir in dir.dirs() {
render_template(handlebars, data, dir, out_dir.as_ref())?;
}
Ok(())
}

fn resolve_tauri_path<P: AsRef<Path>>(path: P, crate_name: &str) -> PathBuf {
let path = path.as_ref();
if path.is_absolute() {
path.join(crate_name)
} else {
PathBuf::from("..").join(path).join(crate_name)
}
}
Loading

0 comments on commit ac8e69a

Please sign in to comment.