Skip to content

Commit

Permalink
feat: add android open and ios open commands (#4946)
Browse files Browse the repository at this point in the history
  • Loading branch information
lucasfernog committed Aug 15, 2022
1 parent a9f8ac7 commit a9c8e56
Show file tree
Hide file tree
Showing 7 changed files with 154 additions and 13 deletions.
6 changes: 6 additions & 0 deletions .changes/mobile-open.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"cli.rs": minor
"cli.js": minor
---

Added `android open` and `ios open` commands.
2 changes: 1 addition & 1 deletion tooling/cli/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion tooling/cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ path = "src/main.rs"
bossy = { git = "https://github.com/lucasfernog/bossy", branch = "fix/winapi-features" }

[dependencies]
# cargo-mobile = { path = "../../../cargo-mobile/", default-features = false }
#cargo-mobile = { path = "../../../cargo-mobile/", default-features = false }
cargo-mobile = { git = "https://github.com/tauri-apps/cargo-mobile", branch = "feat/library", default-features = false }
bossy = "0.2"
textwrap = { version = "0.11.0", features = ["term_size"] }
Expand Down
54 changes: 52 additions & 2 deletions tooling/cli/src/mobile/android.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,37 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT

use cargo_mobile::{
android::config::{Config as AndroidConfig, Metadata as AndroidMetadata},
config::{metadata::Metadata, Config},
os,
util::cli::TextWrapper,
};
use clap::{Parser, Subcommand};

use super::init::{command as init_command, Options as InitOptions, Target as InitTarget};
use super::{
ensure_init,
init::{command as init_command, Options as InitOptions},
Target,
};
use crate::Result;

pub(crate) mod project;

#[derive(Debug, thiserror::Error)]
enum Error {
#[error("{0}")]
ProjectNotInitialized(String),
#[error(transparent)]
ConfigFailed(cargo_mobile::config::LoadOrGenError),
#[error(transparent)]
MetadataFailed(cargo_mobile::config::metadata::Error),
#[error("Android is marked as unsupported in your configuration file")]
Unsupported,
#[error(transparent)]
OpenFailed(os::OpenFileError),
}

#[derive(Parser)]
#[clap(
author,
Expand All @@ -25,12 +49,38 @@ pub struct Cli {
#[derive(Subcommand)]
enum Commands {
Init(InitOptions),
Open,
}

pub fn command(cli: Cli) -> Result<()> {
match cli.command {
Commands::Init(options) => init_command(options, InitTarget::Android)?,
Commands::Init(options) => init_command(options, Target::Android)?,
Commands::Open => open()?,
}

Ok(())
}

fn with_config(
wrapper: &TextWrapper,
f: impl FnOnce(&AndroidConfig, &AndroidMetadata) -> Result<(), Error>,
) -> Result<(), Error> {
let (config, _origin) =
Config::load_or_gen(".", true.into(), wrapper).map_err(Error::ConfigFailed)?;
let metadata = Metadata::load(config.app().root_dir()).map_err(Error::MetadataFailed)?;
if metadata.android().supported() {
f(config.android(), metadata.android())
} else {
Err(Error::Unsupported)
}
}

fn open() -> Result<()> {
let wrapper = TextWrapper::with_splitter(textwrap::termwidth(), textwrap::NoHyphenation);
with_config(&wrapper, |config, _metadata| {
ensure_init(config.project_dir(), Target::Android)
.map_err(|e| Error::ProjectNotInitialized(e.to_string()))?;
os::open_file_with("Android Studio", config.project_dir()).map_err(Error::OpenFailed)
})?;
Ok(())
}
8 changes: 1 addition & 7 deletions tooling/cli/src/mobile/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT

use super::Target;
use crate::helpers::{app_paths::tauri_dir, template::JsonMap};
use crate::Result;
use cargo_mobile::{
Expand Down Expand Up @@ -89,13 +90,6 @@ pub enum Error {
OpenInEditor(util::OpenInEditorError),
}

#[derive(PartialEq, Eq)]
pub enum Target {
Android,
#[cfg(target_os = "macos")]
Ios,
}

pub fn exec(
target: Target,
wrapper: &TextWrapper,
Expand Down
54 changes: 52 additions & 2 deletions tooling/cli/src/mobile/ios.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,37 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT

use cargo_mobile::{
apple::config::{Config as AppleConfig, Metadata as AppleMetadata},
config::{metadata::Metadata, Config},
os,
util::cli::TextWrapper,
};
use clap::{Parser, Subcommand};

use super::init::{command as init_command, Options as InitOptions, Target as InitTarget};
use super::{
ensure_init,
init::{command as init_command, Options as InitOptions},
Target,
};
use crate::Result;

pub(crate) mod project;

#[derive(Debug, thiserror::Error)]
enum Error {
#[error("{0}")]
ProjectNotInitialized(String),
#[error(transparent)]
ConfigFailed(cargo_mobile::config::LoadOrGenError),
#[error(transparent)]
MetadataFailed(cargo_mobile::config::metadata::Error),
#[error("iOS is marked as unsupported in your configuration file")]
Unsupported,
#[error(transparent)]
OpenFailed(os::OpenFileError),
}

#[derive(Parser)]
#[clap(
author,
Expand All @@ -25,12 +49,38 @@ pub struct Cli {
#[derive(Subcommand)]
enum Commands {
Init(InitOptions),
Open,
}

pub fn command(cli: Cli) -> Result<()> {
match cli.command {
Commands::Init(options) => init_command(options, InitTarget::Ios)?,
Commands::Init(options) => init_command(options, Target::Ios)?,
Commands::Open => open()?,
}

Ok(())
}

fn with_config(
wrapper: &TextWrapper,
f: impl FnOnce(&AppleConfig, &AppleMetadata) -> Result<(), Error>,
) -> Result<(), Error> {
let (config, _origin) =
Config::load_or_gen(".", true.into(), wrapper).map_err(Error::ConfigFailed)?;
let metadata = Metadata::load(config.app().root_dir()).map_err(Error::MetadataFailed)?;
if metadata.apple().supported() {
f(config.apple(), metadata.apple())
} else {
Err(Error::Unsupported)
}
}

fn open() -> Result<()> {
let wrapper = TextWrapper::with_splitter(textwrap::termwidth(), textwrap::NoHyphenation);
with_config(&wrapper, |config, _metadata| {
ensure_init(config.project_dir(), Target::Ios)
.map_err(|e| Error::ProjectNotInitialized(e.to_string()))?;
os::open_file_with("Xcode", config.project_dir()).map_err(Error::OpenFailed)
})?;
Ok(())
}
41 changes: 41 additions & 0 deletions tooling/cli/src/mobile/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,48 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT

use anyhow::{bail, Result};
use std::path::PathBuf;

pub mod android;
mod init;
#[cfg(target_os = "macos")]
pub mod ios;

#[derive(PartialEq, Eq)]
pub enum Target {
Android,
#[cfg(target_os = "macos")]
Ios,
}

impl Target {
fn ide_name(&self) -> &'static str {
match self {
Self::Android => "Android Studio",
#[cfg(target_os = "macos")]
Self::Ios => "Xcode",
}
}

fn command_name(&self) -> &'static str {
match self {
Self::Android => "android",
#[cfg(target_os = "macos")]
Self::Ios => "ios",
}
}
}

fn ensure_init(project_dir: PathBuf, target: Target) -> Result<()> {
if !project_dir.exists() {
bail!(
"{} project directory {} doesn't exist. Please run `tauri {} init` and try again.",
target.ide_name(),
project_dir.display(),
target.command_name(),
)
} else {
Ok(())
}
}

0 comments on commit a9c8e56

Please sign in to comment.