added t:new and --patches flag
This commit is contained in:
parent
2fad12ea91
commit
0b44140463
17 changed files with 227 additions and 59 deletions
62
README.md
62
README.md
|
@ -7,7 +7,7 @@
|
|||
</p>
|
||||
|
||||
<p align="center">
|
||||
This is a custom patcher for applying modifications to firefox source code. It processes patch files located in the `./patches` directory and applies them to files in a specified root path.
|
||||
This is a custom patcher for applying modifications to Firefox source code. It processes patch files located in the `./patches` directory and applies them to files in a specified root path.
|
||||
</p>
|
||||
|
||||
## How to Use
|
||||
|
@ -21,13 +21,14 @@ This is a custom patcher for applying modifications to firefox source code. It p
|
|||
-MOZ_APP_DISPLAYNAME=Firefox
|
||||
+MOZ_APP_DISPLAYNAME=Spitfire
|
||||
```
|
||||
2. Run the patcher with the `--path` flag:
|
||||
2. Run the patcher with the `--path` and `--patches` flags:
|
||||
|
||||
```sh
|
||||
./run.sh --path ./mozilla-central
|
||||
./run.sh --path ./mozilla-central/obj-x86_64-pc-linux-gnu/dist/bin --patches ./mozilla-central/patcher/post-compile-patches
|
||||
```
|
||||
|
||||
*Root path will be resolved to an absolute path, and patches will be applied relative to this path.*
|
||||
- --path *Will be resolved to an absolute path, and patches will be applied relative to this path.*
|
||||
- --patches *Specifies a path to a `.patch` file or a folder containing patches to be applied by this script*
|
||||
|
||||
## Parameters Explained
|
||||
|
||||
|
@ -39,7 +40,7 @@ Here are the details of each parameter used in the patching system:
|
|||
- This is the file that will be read and modified based on the patch instructions.
|
||||
- **Example:**
|
||||
|
||||
```
|
||||
```patch
|
||||
i:/browser/branding/official/configure.sh
|
||||
```
|
||||
|
||||
|
@ -51,7 +52,7 @@ Here are the details of each parameter used in the patching system:
|
|||
- If the input and output paths are the same, the original file will be overwritten.
|
||||
- **Example:**
|
||||
|
||||
```
|
||||
```patch
|
||||
o:/browser/branding/official/configure.sh
|
||||
```
|
||||
|
||||
|
@ -61,34 +62,42 @@ Here are the details of each parameter used in the patching system:
|
|||
|
||||
- Defines the type of patch being applied. This parameter can be skipped if not applicable.
|
||||
- Common types:
|
||||
1. **`pref`:** Indicates that the patch is modifying preference settings (e.g., Firefox `prefs.js`).
|
||||
- When `t:pref` is specified, the script will search for existing preferences in the input file and replace them with the new ones provided in the patch. If not found, it will add the new preference.
|
||||
- **Example:**
|
||||
```
|
||||
t:pref
|
||||
+pref("extensions.getAddons.showPane", false); // HIDDEN
|
||||
```
|
||||
2. **`standard`:** Standard patching type that follows the `+` (add) and `-` (remove) syntax.
|
||||
1. **`standard`:** Standard patching type that follows the `+` (add) and `-` (remove) syntax.
|
||||
- Used for general file modifications.
|
||||
- **Example:**
|
||||
```
|
||||
```patch
|
||||
-MOZ_APP_DISPLAYNAME=Firefox
|
||||
+MOZ_APP_DISPLAYNAME=Spitfire
|
||||
```
|
||||
- **When to Use:**
|
||||
- **Required for specialized processing:** If the patch involves specific logic, like handling `pref` files, include this parameter.
|
||||
- **Optional for standard patches:** For simple addition or removal of lines, you can skip this parameter.
|
||||
2. **`pref`:** Indicates that the patch is modifying preference settings (e.g., Firefox `prefs.js`).
|
||||
- When `t:pref` is specified, the script will search for existing preferences in the input file and replace them with the new ones provided in the patch. If not found, it will add the new preference.
|
||||
- **Example:**
|
||||
```patch
|
||||
t:pref
|
||||
+pref("extensions.getAddons.showPane", false); // HIDDEN
|
||||
```
|
||||
3. **`new`:** Used for creating new files or overwriting existing files with specified content.
|
||||
- Creates a new file at the `o:` location.
|
||||
- **Example:**
|
||||
```patch
|
||||
t:new
|
||||
o:/browser/branding/official/newfile.txt
|
||||
|
||||
### Example Patch File
|
||||
+This is a new file created by Spitfire Patcher.
|
||||
```
|
||||
|
||||
```
|
||||
### Example Patch Files
|
||||
|
||||
```patch
|
||||
t:pref
|
||||
i:/browser/branding/official/configure.sh
|
||||
o:/browser/branding/official/configure.sh
|
||||
i:/browser/firefox.js
|
||||
o:/browser/spitfire.js
|
||||
|
||||
-pref("browser.privatebrowsing.autostart", false);
|
||||
+pref("browser.privatebrowsing.autostart", true);
|
||||
```
|
||||
|
||||
```patch
|
||||
t:standard
|
||||
i:/browser/app/profile/firefox.js
|
||||
o:/browser/app/profile/firefox.js
|
||||
|
@ -97,13 +106,20 @@ o:/browser/app/profile/firefox.js
|
|||
+MOZ_APP_DISPLAYNAME=Spitfire
|
||||
```
|
||||
|
||||
```patch
|
||||
t:new
|
||||
o:/browser/branding/official/new-file.txt
|
||||
|
||||
+Welcome to Spitfire Browser Branding.
|
||||
```
|
||||
|
||||
### Summary of Parameters
|
||||
|
||||
| Parameter | Required | Purpose | Example |
|
||||
| ----------- | ---------- | ------------------------------------- | ------------------------------------- |
|
||||
| `i:` | Yes | Specifies the input file path. | `i:/browser/app/profile/firefox.js` |
|
||||
| `o:` | Yes | Specifies the output file path. | `o:/browser/app/profile/firefox.js` |
|
||||
| `t:` | No | Defines the type of patch. | `t:pref` or `t:standard` |
|
||||
| `t:` | No | Defines the type of patch. | `t:pref`, `t:standard`, or `t:new` |
|
||||
| `+` | Yes | Adds a line to the output file. | `+MOZ_APP_DISPLAYNAME=Spitfire` |
|
||||
| `-` | Yes | Removes a line from the input file. | `-MOZ_APP_DISPLAYNAME=Firefox` |
|
||||
|
||||
|
|
90
main.go
90
main.go
|
@ -11,8 +11,9 @@ import (
|
|||
)
|
||||
|
||||
func main() {
|
||||
// Define the --path flag
|
||||
// Define the --path and --patches flags
|
||||
rootPath := flag.String("path", ".", "Root path for patch application")
|
||||
patchSource := flag.String("patches", "./patches", "File or directory containing patch(es)")
|
||||
flag.Parse()
|
||||
|
||||
// Convert root path to an absolute path
|
||||
|
@ -21,31 +22,43 @@ func main() {
|
|||
log.Fatalf("Failed to resolve absolute path for root: %v", err)
|
||||
}
|
||||
|
||||
fmt.Printf("Starting custom patcher...\nRoot path: %s\n", absoluteRootPath)
|
||||
// Resolve patches path (handle both absolute and relative paths)
|
||||
absolutePatchesPath := *patchSource
|
||||
if !filepath.IsAbs(absolutePatchesPath) {
|
||||
absolutePatchesPath = filepath.Clean(filepath.Join(absoluteRootPath, *patchSource))
|
||||
}
|
||||
|
||||
fmt.Printf("Starting custom patcher...\nRoot path: %s\nPatches source: %s\n", absoluteRootPath, absolutePatchesPath)
|
||||
|
||||
patchDir := "./patches"
|
||||
var successfulPatches, failedPatches []string
|
||||
|
||||
err = filepath.Walk(patchDir, func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !info.IsDir() && strings.HasSuffix(info.Name(), ".patch") {
|
||||
fmt.Printf("Applying patch: %s\n", path)
|
||||
err := applyPatch(path, absoluteRootPath)
|
||||
if err != nil {
|
||||
fmt.Printf("Failed to apply patch %s: %v\n", path, err)
|
||||
failedPatches = append(failedPatches, path)
|
||||
} else {
|
||||
fmt.Printf("Successfully applied patch: %s\n", path)
|
||||
successfulPatches = append(successfulPatches, path)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
// Determine if --patches is a directory or a file
|
||||
info, err := os.Stat(absolutePatchesPath)
|
||||
if err != nil {
|
||||
log.Fatalf("Error reading patches: %v", err)
|
||||
log.Fatalf("Failed to access patch source: %v", err)
|
||||
}
|
||||
|
||||
if info.IsDir() {
|
||||
// Walk through directory to apply all patches
|
||||
err = filepath.Walk(absolutePatchesPath, func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !info.IsDir() && strings.HasSuffix(info.Name(), ".patch") {
|
||||
applyPatchWrapper(path, absoluteRootPath, &successfulPatches, &failedPatches)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
log.Fatalf("Error reading patches from directory: %v", err)
|
||||
}
|
||||
} else {
|
||||
// Single file provided
|
||||
if strings.HasSuffix(info.Name(), ".patch") {
|
||||
applyPatchWrapper(absolutePatchesPath, absoluteRootPath, &successfulPatches, &failedPatches)
|
||||
} else {
|
||||
log.Fatalf("Provided patch file is not a .patch file")
|
||||
}
|
||||
}
|
||||
|
||||
// Print the summary
|
||||
|
@ -69,6 +82,19 @@ func main() {
|
|||
}
|
||||
}
|
||||
|
||||
// applyPatchWrapper wraps the patch application and updates results
|
||||
func applyPatchWrapper(patchPath, rootPath string, successfulPatches, failedPatches *[]string) {
|
||||
fmt.Printf("Applying patch: %s\n", patchPath)
|
||||
err := applyPatch(patchPath, rootPath)
|
||||
if err != nil {
|
||||
fmt.Printf("Failed to apply patch %s: %v\n", patchPath, err)
|
||||
*failedPatches = append(*failedPatches, patchPath)
|
||||
} else {
|
||||
fmt.Printf("Successfully applied patch: %s\n", patchPath)
|
||||
*successfulPatches = append(*successfulPatches, patchPath)
|
||||
}
|
||||
}
|
||||
|
||||
// applyPatch processes a single patch file
|
||||
func applyPatch(patchPath, rootPath string) error {
|
||||
file, err := os.Open(patchPath)
|
||||
|
@ -120,14 +146,20 @@ func applyPatch(patchPath, rootPath string) error {
|
|||
return fmt.Errorf("failed to read patch file: %v", err)
|
||||
}
|
||||
|
||||
if inputFilePath == "" || outputFilePath == "" {
|
||||
return fmt.Errorf("patch file must specify both input (i:) and output (o:) files")
|
||||
if inputFilePath == "" && patchType != "new" {
|
||||
return fmt.Errorf("patch file must specify input (i:) file")
|
||||
}
|
||||
|
||||
// Replace the original file with the temporary file
|
||||
err = os.Rename(inputFilePath, outputFilePath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to replace output file: %v", err)
|
||||
if outputFilePath == "" {
|
||||
return fmt.Errorf("patch file must specify output (o:) file")
|
||||
}
|
||||
|
||||
if patchType != "new" {
|
||||
// Replace the original file with the temporary file
|
||||
err = os.Rename(inputFilePath, outputFilePath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to replace output file: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Process based on patch type
|
||||
|
@ -136,6 +168,8 @@ func applyPatch(patchPath, rootPath string) error {
|
|||
return applyPrefModifications(outputFilePath, modifications)
|
||||
case "standard":
|
||||
return applyStandardModifications(outputFilePath, modifications)
|
||||
case "new":
|
||||
return applyNewModifications(outputFilePath, modifications)
|
||||
default:
|
||||
fmt.Printf("Type not specified defaulting to standard")
|
||||
return applyStandardModifications(outputFilePath, modifications)
|
||||
|
|
44
new.go
Normal file
44
new.go
Normal file
|
@ -0,0 +1,44 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// applyNewModifications handles `t:new` type patches
|
||||
func applyNewModifications(targetFilePath string, modifications []string) error {
|
||||
// Ensure the directory structure exists
|
||||
dir := filepath.Dir(targetFilePath)
|
||||
if err := os.MkdirAll(dir, os.ModePerm); err != nil {
|
||||
return fmt.Errorf("failed to create directories for target file: %v", err)
|
||||
}
|
||||
|
||||
// Check if the file exists
|
||||
if _, err := os.Stat(targetFilePath); err == nil {
|
||||
// File exists, delete it
|
||||
if err := os.Remove(targetFilePath); err != nil {
|
||||
return fmt.Errorf("failed to delete existing target file: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Create a new file and apply modifications
|
||||
tempFile, err := os.Create(targetFilePath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create target file: %v", err)
|
||||
}
|
||||
defer tempFile.Close()
|
||||
|
||||
// Write new modifications
|
||||
for _, mod := range modifications {
|
||||
if strings.HasPrefix(mod, "+") {
|
||||
newLine := strings.TrimPrefix(mod, "+")
|
||||
if _, err := tempFile.WriteString(newLine + "\n"); err != nil {
|
||||
return fmt.Errorf("failed to write new content to target file: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
30
post-compile-patches/search-engine-qgato.patch
Normal file
30
post-compile-patches/search-engine-qgato.patch
Normal file
|
@ -0,0 +1,30 @@
|
|||
t: new
|
||||
o: /distribution/policies.json
|
||||
|
||||
+{
|
||||
+ "__COMMENT__ More Information": "https://github.com/mozilla/policy-templates/blob/master/README.md",
|
||||
+ "policies": {
|
||||
+ "DisableAppUpdate": true,
|
||||
+ "DisableTelemetry": true,
|
||||
+ "SearchEngines": {
|
||||
+ "Default": "QGato",
|
||||
+ "Add": [
|
||||
+ {
|
||||
+ "Name": "QGato",
|
||||
+ "Description": "QGato Search Engine",
|
||||
+ "Method": "GET",
|
||||
+ "URLTemplate": "https://qgato.xyz/search?q={searchTerms}",
|
||||
+ "SuggestURLTemplate": "https://qgato.xyz/suggestions?q={searchTerms}",
|
||||
+ "IconURL": "https://qgato.xyz/static/images/icon.png"
|
||||
+ }
|
||||
+ ],
|
||||
+ "Remove": [
|
||||
+ "Google",
|
||||
+ "Bing",
|
||||
+ "Amazon.com",
|
||||
+ "eBay",
|
||||
+ "Twitter"
|
||||
+ ]
|
||||
+ }
|
||||
+ }
|
||||
+}
|
9
pre-compile-patches/search-engines.patch
Normal file
9
pre-compile-patches/search-engines.patch
Normal file
|
@ -0,0 +1,9 @@
|
|||
t: pref
|
||||
i: /browser/app/profile/firefox.js
|
||||
o: /browser/app/profile/firefox.js
|
||||
|
||||
+pref("browser.search.defaultenginename", "QGato");
|
||||
+pref("browser.search.defaultenginename.US", "QGato");
|
||||
+pref("browser.search.order.1", "QGato");
|
||||
+pref("browser.search.order.2", "DuckDuckGo");
|
||||
+pref("browser.search.order.3", "Startpage");
|
51
run.sh
51
run.sh
|
@ -1,13 +1,48 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Check if --path argument is provided
|
||||
if [[ "$#" -lt 2 ]] || [[ "$1" != "--path" ]]; then
|
||||
echo "Usage: $0 --path <path-to-apply>"
|
||||
exit 1
|
||||
# Parse arguments
|
||||
ROOT_PATH=""
|
||||
PATCHES_SOURCE=""
|
||||
|
||||
while [[ "$#" -gt 0 ]]; do
|
||||
case $1 in
|
||||
--path)
|
||||
ROOT_PATH="$2"
|
||||
shift
|
||||
;;
|
||||
--patches)
|
||||
PATCHES_SOURCE="$2"
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
echo "Unknown parameter: $1"
|
||||
echo "Usage: $0 --path <path-to-apply> --patches <patches-directory>"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
# Validate arguments
|
||||
if [[ -z "$ROOT_PATH" ]] || [[ -z "$PATCHES_SOURCE" ]]; then
|
||||
echo "Both --path and --patches arguments are required."
|
||||
echo "Usage: $0 --path <path-to-apply> --patches <patches-directory>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Extract the --path value
|
||||
ROOT_PATH=$2
|
||||
# Log paths for debugging
|
||||
echo "Root path: $ROOT_PATH"
|
||||
echo "Patches source: $PATCHES_SOURCE"
|
||||
|
||||
# Verify the patches directory exists
|
||||
if [[ ! -d "$PATCHES_SOURCE" ]]; then
|
||||
echo "Failed to access patches source: $PATCHES_SOURCE does not exist."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Run the Go application with the specified path and patches
|
||||
go run main.go pref.go standard.go new.go --path "$ROOT_PATH" --patches "$PATCHES_SOURCE"
|
||||
|
||||
# Exit with the status of the last command
|
||||
exit $?
|
||||
|
||||
# Run the Go application with the specified path
|
||||
go run main.go pref.go standard.go --path "$ROOT_PATH"
|
||||
|
|
Loading…
Add table
Reference in a new issue