Skip to content

Commit 7e45fad

Browse files
committed
Add support for dotenv files
Load CLI args from `.env` files Rename entrypoint to `extractor`
1 parent ef61555 commit 7e45fad

File tree

8 files changed

+84
-7
lines changed

8 files changed

+84
-7
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,6 @@ Cargo.lock
2121
.idea/
2222

2323
.DS_Store
24+
.env
2425
ios
2526
extracted/

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "ios"
3-
version = "0.0.2-alpha"
3+
version = "0.2.1"
44
description = "Light-weight CLI tool to extract iOS backup"
55
edition = "2021"
66
authors = ["Vignesh Rao"]
@@ -35,3 +35,4 @@ threadpool = "1.8.1"
3535
log = "0.4.25"
3636
chrono = "0.4.39"
3737
tqdm = "0.7.0"
38+
dotenv = "0.15.0"

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ cargo add ios
2323
use ios;
2424

2525
fn main() {
26-
match ios::retriever() {
26+
match ios::extractor() {
2727
Ok(res) => {
2828
println!("{}", res);
2929
}

src/fileio.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ fn extract_files(
145145
if !src_path.exists() {
146146
let msg = format!("Path {} doesn't exist", src_path.display());
147147
log::debug!("{}", msg);
148-
return Err(std::io::Error::new(std::io::ErrorKind::NotFound, msg))
148+
return Err(std::io::Error::new(std::io::ErrorKind::NotFound, msg));
149149
}
150150
let filename = relative_path
151151
.file_name()

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use rusqlite::Result;
2424
///
2525
/// * `Ok` - If the function completes successfully
2626
/// * `Err` - If the function encounters an error
27-
pub fn retriever() -> Result<String, String> {
27+
pub fn extractor() -> Result<String, String> {
2828
let metadata = constant::build_info();
2929
let arguments = parser::arguments(&metadata);
3030
let empty_serial = arguments.serial_numbers.is_empty();

src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
fn main() {
2-
match ios::retriever() {
2+
match ios::extractor() {
33
Ok(res) => {
44
println!("{}", res);
55
}

src/parser.rs

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,13 @@ fn missing_value(key: &str) {
3838
///
3939
/// A `PathBuf` containing the default backup directory path
4040
fn default_ios_backup_directory() -> PathBuf {
41+
let backup_dir = PathBuf::from(
42+
squire::env_var("backup_dir", Some(vec!["source_dir", "source", "src"]))
43+
.unwrap_or_default(),
44+
);
45+
if backup_dir.exists() {
46+
return backup_dir;
47+
}
4148
let home = dirs::home_dir().expect("Could not determine home directory");
4249
if cfg!(target_os = "windows") {
4350
home.join("AppData/Roaming/Apple Computer/MobileSync/Backup")
@@ -46,6 +53,23 @@ fn default_ios_backup_directory() -> PathBuf {
4653
}
4754
}
4855

56+
/// Default output directory
57+
///
58+
/// # Returns
59+
///
60+
/// A `PathBuf` containing the default output directory path
61+
fn default_output_directory() -> PathBuf {
62+
let output_str = squire::env_var(
63+
"output_dir",
64+
Some(vec!["destination_dir", "destination", "dst"]),
65+
)
66+
.unwrap_or_default();
67+
if output_str.is_empty() {
68+
return PathBuf::from("extracted");
69+
}
70+
PathBuf::from(output_str)
71+
}
72+
4973
/// Helper function to print the command-line arguments.
5074
///
5175
/// # Returns
@@ -82,6 +106,7 @@ pub fn arguments(metadata: &constant::MetaData) -> ArgConfig {
82106
let mut debug = false;
83107
let mut serial = String::new();
84108
let mut workers = String::new();
109+
let mut env_file = String::new();
85110
let mut backup_dir = String::new();
86111
let mut output_dir = String::new();
87112
let mut organize = Organizer::Auto;
@@ -122,6 +147,14 @@ pub fn arguments(metadata: &constant::MetaData) -> ArgConfig {
122147
missing_value(&args[i - 1]);
123148
}
124149
}
150+
"--env" | "--env-file" => {
151+
i += 1; // Move to the next argument.
152+
if i < args.len() {
153+
env_file = args[i].clone();
154+
} else {
155+
missing_value(&args[i - 1]);
156+
}
157+
}
125158
"--organize" => {
126159
i += 1; // Move to the next argument.
127160
if i < args.len() {
@@ -166,6 +199,12 @@ pub fn arguments(metadata: &constant::MetaData) -> ArgConfig {
166199
println!("{} {}", &metadata.pkg_name, &metadata.pkg_version);
167200
std::process::exit(0)
168201
}
202+
203+
if env_file.is_empty() {
204+
env_file = squire::env_var("env_file", None).unwrap_or(".env".to_string())
205+
}
206+
let _ = dotenv::from_path(env_file);
207+
169208
let backup_dir_final = if backup_dir.is_empty() {
170209
default_ios_backup_directory()
171210
} else {
@@ -181,7 +220,7 @@ pub fn arguments(metadata: &constant::MetaData) -> ArgConfig {
181220
}
182221
};
183222
let output_dir_final = if output_dir.is_empty() {
184-
PathBuf::from("extracted")
223+
default_output_directory()
185224
} else {
186225
PathBuf::from(output_dir)
187226
};
@@ -190,11 +229,18 @@ pub fn arguments(metadata: &constant::MetaData) -> ArgConfig {
190229
} else {
191230
workers.parse::<usize>().unwrap()
192231
};
232+
if serial.is_empty() {
233+
serial = squire::env_var("serial", None).unwrap_or_default()
234+
}
193235
let serial_numbers: Vec<String> = serial
194236
.split(",")
195237
.filter(|s| !s.is_empty())
196238
.map(String::from)
197239
.collect();
240+
// todo: implement env var check for all CLI arguments
241+
// todo: remove the debug step
242+
println!("{:?}", backup_dir_final);
243+
println!("{:?}", output_dir_final);
198244
ArgConfig {
199245
list,
200246
all,

src/squire.rs

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::fs::metadata;
22
use std::path::{Path, PathBuf};
33
use std::time::{SystemTime, UNIX_EPOCH};
4-
use std::{fs, thread};
4+
use std::{env, fs, thread};
55

66
/// Function to convert seconds to human-readable format
77
///
@@ -256,3 +256,32 @@ pub fn file_size(src_path: &Path, filename: &String) -> PathBuf {
256256
.join(filename)
257257
.to_owned()
258258
}
259+
260+
/// Loads an environment variable by looking for both upper/lower case of the key
261+
///
262+
/// # Arguments
263+
///
264+
/// * `key` - Takes the key for env var as an argument
265+
///
266+
/// # Returns
267+
///
268+
/// A `String` with the response value from the environment variable
269+
pub fn env_var(env_key: &'static str, alias: Option<Vec<&'static str>>) -> Option<String> {
270+
let mut alias_list = match alias {
271+
Some(v) => v,
272+
None => vec![env_key],
273+
};
274+
if !alias_list.contains(&env_key) {
275+
alias_list.push(env_key);
276+
}
277+
for key in alias_list {
278+
return match env::var(key.to_uppercase()) {
279+
Ok(val) => Some(val),
280+
Err(_) => match env::var(key.to_lowercase()) {
281+
Ok(val) => Some(val),
282+
Err(_) => continue,
283+
},
284+
};
285+
}
286+
None
287+
}

0 commit comments

Comments
 (0)