Skip to content

Commit 718bfc5

Browse files
authored
feat(newDir): Better new direcory flag, allows normal and eet install to work (#150)
2 parents b8953a9 + 44d0665 commit 718bfc5

File tree

6 files changed

+179
-150
lines changed

6 files changed

+179
-150
lines changed

.envrc-sample

+2
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1+
set -a
12
use nix
3+
mkdir -p $TMPDIR

shell.nix

+1-7
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,8 @@ with import <nixpkgs> {};
22

33
stdenv.mkDerivation {
44
name = "rust-env";
5-
nativeBuildInputs = [
6-
# Build-time Additional Dependencies
7-
cargo
8-
pkg-config
9-
rustc
10-
];
115
buildInputs = [
12-
# Run-time Additional Dependencies
6+
cargo
137
git
148
gnupg
159
pre-commit

src/config/args.rs

+34-21
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ use std::env::{split_paths, var_os};
22
use std::fmt::Debug;
33
use std::fs;
44
use std::path::PathBuf;
5-
use std::time::{SystemTime, UNIX_EPOCH};
65

76
use clap::Subcommand;
87
use clap::{builder::BoolishValueParser, builder::OsStr, Parser};
@@ -67,6 +66,10 @@ pub(crate) struct Normal {
6766
#[clap(env, short, long, value_parser = parse_absolute_path, required = true)]
6867
pub(crate) game_directory: PathBuf,
6968

69+
/// Instead of operating on an existing directory, create a new one with this flag as its name and then copy the original contents into it.
70+
#[clap(env, long, short = 'n', required = false)]
71+
pub(crate) new_game_directory: Option<PathBuf>,
72+
7073
/// CommonOptions
7174
#[clap(flatten)]
7275
pub(crate) options: Options,
@@ -92,26 +95,23 @@ pub(crate) struct Eet {
9295
#[clap(env, short='z', long, value_parser = path_must_exist, required = true)]
9396
pub(crate) bg2_log_file: PathBuf,
9497

95-
/// Instead of using given directories create new ones with files copied into them
98+
/// Instead of operating on an existing directory, create a new one with this flag as its name and then copy the original contents into it.
9699
#[clap(
97100
env,
98-
short='g',
101+
short,
99102
long,
100103
action = clap::ArgAction::SetTrue,
101104
required = false,
102105
)]
103-
pub(crate) create_directories: bool,
106+
pub(crate) generate_directories: bool,
104107

105-
/// When create_directories is true, this is the prefix which the created directories have
106-
#[clap(
107-
env,
108-
long,
109-
short = 'p',
110-
default_value_t = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs().to_string(),
111-
default_missing_value = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs().to_string(),
112-
required = false
113-
)]
114-
pub(crate) create_directories_prefix: String,
108+
/// If generate_directories is true. This is the path for the new pre-eet directory.
109+
#[clap(env, short = 'p', long, value_parser = path_must_exist)]
110+
pub(crate) new_pre_eet_dir: Option<PathBuf>,
111+
112+
/// If generate_directories is true. This is the path for the new eet directory.
113+
#[clap(env, short = 'n', long, value_parser = path_must_exist)]
114+
pub(crate) new_eet_dir: Option<PathBuf>,
115115

116116
/// CommonOptions
117117
#[clap(flatten)]
@@ -185,15 +185,26 @@ pub(crate) struct Options {
185185
pub(crate) timeout: usize,
186186

187187
/// Weidu log setting "--autolog" is default
188-
#[clap(env, long, short='u', default_value = "autolog", value_parser = parse_weidu_log_mode, required = false)]
188+
#[clap(
189+
env,
190+
long,
191+
short='u',
192+
default_value = "autolog",
193+
value_parser = parse_weidu_log_mode,
194+
required = false
195+
)]
189196
pub(crate) weidu_log_mode: String,
190197

