Skip to content

Commit 40407c9

Browse files
committed
feat(rs): implement reset
1 parent 9310142 commit 40407c9

File tree

8 files changed

+145
-12
lines changed

8 files changed

+145
-12
lines changed

rs/src/config.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,11 @@ pub struct MWUtilConfig {
8282
pub mw_database: Option<String>,
8383
pub mw_install_path: String,
8484
pub mw_branch: String,
85+
pub mw_server: Option<String>,
86+
pub mw_script_path: Option<String>,
87+
pub mw_language: Option<String>,
88+
pub mw_user: Option<String>,
89+
pub mw_password: Option<String>,
8590

8691
pub gerrit_username: Option<String>,
8792
pub git_email: Option<String>,
@@ -145,6 +150,11 @@ pub fn load_mwutil_config(debug: bool) -> anyhow::Result<MWUtilConfig> {
145150
mw_database: env::var("MWC_DB_DATABASE").ok(),
146151
mw_install_path,
147152
mw_branch,
153+
mw_server: env::var("MW_SERVER").ok(),
154+
mw_script_path: env::var("MW_SCRIPT_PATH").ok(),
155+
mw_language: env::var("MW_LANG").ok(),
156+
mw_user: env::var("MEDIAWIKI_USER").ok(),
157+
mw_password: env::var("MEDIAWIKI_PASSWORD").ok(),
148158

149159
gerrit_username: env::var("GERRIT_USERNAME").ok(),
150160
git_email: env::var("GIT_EMAIL").ok(),

rs/src/main.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use crate::modules::security::SecurityArgs;
1414
use crate::modules::sql::SqlArgs;
1515
use anyhow::bail;
1616
use clap::{CommandFactory, Parser, Subcommand};
17+
use crate::modules::reset::ResetArgs;
1718

1819
mod config;
1920
mod modules;
@@ -58,6 +59,8 @@ pub enum Modules {
5859
Pull(PullArgs),
5960
/// Recreates containers
6061
Recreate(RecreateArgs),
62+
/// Resets various parts of the local dev environment
63+
Reset(ResetArgs),
6164
/// Runs a maintenance script
6265
Run(RunArgs),
6366
/// Allows creating and pushing security patches
@@ -102,6 +105,7 @@ pub fn run_module(module: Modules, config: Option<&MWUtilConfig>) -> anyhow::Res
102105
Modules::OpenSearch(args) => modules::opensearch::execute(config.unwrap(), args),
103106
Modules::Pull(args) => modules::pull::execute(config.unwrap(), args),
104107
Modules::Recreate(args) => modules::recreate::execute(config.unwrap(), args),
108+
Modules::Reset(args) => modules::reset::execute(config.unwrap(), args),
105109
Modules::Run(args) => modules::run::execute(config.unwrap(), args),
106110
Modules::Security(args) => modules::security::execute(config, args),
107111
Modules::SetupGerrit => modules::setup_gerrit::execute(config.unwrap(), None),

rs/src/modules/db.rs

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use crate::modules::down::DownArgs;
55
use crate::modules::recreate::RecreateArgs;
66
use crate::modules::{down, recreate};
77
use crate::utils::SpinnerSequence;
8-
use anyhow::{anyhow, Context};
8+
use anyhow::{anyhow, bail, Context};
99
use clap::{Args, Subcommand};
1010
use clap_complete::ArgValueCompleter;
1111
use clap_complete::CompletionCandidate;
@@ -150,12 +150,8 @@ pub fn delete_all_dumps(config: &MWUtilConfig) -> anyhow::Result<()> {
150150
Ok(())
151151
}
152152

153-
pub fn import_dump(config: &MWUtilConfig, args: DumpSubArgs) -> anyhow::Result<()> {
154-
let dump_file = get_dump(config, &args.name, Existence::MustExist)?;
155-
let bytes = fs::read(dump_file).context("Failed to read dump file")?;
156-
157-
let mut spinner = SpinnerSequence::new(4, "Dropping database");
158-
run_sql_query(
153+
pub fn drop_mw_database(config: &MWUtilConfig) -> anyhow::Result<()> {
154+
let status = run_sql_query(
159155
config,
160156
DbCommandUser::Mw,
161157
Some(DbCommandDatabase::None),
@@ -164,6 +160,18 @@ pub fn import_dump(config: &MWUtilConfig, args: DumpSubArgs) -> anyhow::Result<(
164160
config.mw_database.clone().ok_or_else(|| anyhow!("MW database not set!"))?
165161
).as_str(),
166162
).context("Failed to drop database")?;
163+
if !status.success() {
164+
bail!("Failed to drop database: Command returned an error!")
165+
}
166+
Ok(())
167+
}
168+
169+
pub fn import_dump(config: &MWUtilConfig, args: DumpSubArgs) -> anyhow::Result<()> {
170+
let dump_file = get_dump(config, &args.name, Existence::MustExist)?;
171+
let bytes = fs::read(dump_file).context("Failed to read dump file")?;
172+
173+
let mut spinner = SpinnerSequence::new(4, "Dropping database");
174+
drop_mw_database(config)?;
167175

168176
spinner.next("Creating database");
169177
run_sql_query(

rs/src/modules/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,4 @@ pub(crate) mod lint;
1616
pub(crate) mod npm;
1717
pub(crate) mod list_repo_remotes;
1818
pub(crate) mod security;
19+
pub(crate) mod reset;

rs/src/modules/opensearch.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use std::process::Command;
1414
#[derive(Args)]
1515
pub struct OpenSearchArgs {
1616
#[command(subcommand)]
17-
command: OpenSearchCommand,
17+
pub command: OpenSearchCommand,
1818
}
1919

2020
#[derive(Subcommand)]

rs/src/modules/recreate.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use crate::utils::container_completer;
44
use clap::Args;
55
use clap_complete::ArgValueCompleter;
66

7-
#[derive(Args)]
7+
#[derive(Args, Default)]
88
pub struct RecreateArgs {
99
/// The container to recreate
1010
#[arg(add = ArgValueCompleter::new(container_completer))]

rs/src/modules/reset.rs

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
use std::fs;
2+
use anyhow::{anyhow, bail};
3+
use clap::{Args, ValueEnum};
4+
use crate::config::MWUtilConfig;
5+
use crate::constants::MEDIAWIKI_CONTAINER;
6+
use crate::modules::{db, opensearch};
7+
use crate::modules::opensearch::{OpenSearchArgs, OpenSearchCommand};
8+
use crate::modules::run::RunArgs;
9+
use crate::{run_module, Modules};
10+
use crate::utils::SpinnerSequence;
11+
12+
// only supports top-level files in images/ !
13+
const EXCLUDED_UPLOADS: [&str; 2] = ["README", ".htaccess"];
14+
15+
#[derive(Clone, PartialEq, ValueEnum)]
16+
pub enum ResetActions {
17+
Database,
18+
OpenSearch,
19+
Uploads,
20+
}
21+
22+
#[derive(Args)]
23+
pub struct ResetArgs {
24+
/// The actions to perform
25+
actions: Vec<ResetActions>
26+
}
27+
28+
pub fn execute(config: &MWUtilConfig, args: ResetArgs) -> anyhow::Result<()> {
29+
let actions = args.actions;
30+
// not using SpinnerSequence::new here so we can init the text dynamically
31+
let mut spinner = SpinnerSequence {
32+
cur: 0,
33+
max: actions.len() as u8,
34+
last: None,
35+
};
36+
if actions.contains(&ResetActions::Uploads) {
37+
spinner.next("Resetting uploads");
38+
reset_uploads(config)?;
39+
}
40+
if actions.contains(&ResetActions::Database) {
41+
spinner.next("Resetting database");
42+
reset_database(config)?;
43+
}
44+
if actions.contains(&ResetActions::OpenSearch) {
45+
spinner.next("Resetting OpenSearch");
46+
opensearch::execute(config, OpenSearchArgs {
47+
command: OpenSearchCommand::Reset,
48+
})?;
49+
}
50+
Ok(())
51+
}
52+
53+
pub fn reset_uploads(config: &MWUtilConfig) -> anyhow::Result<()> {
54+
let upload_dir = config.core_dir.join("images");
55+
if !upload_dir.exists() {
56+
bail!("Upload directory does not exist!");
57+
}
58+
if !upload_dir.is_dir() {
59+
bail!("Upload directory is not a directory!");
60+
}
61+
if let Ok(files) = fs::read_dir(upload_dir) {
62+
for entry in files.flatten() {
63+
if !EXCLUDED_UPLOADS.contains(&entry.file_name().to_string_lossy().as_ref()) {
64+
let path = entry.path();
65+
println!("Removing {}", entry.file_name().to_string_lossy());
66+
if path.is_dir() {
67+
fs::remove_dir_all(path)?;
68+
} else {
69+
fs::remove_file(path)?;
70+
}
71+
}
72+
}
73+
}
74+
Ok(())
75+
}
76+
77+
pub fn reset_database(config: &MWUtilConfig) -> anyhow::Result<()> {
78+
db::drop_mw_database(config)?;
79+
80+
let local_settings = config.core_dir.join("LocalSettings.php");
81+
let local_settings_tmp = config.core_dir.join("LocalSettings.temp.php");
82+
fs::rename(&local_settings, &local_settings_tmp)?;
83+
84+
let install_args = vec![
85+
format!("--dbname={}", config.mw_database.clone().ok_or_else(|| anyhow!("MW Database not set!"))?),
86+
format!("--dbuser={}", config.db_user.clone().ok_or_else(|| anyhow!("DB User not set!"))?),
87+
format!("--dbpass={}", config.db_password.clone().ok_or_else(|| anyhow!("DB Password not set!"))?),
88+
format!("--dbserver={}", config.db_type.clone().get_container_name()),
89+
format!("--server={}", config.mw_server.clone().ok_or_else(|| anyhow!("MW Server not set!"))?),
90+
format!("--scriptpath={}", config.mw_script_path.clone().ok_or_else(|| anyhow!("MW Script Path not set!"))?),
91+
format!("--lang={}", config.mw_language.clone().ok_or_else(|| anyhow!("MW Language not set!"))?),
92+
format!("--pass={}", config.mw_password.clone().ok_or_else(|| anyhow!("MW Password not set!"))?),
93+
MEDIAWIKI_CONTAINER.to_string(),
94+
config.mw_user.clone().ok_or_else(|| anyhow!("MW User not set!"))?,
95+
];
96+
97+
let result = run_module(Modules::Run(RunArgs {
98+
script: "install".to_string(),
99+
extra_args: install_args,
100+
}), Some(config));
101+
102+
fs::rename(local_settings_tmp, local_settings)?;
103+
104+
result?;
105+
106+
run_module(Modules::Update, Some(config))?;
107+
run_module(Modules::Recreate(Default::default()), Some(config))?;
108+
109+
Ok(())
110+
}

rs/src/utils.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,9 @@ pub fn set_git_config(option: &str, value: &str, repo_folder: &PathBuf) -> anyho
5151
}
5252

5353
pub struct SpinnerSequence {
54-
cur: u8,
55-
max: u8,
56-
last: Option<ProgressBar>,
54+
pub cur: u8,
55+
pub max: u8,
56+
pub last: Option<ProgressBar>,
5757
}
5858

5959
impl SpinnerSequence {

0 commit comments

Comments
 (0)