Skip to content

Commit 56422bf

Browse files
authored
Android SDK access (dodorare#8)
* Add availability to parse key * Change android sdk access * Fix error casting * Add find_max_version() function * Fix fmt * Remove unused serde dep * Fix cargo clippy * Add run tests to CI * Fix CI * Try to fix CI * Fix CI syntax * Remove check deadlinks job
1 parent 335c3bb commit 56422bf

File tree

12 files changed

+77
-36
lines changed

12 files changed

+77
-36
lines changed

.github/workflows/ci.yml

+18-10
Original file line numberDiff line numberDiff line change
@@ -12,31 +12,39 @@ on:
1212
- '**.rs'
1313
- '**.toml'
1414
jobs:
15-
test-and-check:
15+
clean:
1616
name: Check code format
1717
runs-on: ubuntu-latest
1818
steps:
1919
- uses: actions/checkout@master
2020
- uses: actions-rs/toolchain@v1
2121
with:
22+
profile: minimal
2223
toolchain: nightly
2324
components: rustfmt, clippy
2425
override: true
26+
- name: Check the format
27+
run: cargo +nightly fmt --all -- --check
28+
- name: Run clippy
29+
run: cargo clippy --all-targets --all-features -- -D warnings -A clippy::upper_case_acronyms
30+
31+
run-tests:
32+
name: Run tests
33+
runs-on: macos-latest
34+
steps:
35+
- uses: actions/checkout@master
36+
- uses: actions-rs/toolchain@v1
37+
with:
38+
profile: minimal
39+
toolchain: stable
40+
override: true
2541
- name: Setup Android SDK
2642
uses: android-actions/setup-android@v2
2743
- name: Install bundletool
2844
run: |
2945
wget https://github.com/google/bundletool/releases/download/1.8.2/bundletool-all-1.8.2.jar
3046
mv bundletool-all-1.8.2.jar $HOME/bundletool.jar
31-
- name: Check the format
32-
run: cargo +nightly fmt --all -- --check
33-
- name: Run clippy
34-
run: cargo clippy --all-targets --all-features -- -D warnings -A clippy::upper_case_acronyms
3547
- name: Run tests
3648
run: |
3749
export BUNDLETOOL_PATH="$HOME/bundletool.jar"
38-
cargo test --no-fail-fast
39-
- name: Check for deadlinks
40-
run: |
41-
cargo install cargo-deadlinks
42-
cargo deadlinks --check-http || true
50+
cargo test --all

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "android-tools"
3-
version = "0.2.8"
3+
version = "0.2.9"
44
edition = "2021"
55
authors = ["DodoRare Team <[email protected]>"]
66
description = "Android-related tools for building and developing applications 🛠"

src/aapt2/mod.rs

+2-9
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ pub use optimize::*;
2626
pub use version::*;
2727

2828
use self::{daemon::Aapt2Daemon, diff::Aapt2Diff, version::Aapt2Version};
29-
use crate::{error::*, sdk_path_from_env};
29+
use crate::{error::*, find_max_version, sdk_path_from_env};
3030
use std::{
3131
path::{Path, PathBuf},
3232
process::Command,
@@ -110,14 +110,7 @@ pub fn aapt2_tool() -> Result<Command> {
110110
}
111111
let sdk_path = sdk_path_from_env()?;
112112
let build_tools = sdk_path.join("build-tools");
113-
let target_sdk_version = std::fs::read_dir(&build_tools)
114-
.map_err(|_| Error::PathNotFound(build_tools.clone()))?
115-
.filter_map(|path| path.ok())
116-
.filter(|path| path.path().is_dir())
117-
.filter_map(|path| path.file_name().into_string().ok())
118-
.filter(|name| name.chars().next().unwrap().is_digit(10))
119-
.max()
120-
.ok_or(AndroidError::BuildToolsNotFound)?;
113+
let target_sdk_version = find_max_version(&build_tools)?;
121114
let aapt2_exe = build_tools.join(target_sdk_version).join(bin!("aapt2"));
122115
Ok(Command::new(aapt2_exe))
123116
}

src/adb/screenrecord.rs

Whitespace-only changes.

src/bundletool/build_apks.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ use std::path::{Path, PathBuf};
2828
/// The table below describes the various flags and options you can set when using the
2929
/// `bundletool build-apks` command in greater detail. Only `--bundle` and `--output` are
3030
/// required—all other flags are optional
31-
#[derive(Debug, PartialEq, Default)]
31+
#[derive(Debug, Default)]
3232
pub struct BuildApks {
3333
bundle: PathBuf,
3434
output: PathBuf,
@@ -47,13 +47,13 @@ pub struct BuildApks {
4747
local_testing: bool,
4848
}
4949

50-
#[derive(Debug, PartialEq)]
50+
#[derive(Debug)]
5151
pub enum KsPass {
5252
KsPassPass,
5353
KsPassFile,
5454
}
5555

56-
#[derive(Debug, PartialEq)]
56+
#[derive(Debug)]
5757
pub enum KeyPass {
5858
KeyPassPass,
5959
KeyPassFile,

src/bundletool/build_bundle.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use std::path::{Path, PathBuf};
1515
/// can not use apksigner to sign your app bundle.
1616
///
1717
/// [jarsigner]: https://docs.oracle.com/javase/8/docs/technotes/tools/windows/jarsigner.html
18-
#[derive(Debug, PartialEq, PartialOrd)]
18+
#[derive(Debug)]
1919
pub struct BuildBundle {
2020
modules: Vec<PathBuf>,
2121
output: PathBuf,

src/bundletool/get_device_spec.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use std::path::{Path, PathBuf};
2020
/// `bundletool build-apks --device-spec=/MyApp/pixel2.json`
2121
/// `--bundle=/MyApp/my_app.aab --output=/MyApp/my_app.apks`
2222
/// ```
23-
#[derive(Debug, PartialEq, PartialOrd)]
23+
#[derive(Debug)]
2424
pub struct GetDeviceSpec {
2525
output: PathBuf,
2626
}

src/error.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ pub type Result<T> = std::result::Result<T, Error>;
99
/// Android specific error type
1010
#[derive(Display, Debug, Error)]
1111
pub enum AndroidError {
12+
/// Android SDK or Android NDK is not found.
13+
AndroidToolIsNotFound,
1214
/// Android SDK is not found
1315
AndroidSdkNotFound,
1416
/// Android NDK is not found
@@ -43,7 +45,7 @@ pub enum Error {
4345
CmdNotFound(String),
4446
/// Command had a non-zero exit code. Stdout: {0} Stderr: {1}
4547
CmdFailed(String, String),
46-
/// Bundletool is not found
48+
/// Bundletool is not found. Please, use crossbundle install command to setup bundletool
4749
BundletoolNotFound,
4850
/// Compiled resources not found
4951
CompiledResourcesNotFound,

src/java_tools/keytool.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -785,8 +785,8 @@ impl Keytool {
785785
}
786786

787787
/// Runs keytool commands
788-
pub fn run(&self) -> Result<Option<AabKey>> {
789-
let mut key = Some(AabKey::new_default()?);
788+
pub fn run(&self) -> Result<Option<Key>> {
789+
let mut key = Some(Key::new_default()?);
790790
let mut keytool = keytool()?;
791791
if self.v {
792792
keytool.arg("-v");
@@ -1024,13 +1024,13 @@ impl std::fmt::Display for KeyAlgorithm {
10241024
}
10251025

10261026
#[derive(Debug, Clone)]
1027-
pub struct AabKey {
1027+
pub struct Key {
10281028
pub key_path: PathBuf,
10291029
pub key_pass: String,
10301030
pub key_alias: String,
10311031
}
10321032

1033-
impl AabKey {
1033+
impl Key {
10341034
pub fn new_default() -> Result<Self> {
10351035
let key_path = android_dir()?.join("aab.keystore");
10361036
let key_pass = "android".to_string();

src/lib.rs

+40-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
use error::AndroidError;
21
use std::path::PathBuf;
32

3+
use error::AndroidError;
4+
45
/// On Windows adds `.exe` to given string.
56
macro_rules! bin {
67
($bin:expr) => {{
@@ -31,7 +32,44 @@ pub fn sdk_path_from_env() -> crate::error::Result<PathBuf> {
3132
.ok()
3233
.or_else(|| std::env::var("ANDROID_SDK_PATH").ok())
3334
.or_else(|| std::env::var("ANDROID_HOME").ok());
34-
std::path::PathBuf::from(sdk_path.ok_or(AndroidError::AndroidSdkNotFound)?)
35+
std::path::PathBuf::from(
36+
sdk_path.unwrap_or(sdk_install_path()?.to_str().unwrap().to_string()),
37+
)
3538
};
3639
Ok(sdk_path)
3740
}
41+
42+
/// Default installation path
43+
pub fn sdk_install_path() -> crate::error::Result<PathBuf> {
44+
let home_dir_path = dirs::home_dir().unwrap();
45+
#[cfg(target_os = "windows")]
46+
let path = std::path::Path::new("Local").join("Android").join("Sdk");
47+
#[cfg(target_os = "macos")]
48+
let path = std::path::Path::new("Library").join("Android").join("sdk");
49+
#[cfg(target_os = "linux")]
50+
let path = std::path::Path::new("Android").join("sdk");
51+
52+
#[cfg(target_os = "windows")]
53+
let app_data = std::path::Path::new("AppData");
54+
#[cfg(target_os = "windows")]
55+
let sdk_path = home_dir_path.join(app_data).join(path);
56+
57+
#[cfg(not(target_os = "windows"))]
58+
let sdk_path = home_dir_path.join(path);
59+
60+
if !sdk_path.exists() {
61+
std::fs::create_dir_all(&sdk_path)?;
62+
}
63+
Ok(sdk_path)
64+
}
65+
66+
pub fn find_max_version(target_dir: &std::path::Path) -> crate::error::Result<String> {
67+
let max_version = std::fs::read_dir(&target_dir)?
68+
.filter_map(|path| path.ok())
69+
.filter(|path| path.path().is_dir())
70+
.filter_map(|path| path.file_name().into_string().ok())
71+
.filter(|name| name.chars().next().unwrap().is_ascii_digit())
72+
.max()
73+
.ok_or(AndroidError::AndroidToolIsNotFound)?;
74+
Ok(max_version)
75+
}

tests/gen_key.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use android_tools::java_tools::{android_dir, AabKey, KeyAlgorithm, Keytool};
1+
use android_tools::java_tools::{android_dir, Key, KeyAlgorithm, Keytool};
22

33
#[test]
44
/// The [`keytool`] command is a key and certificate management utility. It enables users to administer
@@ -34,7 +34,7 @@ fn test_create_keystore_with_keytool() {
3434
});
3535

3636
// Creates new keystore from keytool
37-
let key = AabKey::new_default().unwrap();
37+
let key = Key::new_default().unwrap();
3838
Keytool::new()
3939
.genkeypair(true)
4040
.v(true)

tests/jarsigner.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use android_tools::java_tools::{android_dir, AabKey, JarSigner, KeyAlgorithm, Keytool};
1+
use android_tools::java_tools::{android_dir, JarSigner, Key, KeyAlgorithm, Keytool};
22

33
#[test]
44
/// The [`jarsigner`] tool has two purposes:
@@ -39,7 +39,7 @@ fn test_sign_application_with_jarsigner() {
3939
});
4040

4141
// Creates new keystore to sign aab
42-
let key = AabKey::new_default().unwrap();
42+
let key = Key::new_default().unwrap();
4343
Keytool::new()
4444
.genkeypair(true)
4545
.v(true)

0 commit comments

Comments
 (0)