191198
/// Strict Version and Component/SubComponent matching
192199
#[clap(
193200
env,
194201
short = 'x',
195202
long,
203+
num_args=0..=1,
196204
action = clap::ArgAction::SetTrue,
205+
default_value_t = false,
206+
default_missing_value = "false",
207+
value_parser = BoolishValueParser::new(),
197208
required = false,
198209
)]
199210
pub(crate) strict_matching: bool,
@@ -324,6 +335,7 @@ mod tests {
324335
command: InstallType::Normal(Normal {
325336
log_file: fake_log_file.clone(),
326337
game_directory: fake_game_dir.clone(),
338+
new_game_directory: None,
327339
options: Options {
328340
weidu_binary: fake_weidu_bin.clone(),
329341
mod_directories: vec![fake_mod_dirs.clone()],
@@ -333,7 +345,7 @@ mod tests {
333345
abort_on_warnings: expected_flag_value,
334346
timeout: 3600,
335347
weidu_log_mode: "--autolog".to_string(),
336-
strict_matching: true,
348+
strict_matching: false,
337349
},
338350
}),
339351
};
@@ -360,7 +372,7 @@ mod tests {
360372
let fake_game_dir = std::env::current_dir().unwrap().join("fixtures");
361373
let fake_weidu_bin = fake_game_dir.clone().join("weidu");
362374
let fake_log_file = fake_game_dir.clone().join("weidu.log");
363-
let prefix = "prefix";
375+
let new_dir = PathBuf::new().join("test");
364376
let expected_flag_value = true;
365377

366378
let expected = Args {
@@ -380,18 +392,19 @@ mod tests {
380392
weidu_log_mode: "--autolog".to_string(),
381393
strict_matching: !expected_flag_value,
382394
},
383-
create_directories: true,
384-
create_directories_prefix: prefix.to_string(),
395+
generate_directories: false,
396+
new_pre_eet_dir: None,
397+
new_eet_dir: Some("test".into()),
385398
}),
386399
};
387400
let test_arg_string = format!(
388-
"mod_installer eet -w {} -1 {} -y {} -2 {} -z {} -g -p {}",
401+
"mod_installer eet -w {} -1 {} -y {} -2 {} -z {} -n {}",
389402
fake_weidu_bin.to_str().unwrap_or_default(),
390403
fake_game_dir.to_str().unwrap_or_default(),
391404
fake_log_file.to_str().unwrap_or_default(),
392405
fake_game_dir.to_str().unwrap_or_default(),
393406
fake_log_file.to_str().unwrap_or_default(),
394-
prefix,
407+
new_dir.to_str().unwrap_or_default(),
395408
);
396409
let result = Args::parse_from(test_arg_string.split(' '));
397410
assert_eq!(

src/installers.rs

+133
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
use std::path::PathBuf;
2+
use std::{collections::HashMap, error::Error, path::Path, sync::Arc};
3+
4+
use crate::{
5+
config::args::{Eet, Options},
6+
config::parser_config::ParserConfig,
7+
utils::{
8+
clone_directory, copy_folder, find_mods, find_parent_folder,
9+
mod_folder_present_in_game_directory, search_mod_folders,
10+
},
11+
weidu::{install, InstallationResult},
12+
};
13+
14+
const EET: &str = "eet";
15+
const PRE_EET: &str = "pre-eet";
16+
17+
pub(crate) fn normal_install(
18+
log_file: &Path,
19+
game_dir: &Path,
20+
new_game_directory: &Option<PathBuf>,
21+
options: &Options,
22+
parser_config: Arc<ParserConfig>,
23+
) -> Result<(), Box<dyn Error>> {
24+
let game_directory = if let Some(new_game_dir) = new_game_directory.clone() {
25+
clone_directory(game_dir, &new_game_dir)?
26+
} else {
27+
game_dir.to_path_buf()
28+
};
29+
30+
let mods_to_be_installed = match find_mods(
31+
log_file,
32+
options.skip_installed,
33+
&game_directory,
34+
options.strict_matching,
35+
) {
36+
Ok(mods) => mods,
37+
Err(err) => {
38+
return Err(format!("Failed to find weidu log file, {:?}", err).into());
39+
}
40+
};
41+
42+
let mut mod_folder_cache = HashMap::new();
43+
for weidu_mod in &mods_to_be_installed {
44+
let mod_folder = mod_folder_cache
45+
.entry(weidu_mod.tp_file.clone())
46+
.or_insert_with(|| {
47+
search_mod_folders(&options.mod_directories, weidu_mod, options.depth).unwrap()
48+
});
49+
50+
log::debug!("Found mod folder {:?}, for mod {:?}", mod_folder, weidu_mod);
51+
52+
if !mod_folder_present_in_game_directory(&game_directory, &weidu_mod.name) {
53+
log::info!(
54+
"Copying mod directory, from {:?} to, {:?}",
55+
mod_folder,
56+
game_directory.join(&weidu_mod.name)
57+
);
58+
copy_folder(mod_folder, game_directory.join(&weidu_mod.name))?;
59+
}
60+
log::info!("Installing mod {:?}", &weidu_mod);
61+
match install(
62+
&options.weidu_binary,
63+
&game_directory,
64+
parser_config.clone(),
65+
weidu_mod,
66+
&options.language,
67+
&options.weidu_log_mode,
68+
options.timeout,
69+
) {
70+
InstallationResult::Fail(message) => {
71+
return Err(format!(
72+
"Failed to install mod {}, error is '{}'",
73+
weidu_mod.name, message
74+
)
75+
.into());
76+
}
77+
InstallationResult::Success => {
78+
log::info!("Installed mod {:?}", &weidu_mod);
79+
}
80+
InstallationResult::Warnings => {
81+
if options.abort_on_warnings {
82+
return Err(
83+
format!("Installed mod {:?} with warnings, stopping", weidu_mod).into(),
84+
);
85+
} else {
86+
log::warn!("Installed mod {:?} with warnings, keep going", weidu_mod);
87+
}
88+
}
89+
}
90+
}
91+
Ok(())
92+
}
93+
94+
pub(crate) fn eet_install(
95+
command: &Eet,
96+
parser_config: Arc<ParserConfig>,
97+
) -> Result<(), Box<dyn Error>> {
98+
log::info!("Beginning pre eet install process");
99+
let new_game_directory: Option<PathBuf> = if command.generate_directories {
100+
if command.new_pre_eet_dir.is_none() {
101+
Some(find_parent_folder(&command.bg1_game_directory)?.join(PRE_EET))
102+
} else {
103+
command.new_pre_eet_dir.clone()
104+
}
105+
} else {
106+
None
107+
};
108+
normal_install(
109+
&command.bg1_log_file,
110+
&command.bg1_game_directory,
111+
&new_game_directory,
112+
&command.options,
113+
parser_config.clone(),
114+
)?;
115+
116+
log::info!("Beginning eet install process");
117+
let new_game_directory: Option<PathBuf> = if command.generate_directories {
118+
if command.new_eet_dir.is_none() {
119+
Some(find_parent_folder(&command.bg2_game_directory)?.join(EET))
120+
} else {
121+
command.new_eet_dir.clone()
122+
}
123+
} else {
124+
None
125+
};
126+
normal_install(
127+
&command.bg2_log_file,
128+
&command.bg2_game_directory,
129+
&new_game_directory,
130+
&command.options,
131+
parser_config.clone(),
132+
)
133+
}

0 commit comments

Comments
 (0)