Skip to content

Commit a9c8e56

Browse files
authored
feat: add android open and ios open commands (#4946)
1 parent a9f8ac7 commit a9c8e56

File tree

7 files changed

+154
-13
lines changed

7 files changed

+154
-13
lines changed

.changes/mobile-open.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 `android open` and `ios open` commands.

tooling/cli/Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tooling/cli/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ path = "src/main.rs"
3030
bossy = { git = "https://github.com/lucasfernog/bossy", branch = "fix/winapi-features" }
3131

3232
[dependencies]
33-
# cargo-mobile = { path = "../../../cargo-mobile/", default-features = false }
33+
#cargo-mobile = { path = "../../../cargo-mobile/", default-features = false }
3434
cargo-mobile = { git = "https://github.com/tauri-apps/cargo-mobile", branch = "feat/library", default-features = false }
3535
bossy = "0.2"
3636
textwrap = { version = "0.11.0", features = ["term_size"] }

tooling/cli/src/mobile/android.rs

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,37 @@
22
// SPDX-License-Identifier: Apache-2.0
33
// SPDX-License-Identifier: MIT
44

5+
use cargo_mobile::{
6+
android::config::{Config as AndroidConfig, Metadata as AndroidMetadata},
7+
config::{metadata::Metadata, Config},
8+
os,
9+
util::cli::TextWrapper,
10+
};
511
use clap::{Parser, Subcommand};
612

7-
use super::init::{command as init_command, Options as InitOptions, Target as InitTarget};
13+
use super::{
14+
ensure_init,
15+
init::{command as init_command, Options as InitOptions},
16+
Target,
17+
};
818
use crate::Result;
919

1020
pub(crate) mod project;
1121

22+
#[derive(Debug, thiserror::Error)]
23+
enum Error {
24+
#[error("{0}")]
25+
ProjectNotInitialized(String),
26+
#[error(transparent)]
27+
ConfigFailed(cargo_mobile::config::LoadOrGenError),
28+
#[error(transparent)]
29+
MetadataFailed(cargo_mobile::config::metadata::Error),
30+
#[error("Android is marked as unsupported in your configuration file")]
31+
Unsupported,
32+
#[error(transparent)]
33+
OpenFailed(os::OpenFileError),
34+
}
35+
1236
#[derive(Parser)]
1337
#[clap(
1438
author,
@@ -25,12 +49,38 @@ pub struct Cli {
2549
#[derive(Subcommand)]
2650
enum Commands {
2751
Init(InitOptions),
52+
Open,
2853
}
2954

3055
pub fn command(cli: Cli) -> Result<()> {
3156
match cli.command {
32-
Commands::Init(options) => init_command(options, InitTarget::Android)?,
57+
Commands::Init(options) => init_command(options, Target::Android)?,
58+
Commands::Open => open()?,
59+
}
60+
61+
Ok(())
62+
}
63+
64+
fn with_config(
65+
wrapper: &TextWrapper,
66+
f: impl FnOnce(&AndroidConfig, &AndroidMetadata) -> Result<(), Error>,
67+
) -> Result<(), Error> {
68+
let (config, _origin) =
69+
Config::load_or_gen(".", true.into(), wrapper).map_err(Error::ConfigFailed)?;
70+
let metadata = Metadata::load(config.app().root_dir()).map_err(Error::MetadataFailed)?;
71+
if metadata.android().supported() {
72+
f(config.android(), metadata.android())
73+
} else {
74+
Err(Error::Unsupported)
3375
}
76+
}
3477

78+
fn open() -> Result<()> {
79+
let wrapper = TextWrapper::with_splitter(textwrap::termwidth(), textwrap::NoHyphenation);
80+
with_config(&wrapper, |config, _metadata| {
81+
ensure_init(config.project_dir(), Target::Android)
82+
.map_err(|e| Error::ProjectNotInitialized(e.to_string()))?;
83+
os::open_file_with("Android Studio", config.project_dir()).map_err(Error::OpenFailed)
84+
})?;
3585
Ok(())
3686
}

tooling/cli/src/mobile/init.rs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// SPDX-License-Identifier: Apache-2.0
33
// SPDX-License-Identifier: MIT
44

5+
use super::Target;
56
use crate::helpers::{app_paths::tauri_dir, template::JsonMap};
67
use crate::Result;
78
use cargo_mobile::{
@@ -89,13 +90,6 @@ pub enum Error {
8990
OpenInEditor(util::OpenInEditorError),
9091
}
9192

92-
#[derive(PartialEq, Eq)]
93-
pub enum Target {
94-
Android,
95-
#[cfg(target_os = "macos")]
96-
Ios,
97-
}
98-
9993
pub fn exec(
10094
target: Target,
10195
wrapper: &TextWrapper,

tooling/cli/src/mobile/ios.rs

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,37 @@
22
// SPDX-License-Identifier: Apache-2.0
33
// SPDX-License-Identifier: MIT
44

5+
use cargo_mobile::{
6+
apple::config::{Config as AppleConfig, Metadata as AppleMetadata},
7+
config::{metadata::Metadata, Config},
8+
os,
9+
util::cli::TextWrapper,
10+
};
511
use clap::{Parser, Subcommand};
612

7-
use super::init::{command as init_command, Options as InitOptions, Target as InitTarget};
13+
use super::{
14+
ensure_init,
15+
init::{command as init_command, Options as InitOptions},
16+
Target,
17+
};
818
use crate::Result;
919

1020
pub(crate) mod project;
1121

22+
#[derive(Debug, thiserror::Error)]
23+
enum Error {
24+
#[error("{0}")]
25+
ProjectNotInitialized(String),
26+
#[error(transparent)]
27+
ConfigFailed(cargo_mobile::config::LoadOrGenError),
28+
#[error(transparent)]
29+
MetadataFailed(cargo_mobile::config::metadata::Error),
30+
#[error("iOS is marked as unsupported in your configuration file")]
31+
Unsupported,
32+
#[error(transparent)]
33+
OpenFailed(os::OpenFileError),
34+
}
35+
1236
#[derive(Parser)]
1337
#[clap(
1438
author,
@@ -25,12 +49,38 @@ pub struct Cli {
2549
#[derive(Subcommand)]
2650
enum Commands {
2751
Init(InitOptions),
52+
Open,
2853
}
2954

3055
pub fn command(cli: Cli) -> Result<()> {
3156
match cli.command {
32-
Commands::Init(options) => init_command(options, InitTarget::Ios)?,
57+
Commands::Init(options) => init_command(options, Target::Ios)?,
58+
Commands::Open => open()?,
59+
}
60+
61+
Ok(())
62+
}
63+
64+
fn with_config(
65+
wrapper: &TextWrapper,
66+
f: impl FnOnce(&AppleConfig, &AppleMetadata) -> Result<(), Error>,
67+
) -> Result<(), Error> {
68+
let (config, _origin) =
69+
Config::load_or_gen(".", true.into(), wrapper).map_err(Error::ConfigFailed)?;
70+
let metadata = Metadata::load(config.app().root_dir()).map_err(Error::MetadataFailed)?;
71+
if metadata.apple().supported() {
72+
f(config.apple(), metadata.apple())
73+
} else {
74+
Err(Error::Unsupported)
3375
}
76+
}
3477

78+
fn open() -> Result<()> {
79+
let wrapper = TextWrapper::with_splitter(textwrap::termwidth(), textwrap::NoHyphenation);
80+
with_config(&wrapper, |config, _metadata| {
81+
ensure_init(config.project_dir(), Target::Ios)
82+
.map_err(|e| Error::ProjectNotInitialized(e.to_string()))?;
83+
os::open_file_with("Xcode", config.project_dir()).map_err(Error::OpenFailed)
84+
})?;
3585
Ok(())
3686
}

tooling/cli/src/mobile/mod.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,48 @@
22
// SPDX-License-Identifier: Apache-2.0
33
// SPDX-License-Identifier: MIT
44

5+
use anyhow::{bail, Result};
6+
use std::path::PathBuf;
7+
58
pub mod android;
69
mod init;
710
#[cfg(target_os = "macos")]
811
pub mod ios;
12+
13+
#[derive(PartialEq, Eq)]
14+
pub enum Target {
15+
Android,
16+
#[cfg(target_os = "macos")]
17+
Ios,
18+
}
19+
20+
impl Target {
21+
fn ide_name(&self) -> &'static str {
22+
match self {
23+
Self::Android => "Android Studio",
24+
#[cfg(target_os = "macos")]
25+
Self::Ios => "Xcode",
26+
}
27+
}
28+
29+
fn command_name(&self) -> &'static str {
30+
match self {
31+
Self::Android => "android",
32+
#[cfg(target_os = "macos")]
33+
Self::Ios => "ios",
34+
}
35+
}
36+
}
37+
38+
fn ensure_init(project_dir: PathBuf, target: Target) -> Result<()> {
39+
if !project_dir.exists() {
40+
bail!(
41+
"{} project directory {} doesn't exist. Please run `tauri {} init` and try again.",
42+
target.ide_name(),
43+
project_dir.display(),
44+
target.command_name(),
45+
)
46+
} else {
47+
Ok(())
48+
}
49+
}

0 commit comments

Comments
 (0)