//! The `wolfree_sed_in_place` crate provides a function for performing in-place replacements of patterns in multiple files using regular expressions. //! It allows you to recursively process all files within a specified directory and replace occurrences of a given pattern with a specified replacement string. #![allow(clippy::blanket_clippy_restriction_lints)] #![allow(clippy::exit)] #![allow(clippy::print_stderr)] #![allow(clippy::implicit_return)] /* SPDX-License-Identifier: AGPL-3.0-or-later * This file is part of Wolfree. * This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. */ use regex::Regex; use std::fs; use walkdir::WalkDir; /// Perform in-place replacements on files in a given directory, using regular expressions. /// /// This function walks through all the files in the specified `directory_path`, /// filters out directories, and applies a regular expression-based replacement /// on the contents of each file. /// /// # Arguments /// /// * `directory_path`: A string slice representing the path of the directory to traverse. /// * `pattern`: A string slice containing the regular expression pattern to search for. /// * `replacement`: A string slice representing the replacement for each matched pattern. /// /// # Examples /// /// ```rust /// // Replace a specific pattern in the file contents in the "./data/" directory. /// wolfree_sed_in_place("./data/", r"\bFoo\b", "Bar"); /// ``` /// /// This example replaces all occurrences of the word "Foo" with "Bar" in the files inside the "data" directory. fn wolfree_sed_in_place(directory_path: &str, pattern: &str, replacement: &str) { // Compile the regular expression pattern let regex = match Regex::new(pattern) { Ok(re) => re, Err(err) => { eprintln!("Error: {err}",); std::process::exit(1); } }; // Create a directory walker and filter out non-file entries let walker = WalkDir::new(directory_path) .into_iter() .filter_map(Result::ok) .filter(|entry| !entry.file_type().is_dir()); // Process each file in the directory for entry in walker { let file_path = entry.path(); // Read the file's contents into a string let file_contents = match fs::read_to_string(file_path) { Ok(contents) => contents, Err(err) => { eprintln!("Error: {err}",); std::process::exit(1); } }; // Perform the regex replacement on the file's contents let modified_contents = regex.replace(&file_contents, replacement); let modified_contents_as_ref = modified_contents.as_ref(); // Write the modified contents back to the file, overwriting its previous contents match fs::write(file_path, modified_contents_as_ref) { Ok(_) => (), Err(err) => { eprintln!("Error: {err}",); std::process::exit(1); } }; } } /// Entry point of the program. /// Demonstrates using `wolfree_sed_in_place` function to perform in-place replacements on files in specific directories. fn main() { wolfree_sed_in_place( "./docusaurus/build/input/", "", include_str!("include_str.html"), ); wolfree_sed_in_place( "./docusaurus/build/_next/static/chunks/", r"try(.{0,100}?)generateEncodedJSONFromValue(.*?)unescapeForUrl(.*?)catch(.*?)\{}", include_str!("include_str.tsx"), ); // console error: // _app-daabd76ef4fe402d.js:5 // WebSocket connection to 'wss://localhost/n/v1/api/fetcher/results' failed: // startWebsocket @ _app-daabd76ef4fe402d.js:5 // send @ _app-daabd76ef4fe402d.js:5 // sendMessage @ 1695-ae743311a23f8eb5.js:1 // newQuery @ 1695-ae743311a23f8eb5.js:78 // newQuery @ 1695-ae743311a23f8eb5.js:78 // fix: // Override the hostname in the minified JavaScript source code. wolfree_sed_in_place( "./docusaurus/build/_next/static/chunks/pages/", "window.location.hostname", "'www.wolframalpha.com'", ); } // regex101: build, test, and debug regex // https://regex101.com/