summaryrefslogtreecommitdiffstats
path: root/rust/wolfree_sed_in_place/src/main.rs
blob: 7d568896f9fc706bcb651333b1f42fa068a374c5 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
//! 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/",
        "</head><body>",
        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/