Skip to content

Commit

Permalink
feat: impl link command + project_name in .android
Browse files Browse the repository at this point in the history
  • Loading branch information
SyedAhkam committed Aug 22, 2023
1 parent fc4652e commit 1e8cf99
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 27 deletions.
24 changes: 4 additions & 20 deletions src/commands/create.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use anyhow::{anyhow, Context, Result};
use anyhow::{Context, Result};
use clap::Parser;

use std::{collections::BTreeMap, path::PathBuf};

use crate::utils::prompt_for_input;
use crate::utils::{prompt_for_input, parse_package_id};

const DEFAULT_COMPILE_SDK_VERSION: &str = "33";
const DEFAULT_TARGET_SDK_VERSION: &str = "33";
Expand Down Expand Up @@ -46,22 +46,6 @@ pub struct Create {
fn get_vars(args: &Create) -> Result<BTreeMap<String, String>> {
let mut map = BTreeMap::<String, String>::new();

// FIXME: this is a hack, we should use a proper parser
let get_package_id = |package_id: String| {
let mut parts = package_id.split('.');
let domain = parts
.next()
.ok_or_else(|| anyhow!("domain part missing in package"))?;
let org = parts
.next()
.ok_or_else(|| anyhow!("org part missing in package"))?;
let name = parts
.next()
.ok_or_else(|| anyhow!("name part missing in package"))?;

anyhow::Ok((domain.to_owned(), org.to_owned(), name.to_owned()))
};

// Metadata
map.insert(
"project_name".into(),
Expand All @@ -70,7 +54,7 @@ fn get_vars(args: &Create) -> Result<BTreeMap<String, String>> {
map.insert("app_name".into(), args.name.as_ref().unwrap().to_owned());

// Package identifiers
let (domain, org, name) = get_package_id(args.package_id.as_ref().unwrap().to_owned())
let (domain, org, name) = parse_package_id(args.package_id.as_ref().unwrap().to_owned())
.context("failed to parse package id")?;
map.insert("package_id_domain".into(), domain);
map.insert("package_id_org".into(), org);
Expand All @@ -94,7 +78,7 @@ fn post_create(args: Create) -> Result<()> {
let dest = args.dest.clone().unwrap();

android_cli::create_local_properties_file(&dest, &args.sdk_path.unwrap())?;
android_cli::create_dot_android(&dest, args.package_id.unwrap())?;
android_cli::create_dot_android(&dest, args.project_name.unwrap(), args.package_id.unwrap(), None)?;

Ok(())
}
Expand Down
32 changes: 32 additions & 0 deletions src/commands/link.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
use std::path::Path;

use anyhow::{Context, Result};
use clap::Parser;

use crate::utils::{prompt_for_input, safe_name};

#[derive(Parser, Debug)]
pub struct Link {}

pub fn handle(_args: Link) -> Result<()> {
let project_name = prompt_for_input("Enter project name", None)?;
let package_id = prompt_for_input("Enter package identifier", None)
.map(safe_name)
.unwrap();
let main_activity_name = prompt_for_input(
"Main Activity name",
Some(android_cli::DEFAULT_MAIN_ACTIVITY.into()),
)?;

android_cli::create_dot_android(
&Path::new("."),
project_name,
package_id,
Some(main_activity_name.into()),
)
.context("Failed to link project")?;

println!("Successfully linked the project");

Ok(())
}
1 change: 1 addition & 0 deletions src/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ pub mod install;
pub mod run;
pub mod launch;
pub mod devices;
pub mod link;
10 changes: 6 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,17 @@ use std::{

use utils::{find_adb, find_gradle};

const VERSION: &str = env!("CARGO_PKG_VERSION");
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
pub const DEFAULT_MAIN_ACTIVITY: &str = "MainActivity";

const DEFAULT_TEMPLATE_REPO: &str = "https://github.com/SyedAhkam/android-cli-template";
const TEMPLATE_REV: &str = "master";

const DOTFILE_COMMENT: &str = "// DO NOT MODIFY; Generated by Android CLI for internal usage.\n";
const DEFAULT_MAIN_ACTIVITY: &str = "MainActivity";

#[derive(Debug, Serialize, Deserialize)]
pub struct DotAndroid {
pub project_name: String,
pub package_id: String,
pub gen_at_version: String,
pub main_activity_name: String,
Expand Down Expand Up @@ -82,12 +83,13 @@ pub fn invoke_adb_command(args: &[&str]) -> Result<ExitStatus> {
Ok(run.status()?)
}

pub fn create_dot_android(dest: &Path, package_id: String) -> Result<()> {
pub fn create_dot_android(dest: &Path, project_name: String, package_id: String, main_activity_name: Option<String>) -> Result<()> {
// Construct the structure
let dot_android = DotAndroid {
package_id,
project_name,
gen_at_version: VERSION.to_owned(),
main_activity_name: DEFAULT_MAIN_ACTIVITY.to_owned(),
main_activity_name: main_activity_name.unwrap_or(DEFAULT_MAIN_ACTIVITY.to_owned())
};

// Serialize into Ron
Expand Down
6 changes: 4 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ enum SubCommand {
Install(commands::install::Install),
Run(commands::run::Run),
Launch(commands::launch::Launch),
Devices(commands::devices::Devices)
Devices(commands::devices::Devices),
Link(commands::link::Link)
}

fn main() {
Expand All @@ -35,7 +36,8 @@ fn main() {
SubCommand::Install(args) => commands::install::handle(args),
SubCommand::Run(args) => commands::run::handle(args),
SubCommand::Launch(args) => commands::launch::handle(args),
SubCommand::Devices(args) => commands::devices::handle(args)
SubCommand::Devices(args) => commands::devices::handle(args),
SubCommand::Link(args) => commands::link::handle(args)
};

if result.is_err() {
Expand Down
25 changes: 24 additions & 1 deletion src/utils.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#![allow(dead_code)]

use anyhow::{Context, Result};
use anyhow::{anyhow, Context, Result};
use which::which;

pub fn prompt_for_input(prompt: &str, default: Option<String>) -> Result<String> {
Expand All @@ -17,6 +17,29 @@ pub fn prompt_for_input(prompt: &str, default: Option<String>) -> Result<String>
.context("failed to prompt user")?)
}

// FIXME: this is a hack, we should use a proper parser
pub fn parse_package_id(package_id: String) -> Result<(String, String, String)> {
let mut parts = package_id.split('.');
let domain = parts
.next()
.ok_or_else(|| anyhow!("domain part missing in package"))?;

let org = parts
.next()
.ok_or_else(|| anyhow!("org part missing in package"))?;

let name = parts
.next()
.ok_or_else(|| anyhow!("name part missing in package"))?;

anyhow::Ok((domain.to_owned(), org.to_owned(), name.to_owned()))
}


pub fn safe_name(name: String) -> String {
name.to_lowercase().replace(" ", "_")
}

pub fn find_gradle() -> Option<String> {
if std::path::Path::new("./gradlew").exists() {
return Some("./gradlew".to_owned());
Expand Down

0 comments on commit 1e8cf99

Please sign in to comment.