mirror of
https://forge.fsky.io/oneflux/omegafox.git
synced 2026-02-10 02:02:03 -08:00
Many changes, bump to v128.0.3-1
- Heavy changes to Makefile. Now uses aria2c to download the Firefox release tarball - New features in developer UI to make patch editing much easier - Modified Playwright's Juggler patches to run on Firefox release v128.0.3 - Bump Playwright Juggler module to June 2th patches - Fix viewport-hijacker and xmas-modified patches for new Firefox release
This commit is contained in:
parent
7ecdd14d4a
commit
bd12f3c46e
19 changed files with 676 additions and 21927 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -1,4 +1,5 @@
|
|||
/camoufox-*
|
||||
/firefox-*
|
||||
/mozilla-unified
|
||||
/extra-docs
|
||||
/.vscode
|
||||
|
|
@ -10,3 +11,4 @@ launch.exe
|
|||
*.old
|
||||
__pycache__/
|
||||
*.pyc
|
||||
wget-log
|
||||
|
|
|
|||
12
Dockerfile
12
Dockerfile
|
|
@ -7,15 +7,15 @@ COPY . /app
|
|||
|
||||
# Install necessary packages
|
||||
RUN apt-get update && apt-get install -y \
|
||||
# Makefile utils
|
||||
build-essential make git msitools wget unzip \
|
||||
# Mach build tools
|
||||
build-essential make msitools wget unzip \
|
||||
# Python
|
||||
python3 python3-dev python3-pip \
|
||||
# Camoufox build system utils
|
||||
p7zip-full golang-go
|
||||
# Camoufox build system tools
|
||||
git p7zip-full golang-go aria2c
|
||||
|
||||
# Fetch Firefox & apply initial patches
|
||||
RUN make fetch && \
|
||||
RUN make setup-minimal && \
|
||||
make mozbootstrap && \
|
||||
mkdir /app/dist
|
||||
|
||||
|
|
@ -23,4 +23,4 @@ RUN make fetch && \
|
|||
VOLUME /root/.mozbuild
|
||||
VOLUME /app/dist
|
||||
|
||||
ENTRYPOINT ["python3", "./multibuild.py"]
|
||||
ENTRYPOINT ["python3", "./multibuild.py"]
|
||||
|
|
|
|||
46
Makefile
46
Makefile
|
|
@ -2,19 +2,21 @@ include upstream.sh
|
|||
export
|
||||
|
||||
cf_source_dir := camoufox-$(version)-$(release)
|
||||
ff_source_tarball := firefox-$(version).source.tar.xz
|
||||
|
||||
debs := python3 python3-dev python3-pip p7zip-full golang-go msitools wget
|
||||
rpms := python3 python3-devel p7zip golang msitools wget
|
||||
pacman := python python-pip p7zip go msitools wget
|
||||
debs := python3 python3-dev python3-pip p7zip-full golang-go msitools wget aria2c
|
||||
rpms := python3 python3-devel p7zip golang msitools wget aria2c
|
||||
pacman := python python-pip p7zip go msitools wget aria2c
|
||||
|
||||
.PHONY: help fetch clean distclean build package build-launcher check-arch revert edits run bootstrap mozbootstrap dir package-common package-linux package-macos package-windows
|
||||
.PHONY: help fetch setup setup-minimal clean distclean build package build-launcher check-arch revert edits run bootstrap mozbootstrap dir package-common package-linux package-macos package-windows
|
||||
|
||||
help:
|
||||
@echo "Available targets:"
|
||||
@echo " fetch - Clone Firefox source code"
|
||||
@echo " fetch - Fetch the Firefox source code"
|
||||
@echo " setup - Setup Camoufox & local git repo for development"
|
||||
@echo " bootstrap - Set up build environment"
|
||||
@echo " mozbootstrap - Sets up mach"
|
||||
@echo " dir - Prepare Camoufox source directory"
|
||||
@echo " dir - Prepare Camoufox source directory with BUILD_TARGET"
|
||||
@echo " revert - Kill all working changes"
|
||||
@echo " edits - Camoufox developer UI"
|
||||
@echo " build-launcher - Build launcher"
|
||||
|
|
@ -27,17 +29,35 @@ help:
|
|||
@echo " run - Run Camoufox"
|
||||
|
||||
fetch:
|
||||
git clone --depth 1 --branch $(BASE_BRANCH) --single-branch $(REMOTE_URL) $(cf_source_dir)
|
||||
cd $(cf_source_dir) && git fetch --depth 1 origin $(BASE_REVISION)
|
||||
make revert
|
||||
aria2c -x16 -s16 -k1M -o $(ff_source_tarball) "https://archive.mozilla.org/pub/firefox/releases/$(version)/source/firefox-$(version).source.tar.xz"; \
|
||||
|
||||
setup-minimal:
|
||||
# Note: Only docker containers are intended to run this directly.
|
||||
# Run this before `make dir` or `make build` to avoid setting up a local git repo.
|
||||
if [ ! -f $(ff_source_tarball) ]; then \
|
||||
make fetch; \
|
||||
fi
|
||||
# Create new cf_source_dir
|
||||
rm -rf $(cf_source_dir)
|
||||
mkdir -p $(cf_source_dir)
|
||||
tar -xJf $(ff_source_tarball) -C $(cf_source_dir) --strip-components=1
|
||||
# Copy settings & additions
|
||||
cd $(cf_source_dir) && bash ../scripts/copy-additions.sh $(version) $(release)
|
||||
|
||||
setup: setup-minimal
|
||||
# Initialize local git repo for development
|
||||
cd $(cf_source_dir) && \
|
||||
git init -b main && \
|
||||
git add -f -A && \
|
||||
git commit -m "Initial commit" && \
|
||||
git tag -a unpatched -m "Initial commit"
|
||||
|
||||
revert:
|
||||
cd $(cf_source_dir) && git reset --hard $(BASE_REVISION)
|
||||
python3 scripts/init-patch.py $(version) $(release)
|
||||
cd $(cf_source_dir) && git reset --hard unpatched
|
||||
|
||||
dir:
|
||||
@if [ ! -d $(cf_source_dir) ]; then \
|
||||
make fetch; \
|
||||
make setup; \
|
||||
fi
|
||||
make clean
|
||||
python3 scripts/patch.py $(version) $(release)
|
||||
|
|
@ -61,7 +81,7 @@ clean:
|
|||
make revert
|
||||
|
||||
distclean:
|
||||
rm -rf $(cf_source_dir)
|
||||
rm -rf $(cf_source_dir) $(ff_source_tarball)
|
||||
|
||||
build:
|
||||
@if [ ! -f $(cf_source_dir)/_READY ]; then \
|
||||
|
|
|
|||
32
README.md
32
README.md
|
|
@ -217,7 +217,7 @@ Miscellaneous (WebGl spoofing, battery status, etc)
|
|||
|
||||
#### Playwright support
|
||||
|
||||
- Added Playwright's Juggler patches
|
||||
- A more updated version of Playwright's Juggler for the latest Firefox, maintained by me
|
||||
- Various config patches to evade bot detection
|
||||
|
||||
#### Debloat/Optimizations
|
||||
|
|
@ -386,9 +386,7 @@ Build artifacts will now appear written under the `dist/` folder.
|
|||
|
||||
---
|
||||
|
||||
## Development Notes
|
||||
|
||||
### How to make a patch
|
||||
## Development Tools
|
||||
|
||||
This repo comes with a developer UI under scripts/developer.py:
|
||||
|
||||
|
|
@ -396,26 +394,20 @@ This repo comes with a developer UI under scripts/developer.py:
|
|||
make edits
|
||||
```
|
||||
|
||||
Patches can be added, removed, and new patches can be added through here.
|
||||
Patches can be edited, created, removed, and managed through here.
|
||||
|
||||
<img src="https://i.imgur.com/cLEn2Yr.png">
|
||||
<img src="https://i.imgur.com/BYAN5J0.png">
|
||||
|
||||
To use, select "Reset workspace", make changes in the camoufox-\*/ folder, then select "Write workspace to patch".
|
||||
### How to make a patch
|
||||
|
||||
1. In the developer UI, click **Reset workspace**.
|
||||
2. Make changes in the `camoufox-*/` folder as needed. You can test your changes with `make build` and `make run`.
|
||||
3. After you're done making changes, click **Write workspace to patch** and save the patch file.
|
||||
|
||||
### How to work on an existing patch
|
||||
|
||||
1. In the developer UI, reset your workspace.
|
||||
2. Then, click "Select patches", and select all **but** the one you want to edit.
|
||||
3. Create a checkpoint. This will commit the current workspace to the local repo:
|
||||
|
||||
```bash
|
||||
make checkpoint
|
||||
```
|
||||
|
||||
4. In the developer UI, click "Select patches", and _apply_ the patch you would like to edit.
|
||||
|
||||
Make your changes. Test builds can be made with `make build` and `make run`.
|
||||
|
||||
5. After you're done editing, hit "Write workspace to patch", and overwrite the existing patch.
|
||||
1. In the developer UI, click **Edit a patch**.
|
||||
2. Select the patch you'd like to edit. Your workspace will be reset to the state of the selected patch.
|
||||
3. After you're done making changes, hit **Write workspace to patch** and overwrite the existing patch file.
|
||||
|
||||
---
|
||||
|
|
|
|||
|
|
@ -368,7 +368,7 @@ class PageTarget {
|
|||
onLocationChange: (aWebProgress, aRequest, aLocation) => this._onNavigated(aLocation),
|
||||
};
|
||||
this._eventListeners = [
|
||||
helper.addObserver(this._updateModalDialogs.bind(this), 'tabmodal-dialog-loaded'),
|
||||
helper.addObserver(this._updateModalDialogs.bind(this), 'common-dialog-loaded'),
|
||||
helper.addProgressListener(tab.linkedBrowser, navigationListener, Ci.nsIWebProgress.NOTIFY_LOCATION),
|
||||
helper.addEventListener(this._linkedBrowser, 'DOMModalDialogClosed', event => this._updateModalDialogs()),
|
||||
helper.addEventListener(this._linkedBrowser, 'WillChangeBrowserRemoteness', event => this._willChangeBrowserRemoteness()),
|
||||
|
|
@ -499,7 +499,7 @@ class PageTarget {
|
|||
}
|
||||
|
||||
_updateModalDialogs() {
|
||||
const prompts = new Set(this._linkedBrowser.tabModalPromptBox ? this._linkedBrowser.tabModalPromptBox.listPrompts() : []);
|
||||
const prompts = new Set(this._linkedBrowser.tabDialogBox.getContentDialogManager().dialogs.map(dialog => dialog.frameContentWindow.Dialog));
|
||||
for (const dialog of this._dialogs.values()) {
|
||||
if (!prompts.has(dialog.prompt())) {
|
||||
this._dialogs.delete(dialog.id());
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ const helper = new Helper();
|
|||
|
||||
let sameProcessInstanceNumber = 0;
|
||||
|
||||
const topBrowingContextToAgents = new Map();
|
||||
|
||||
class JugglerFrameChild extends JSWindowActorChild {
|
||||
constructor() {
|
||||
super();
|
||||
|
|
@ -16,46 +18,66 @@ class JugglerFrameChild extends JSWindowActorChild {
|
|||
}
|
||||
|
||||
handleEvent(aEvent) {
|
||||
if (this._agents && aEvent.type === 'DOMWillOpenModalDialog') {
|
||||
this._agents.channel.pause();
|
||||
const agents = this._agents();
|
||||
if (!agents)
|
||||
return;
|
||||
if (aEvent.type === 'DOMWillOpenModalDialog') {
|
||||
agents.channel.pause();
|
||||
return;
|
||||
}
|
||||
if (this._agents && aEvent.type === 'DOMModalDialogClosed') {
|
||||
this._agents.channel.resumeSoon();
|
||||
if (aEvent.type === 'DOMModalDialogClosed') {
|
||||
agents.channel.resumeSoon();
|
||||
return;
|
||||
}
|
||||
if (this._agents && aEvent.target === this.document)
|
||||
this._agents.pageAgent.onWindowEvent(aEvent);
|
||||
if (this._agents && aEvent.target === this.document)
|
||||
this._agents.frameTree.onWindowEvent(aEvent);
|
||||
if (aEvent.target === this.document) {
|
||||
agents.pageAgent.onWindowEvent(aEvent);
|
||||
agents.frameTree.onWindowEvent(aEvent);
|
||||
}
|
||||
}
|
||||
|
||||
_agents() {
|
||||
return topBrowingContextToAgents.get(this.browsingContext.top);
|
||||
}
|
||||
|
||||
actorCreated() {
|
||||
this.actorName = `content::${this.browsingContext.browserId}/${this.browsingContext.id}/${++sameProcessInstanceNumber}`;
|
||||
|
||||
this._eventListeners.push(helper.addEventListener(this.contentWindow, 'load', event => {
|
||||
this._agents?.pageAgent.onWindowEvent(event);
|
||||
this._agents()?.pageAgent.onWindowEvent(event);
|
||||
}));
|
||||
|
||||
if (this.document.documentURI.startsWith('moz-extension://'))
|
||||
return;
|
||||
this._agents = initialize(this.browsingContext, this.docShell, this);
|
||||
}
|
||||
|
||||
_dispose() {
|
||||
helper.removeListeners(this._eventListeners);
|
||||
// We do not cleanup since agents are shared for all frames in the process.
|
||||
// Child frame events will be forwarded to related top-level agents.
|
||||
if (this.browsingContext.parent)
|
||||
return;
|
||||
|
||||
// TODO: restore the cleanup.
|
||||
// Reset transport so that all messages will be pending and will not throw any errors.
|
||||
// this._channel.resetTransport();
|
||||
// this._agents.pageAgent.dispose();
|
||||
// this._agents.frameTree.dispose();
|
||||
// this._agents = undefined;
|
||||
let agents = topBrowingContextToAgents.get(this.browsingContext);
|
||||
if (!agents) {
|
||||
agents = initialize(this.browsingContext, this.docShell);
|
||||
topBrowingContextToAgents.set(this.browsingContext, agents);
|
||||
}
|
||||
agents.channel.bindToActor(this);
|
||||
agents.actor = this;
|
||||
}
|
||||
|
||||
didDestroy() {
|
||||
this._dispose();
|
||||
helper.removeListeners(this._eventListeners);
|
||||
|
||||
if (this.browsingContext.parent)
|
||||
return;
|
||||
|
||||
const agents = topBrowingContextToAgents.get(this.browsingContext);
|
||||
// The agents are already re-bound to a new actor.
|
||||
if (agents.actor !== this)
|
||||
return;
|
||||
|
||||
topBrowingContextToAgents.delete(this.browsingContext);
|
||||
|
||||
agents.channel.resetTransport();
|
||||
agents.pageAgent.dispose();
|
||||
agents.frameTree.dispose();
|
||||
}
|
||||
|
||||
receiveMessage() { }
|
||||
|
|
|
|||
|
|
@ -370,7 +370,12 @@ class PageAgent {
|
|||
const unsafeObject = frame.unsafeObject(objectId);
|
||||
if (!unsafeObject)
|
||||
throw new Error('Object is not input!');
|
||||
const nsFiles = await Promise.all(files.map(filePath => File.createFromFileName(filePath)));
|
||||
let nsFiles;
|
||||
if (unsafeObject.webkitdirectory) {
|
||||
nsFiles = await new Directory(files[0]).getFiles(true);
|
||||
} else {
|
||||
nsFiles = await Promise.all(files.map(filePath => File.createFromFileName(filePath)));
|
||||
}
|
||||
unsafeObject.mozSetFileArray(nsFiles);
|
||||
const events = [
|
||||
new (frame.domWindow().Event)('input', { bubbles: true, cancelable: true, composed: true }),
|
||||
|
|
|
|||
|
|
@ -7,24 +7,10 @@ const {FrameTree} = ChromeUtils.import('chrome://juggler/content/content/FrameTr
|
|||
const {SimpleChannel} = ChromeUtils.import('chrome://juggler/content/SimpleChannel.js');
|
||||
const {PageAgent} = ChromeUtils.import('chrome://juggler/content/content/PageAgent.js');
|
||||
|
||||
const browsingContextToAgents = new Map();
|
||||
const helper = new Helper();
|
||||
|
||||
function initialize(browsingContext, docShell, actor) {
|
||||
if (browsingContext.parent) {
|
||||
// For child frames, return agents from the main frame.
|
||||
return browsingContextToAgents.get(browsingContext.top);
|
||||
}
|
||||
|
||||
let data = browsingContextToAgents.get(browsingContext);
|
||||
if (data) {
|
||||
// Rebind from one main frame actor to another one.
|
||||
data.channel.bindToActor(actor);
|
||||
return data;
|
||||
}
|
||||
|
||||
data = { channel: undefined, pageAgent: undefined, frameTree: undefined, failedToOverrideTimezone: false };
|
||||
browsingContextToAgents.set(browsingContext, data);
|
||||
function initialize(browsingContext, docShell) {
|
||||
const data = { channel: undefined, pageAgent: undefined, frameTree: undefined, failedToOverrideTimezone: false };
|
||||
|
||||
const applySetting = {
|
||||
geolocation: (geolocation) => {
|
||||
|
|
@ -84,7 +70,6 @@ function initialize(browsingContext, docShell, actor) {
|
|||
data.frameTree.addBinding(worldName, name, script);
|
||||
data.frameTree.setInitScripts([...contextCrossProcessCookie.initScripts, ...pageCrossProcessCookie.initScripts]);
|
||||
data.channel = new SimpleChannel('', 'process-' + Services.appinfo.processID);
|
||||
data.channel.bindToActor(actor);
|
||||
data.pageAgent = new PageAgent(data.channel, data.frameTree);
|
||||
docShell.fileInputInterceptionEnabled = !!pageCrossProcessCookie.interceptFileChooserDialog;
|
||||
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load diff
|
|
@ -1,7 +1,7 @@
|
|||
diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js
|
||||
diff --git a/browser/base/content/browser-init.js b/browser/base/content/browser-init.js
|
||||
index cc62392ab0..0c68a0e991 100644
|
||||
--- a/browser/base/content/browser.js
|
||||
+++ b/browser/base/content/browser.js
|
||||
--- a/browser/base/content/browser-init.js
|
||||
+++ b/browser/base/content/browser-init.js
|
||||
@@ -1568,7 +1568,7 @@ var gBrowserInit = {
|
||||
updateBookmarkToolbarVisibility();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,21 +1,21 @@
|
|||
diff --git a/browser/installer/package-manifest.in b/browser/installer/package-manifest.in
|
||||
index a638dbe8e2..f0d4310cfa 100644
|
||||
index bb0f71dd60..3ad3d84b82 100644
|
||||
--- a/browser/installer/package-manifest.in
|
||||
+++ b/browser/installer/package-manifest.in
|
||||
@@ -253,6 +253,11 @@
|
||||
@RESPATH@/browser/defaults/settings/main
|
||||
@RESPATH@/browser/defaults/settings/security-state
|
||||
@@ -244,6 +244,11 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
+; Camoufox specific files
|
||||
+@RESPATH@/defaults/pref/local-settings.js
|
||||
+@RESPATH@/distribution/policies.json
|
||||
+@RESPATH@/camoufox.cfg
|
||||
+
|
||||
; Warning: changing the path to channel-prefs.js can cause bugs (Bug 756325)
|
||||
; Technically this is an app pref file, but we are keeping it in the original
|
||||
; gre location for now.
|
||||
; [Default Preferences]
|
||||
; All the pref files must be part of base to prevent migration bugs
|
||||
@RESPATH@/browser/@PREF_DIR@/firefox.js
|
||||
diff --git a/lw/moz.build b/lw/moz.build
|
||||
index e69de29..8589aac 100644
|
||||
index e69de29bb2..208184547e 100644
|
||||
--- a/lw/moz.build
|
||||
+++ b/lw/moz.build
|
||||
@@ -0,0 +1,13 @@
|
||||
|
|
@ -33,10 +33,10 @@ index e69de29..8589aac 100644
|
|||
+ "local-settings.js",
|
||||
+]
|
||||
diff --git a/moz.build b/moz.build
|
||||
index 5af3642165..01f5a7e45b 100644
|
||||
index 9db27fd056..e1ec1dc872 100644
|
||||
--- a/moz.build
|
||||
+++ b/moz.build
|
||||
@@ -218,3 +218,5 @@ SPHINX_TREES["mots"] = "docs/mots"
|
||||
@@ -220,3 +220,5 @@ SPHINX_TREES["mots"] = "docs/mots"
|
||||
SPHINX_TREES["update-infrastructure"] = "docs/update-infrastructure"
|
||||
|
||||
include("build/templates.mozbuild")
|
||||
|
|
|
|||
|
|
@ -15,10 +15,7 @@ import sys
|
|||
|
||||
major, minor = sys.version_info[:2]
|
||||
if (major < 3) or (major == 3 and minor < 8):
|
||||
print(
|
||||
"Bootstrap currently only runs on Python 3.8+."
|
||||
"Please try re-running with python3.8+."
|
||||
)
|
||||
print("Bootstrap currently only runs on Python 3.8+." "Please try re-running with python3.8+.")
|
||||
sys.exit(1)
|
||||
|
||||
import ctypes
|
||||
|
|
@ -147,9 +144,7 @@ def hg_clone_firefox(hg: Path, dest: Path, head_repo, head_rev):
|
|||
[str(hg), "pull", "https://hg.mozilla.org/mozilla-unified"], cwd=str(dest)
|
||||
)
|
||||
if not res and head_repo:
|
||||
res = subprocess.call(
|
||||
[str(hg), "pull", head_repo, "-r", head_rev], cwd=str(dest)
|
||||
)
|
||||
res = subprocess.call([str(hg), "pull", head_repo, "-r", head_rev], cwd=str(dest))
|
||||
print("")
|
||||
if res:
|
||||
print(CLONE_MERCURIAL_PULL_FAIL % dest)
|
||||
|
|
@ -159,10 +154,7 @@ def hg_clone_firefox(hg: Path, dest: Path, head_repo, head_rev):
|
|||
print(f'updating to "{head_rev}" - the development head of Gecko and Firefox')
|
||||
res = subprocess.call([str(hg), "update", "-r", head_rev], cwd=str(dest))
|
||||
if res:
|
||||
print(
|
||||
f"error updating; you will need to `cd {dest} && hg update -r central` "
|
||||
"manually"
|
||||
)
|
||||
print(f"error updating; you will need to `cd {dest} && hg update -r central` " "manually")
|
||||
return dest
|
||||
|
||||
|
||||
|
|
@ -182,9 +174,7 @@ def git_clone_firefox(git: Path, dest: Path, watchman: Path, head_repo, head_rev
|
|||
# tiny bootstrapping script.
|
||||
tempdir = Path(tempfile.mkdtemp())
|
||||
with open(tempdir / "download.py", "wb") as fh:
|
||||
shutil.copyfileobj(
|
||||
urlopen(f"{cinnabar_url}/raw/master/download.py"), fh
|
||||
)
|
||||
shutil.copyfileobj(urlopen(f"{cinnabar_url}/raw/master/download.py"), fh)
|
||||
|
||||
subprocess.check_call(
|
||||
[sys.executable, str(tempdir / "download.py")],
|
||||
|
|
@ -213,12 +203,8 @@ def git_clone_firefox(git: Path, dest: Path, watchman: Path, head_repo, head_rev
|
|||
],
|
||||
env=env,
|
||||
)
|
||||
subprocess.check_call(
|
||||
[str(git), "config", "fetch.prune", "true"], cwd=str(dest), env=env
|
||||
)
|
||||
subprocess.check_call(
|
||||
[str(git), "config", "pull.ff", "only"], cwd=str(dest), env=env
|
||||
)
|
||||
subprocess.check_call([str(git), "config", "fetch.prune", "true"], cwd=str(dest), env=env)
|
||||
subprocess.check_call([str(git), "config", "pull.ff", "only"], cwd=str(dest), env=env)
|
||||
|
||||
if head_repo:
|
||||
subprocess.check_call(
|
||||
|
|
@ -278,9 +264,7 @@ def add_microsoft_defender_antivirus_exclusions(dest, no_system_changes):
|
|||
return
|
||||
|
||||
def print_attempt_exclusion(path):
|
||||
print(
|
||||
f"Attempting to add exclusion path to Microsoft Defender Antivirus for: {path}"
|
||||
)
|
||||
print(f"Attempting to add exclusion path to Microsoft Defender Antivirus for: {path}")
|
||||
|
||||
powershell_exe = str(powershell_exe)
|
||||
paths = []
|
||||
|
|
|
|||
54
scripts/copy-additions.sh
Normal file
54
scripts/copy-additions.sh
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Simple bash script that copies the additions from the repository into the source directory
|
||||
# Must be ran from within the source directory
|
||||
|
||||
# Check if correct number of arguments are provided
|
||||
if [ "$#" -ne 2 ]; then
|
||||
echo "Usage: $0 <version> <release>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Assign command-line arguments to variables
|
||||
version="$1"
|
||||
release="$2"
|
||||
|
||||
# Function to run commands and exit on failure
|
||||
run() {
|
||||
echo "$ $1"
|
||||
eval "$1"
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Command failed: $1"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Copy the search-config.json file
|
||||
run 'cp -v ../assets/search-config.json services/settings/dumps/main/search-config.json'
|
||||
|
||||
# vs_pack.py issue... should be temporary
|
||||
run 'cp -v ../patches/librewolf/pack_vs.py build/vs/'
|
||||
|
||||
# Apply most recent `settings` repository files
|
||||
run 'mkdir -p lw'
|
||||
pushd lw > /dev/null
|
||||
run 'cp -v ../../settings/camoufox.cfg .'
|
||||
run 'cp -v ../../settings/distribution/policies.json .'
|
||||
run 'cp -v ../../settings/defaults/pref/local-settings.js .'
|
||||
run 'cp -v ../../settings/chrome.css .'
|
||||
run 'touch moz.build'
|
||||
popd > /dev/null
|
||||
|
||||
# Copy ALL new files/folders from ../additions to .
|
||||
run 'cp -r ../additions/* .'
|
||||
|
||||
# Provide a script that fetches and bootstraps Nightly and some mozconfigs
|
||||
run 'cp -v ../scripts/mozfetch.sh lw/'
|
||||
|
||||
# Override the firefox version
|
||||
for file in "browser/config/version.txt" "browser/config/version_display.txt"; do
|
||||
echo "${version}-${release}" > "$file"
|
||||
done
|
||||
|
||||
# Generate locales
|
||||
run "bash ../scripts/generate-locales.sh"
|
||||
|
|
@ -4,11 +4,12 @@
|
|||
GUI for managing Camoufox patches.
|
||||
"""
|
||||
|
||||
import os
|
||||
import contextlib
|
||||
import os
|
||||
import re
|
||||
|
||||
import easygui
|
||||
from patch import list_files, patch, run
|
||||
from patch import list_patches, patch, run
|
||||
|
||||
|
||||
def into_camoufox_dir():
|
||||
|
|
@ -41,7 +42,7 @@ def reset_camoufox():
|
|||
|
||||
|
||||
def run_patches(reverse=False):
|
||||
patch_files = list(list_files('../patches', suffix='*.patch'))
|
||||
patch_files = list_patches()
|
||||
if reverse:
|
||||
title = "Unpatch files"
|
||||
else:
|
||||
|
|
@ -54,16 +55,116 @@ def run_patches(reverse=False):
|
|||
patch(patch_file, reverse=reverse)
|
||||
|
||||
|
||||
def open_patch_workspace(selected_patch, stop_at_patch=False):
|
||||
"""
|
||||
Resets a workspace for editing a patch.
|
||||
|
||||
Process:
|
||||
1. Resets Camoufox
|
||||
2. Patches all except the selected patch
|
||||
3. Sets checkpoint
|
||||
4. Reruns the selected patch, but reads rejects similar to "Find broken patches"
|
||||
"""
|
||||
# Prepare UI
|
||||
patch_files = list_patches()
|
||||
|
||||
# Reset workspace
|
||||
reset_camoufox()
|
||||
|
||||
skipped_patches = []
|
||||
applied_patches = []
|
||||
# Patch all except the selected patch
|
||||
for patch_file in patch_files:
|
||||
if patch_file == selected_patch:
|
||||
if stop_at_patch:
|
||||
break
|
||||
continue
|
||||
if is_broken(patch_file):
|
||||
print(f'Skipping broken patch: {patch_file}')
|
||||
skipped_patches.append(patch_file)
|
||||
continue
|
||||
patch(patch_file, silent=True)
|
||||
applied_patches.append(patch_file)
|
||||
|
||||
# Set checkpoint
|
||||
if applied_patches:
|
||||
with temp_cd('..'):
|
||||
run('make checkpoint')
|
||||
|
||||
# Set message for patch result
|
||||
patch_broken = is_broken(selected_patch)
|
||||
if patch_broken:
|
||||
message = "Broken patch has been applied to the workspace.\n\nPLEASE FIX THE FOLLOWING:\n"
|
||||
else:
|
||||
message = "Successfully applied patch to the workspace.\n"
|
||||
|
||||
# Run the selected patch
|
||||
patch_result = os.popen(f'patch -p1 -i "{selected_patch}"').read()
|
||||
|
||||
# Find any line containing a file .rej
|
||||
if patch_broken:
|
||||
for line in patch_result.splitlines():
|
||||
if file := re.search(r'[^\s]+\.rej', line):
|
||||
message += f'> {file[0]}' + '\n'
|
||||
|
||||
def msg_format_paths(file_list):
|
||||
message = ''
|
||||
for patch_file in file_list:
|
||||
message += '> ' + patch_file[len('../patches/') :] + '\n'
|
||||
return message
|
||||
|
||||
# Show which patches were applied if not all patches were allowed
|
||||
if stop_at_patch and applied_patches:
|
||||
message += f'\n{"-" * 22} Applied patches {"-" * 22}\n'
|
||||
message += msg_format_paths(applied_patches)
|
||||
|
||||
if skipped_patches:
|
||||
message += f'\n{"-" * 17} Skipped patches (broken!) {"-" * 17}\n'
|
||||
message += msg_format_paths(skipped_patches)
|
||||
|
||||
message += f'\n{"-" * 24} Full output {"-" * 24}\n{patch_result}'
|
||||
easygui.textbox("Patch Result", "Patch Result", message)
|
||||
|
||||
|
||||
def check_patch(patch_file):
|
||||
"""
|
||||
Checks if the patch can be applied or can be reversed
|
||||
Returns (can_apply, can_reverse, is_broken)
|
||||
"""
|
||||
can_apply = not bool(
|
||||
os.system(f'patch -p1 --dry-run --force -i "{patch_file}" > /dev/null 2>&1')
|
||||
)
|
||||
can_reverse = not bool(
|
||||
os.system(f'patch -p1 -R --dry-run --force -i "{patch_file}" > /dev/null 2>&1')
|
||||
)
|
||||
return can_apply, can_reverse, not (can_apply or can_reverse)
|
||||
|
||||
|
||||
def is_broken(patch_file):
|
||||
_, _, is_broken = check_patch(patch_file)
|
||||
return is_broken
|
||||
|
||||
|
||||
def get_rejects(patch_file):
|
||||
# Returns a broken patch's rejects
|
||||
cmd = f'patch -p1 -i "{patch_file}" | tee /dev/stderr | sed -n -E \'s/^.*saving rejects to file (.*\\.rej)$/\\1/p\''
|
||||
result = os.popen(cmd).read().strip()
|
||||
return result.split('\n') if result else []
|
||||
|
||||
|
||||
# GUI Choicebox with options
|
||||
choices = [
|
||||
"Reset workspace",
|
||||
"Check patches",
|
||||
"Set checkpoint",
|
||||
"Edit a patch",
|
||||
"\u2014" * 44,
|
||||
"List patches currently applied",
|
||||
"Select patches",
|
||||
"Reverse patches",
|
||||
"Find broken patches",
|
||||
"Find broken patches (resets workspace)",
|
||||
"\u2014" * 44,
|
||||
"See current workspace",
|
||||
"Write workspace to patch",
|
||||
"Set checkpoint",
|
||||
]
|
||||
|
||||
"""
|
||||
|
|
@ -75,23 +176,34 @@ def handle_choice(choice):
|
|||
match choice:
|
||||
case "Reset workspace":
|
||||
reset_camoufox()
|
||||
easygui.msgbox("Reset completed and bootstrap patches applied.", "Reset Complete")
|
||||
easygui.msgbox(
|
||||
"Reset. All patches & changes have been removed.",
|
||||
"Reset Complete",
|
||||
)
|
||||
|
||||
case "Check patches":
|
||||
case "List patches currently applied":
|
||||
# Produces a list of patches that are applied
|
||||
apply_dict = {}
|
||||
for patch_file in list_files('../patches', suffix='*.patch'):
|
||||
result = os.system(f'git apply --check "{patch_file}" > /dev/null 2>&1')
|
||||
if result == 0:
|
||||
for patch_file in list_patches():
|
||||
print(f'FILE: {patch_file}')
|
||||
can_apply, can_reverse, broken = check_patch(patch_file)
|
||||
if broken:
|
||||
apply_dict[patch_file] = 'BROKEN'
|
||||
elif can_reverse:
|
||||
apply_dict[patch_file] = 'APPLIED'
|
||||
elif can_apply:
|
||||
apply_dict[patch_file] = 'NOT APPLIED'
|
||||
else:
|
||||
apply_dict[patch_file] = 'APPLIED'
|
||||
apply_dict[patch_file] = 'UNKNOWN (broken .patch?)'
|
||||
easygui.textbox(
|
||||
"Patching Result",
|
||||
"Patching Result",
|
||||
'\n'.join(
|
||||
sorted(
|
||||
(f'{v}\t{os.path.basename(k)[:-6]}' for k, v in apply_dict.items()),
|
||||
(
|
||||
f'{v}\t{k[len("../patches/"):-len('.patch')]}'
|
||||
for k, v in apply_dict.items()
|
||||
),
|
||||
reverse=True,
|
||||
key=lambda x: x[0],
|
||||
)
|
||||
|
|
@ -111,24 +223,59 @@ def handle_choice(choice):
|
|||
run_patches(reverse=True)
|
||||
easygui.msgbox("Unpatching completed.", "Unpatching Complete")
|
||||
|
||||
case "Find broken patches":
|
||||
case "Find broken patches (resets workspace)":
|
||||
reset_camoufox()
|
||||
|
||||
broken_patches = []
|
||||
for patch_file in list_files('../patches', suffix='*.patch'):
|
||||
cmd = rf'patch -p1 -i "{patch_file}" | tee /dev/stderr | sed -r --quiet \'s/^.*saving rejects to file (.*\.rej)$/\\1/p\''
|
||||
result = os.popen(cmd).read().strip()
|
||||
print(result)
|
||||
if result:
|
||||
broken_patches.append((patch_file, result))
|
||||
for patch_file in list_patches():
|
||||
if reject_files := get_rejects(patch_file):
|
||||
broken_patches.append((patch_file, reject_files))
|
||||
|
||||
if not broken_patches:
|
||||
easygui.msgbox("All patches applied successfully", "Patching Result")
|
||||
else:
|
||||
message = "Some patches failed to apply:\n\n"
|
||||
for patch_file, rejects in broken_patches:
|
||||
message += f"Patch: {patch_file}\nRejects: {rejects}\n\n"
|
||||
easygui.textbox("Patching Result", "Failed Patches", message)
|
||||
return
|
||||
|
||||
# Display message
|
||||
message = "Some patches failed to apply:\n\n"
|
||||
for patch_file, rejects in broken_patches:
|
||||
message += '> ' + patch_file[len('../patches/') :] + '\n'
|
||||
message += '\n\n\n'
|
||||
|
||||
# Show file contents
|
||||
for patch_file, rejects in broken_patches:
|
||||
message += f"Patch: {patch_file[len('../patches/'):]}\nRejects:\n"
|
||||
for reject in rejects:
|
||||
message += f"{reject}\n"
|
||||
with open(reject, 'r') as f:
|
||||
message += f.read()
|
||||
message += "-" * 62 + "\n"
|
||||
message += '\n'
|
||||
easygui.textbox("Patching Result", "Failed Patches", message)
|
||||
|
||||
case "Edit a patch":
|
||||
patch_files = list_patches()
|
||||
ui_choices = [
|
||||
(
|
||||
f'{n+1}. {"BOOTSTRAP:" if os.path.basename(file_name).startswith("0-") else ""} '
|
||||
f'{file_name[len("../patches/") :]}'
|
||||
)
|
||||
for n, file_name in enumerate(patch_files)
|
||||
]
|
||||
selected_patch = easygui.choicebox(
|
||||
"Select patch to open in workspace",
|
||||
"Patches",
|
||||
ui_choices,
|
||||
)
|
||||
# Return if user cancelled
|
||||
if not selected_patch:
|
||||
return
|
||||
# Get file path of selected patch
|
||||
selected_patch = patch_files[ui_choices.index(selected_patch)]
|
||||
open_patch_workspace(
|
||||
selected_patch,
|
||||
# Patches starting with 0- rely on being ran first.
|
||||
stop_at_patch=os.path.basename(selected_patch).startswith('0-'),
|
||||
)
|
||||
|
||||
case "See current workspace":
|
||||
result = os.popen('git diff').read()
|
||||
|
|
@ -136,13 +283,16 @@ def handle_choice(choice):
|
|||
|
||||
case "Write workspace to patch":
|
||||
# Open a file dialog to select a file to write the diff to
|
||||
file_path = easygui.filesavebox(
|
||||
"Select a file to write the diff to", "Write Diff", filetypes="*.patch"
|
||||
)
|
||||
with temp_cd('../patches'):
|
||||
file_path = easygui.filesavebox(
|
||||
"Select a file to write the patch to",
|
||||
"Write Patch",
|
||||
filetypes="*.patch",
|
||||
)
|
||||
if not file_path:
|
||||
exit()
|
||||
run(f'git diff > {file_path}')
|
||||
easygui.msgbox("Diff written to file", "Diff Written")
|
||||
easygui.msgbox(f"Patch has been written to {file_path}.", "Patch Written")
|
||||
|
||||
case _:
|
||||
print('No choice selected')
|
||||
|
|
|
|||
|
|
@ -1,25 +0,0 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
"""
|
||||
Simple script to apply *.bootstrap patches
|
||||
This was separated from the main patch script because its indended to run on docker build.
|
||||
|
||||
Run:
|
||||
python3 scripts/init-patch.py <version> <release>
|
||||
"""
|
||||
|
||||
from patch import list_files, patch, enter_srcdir, leave_srcdir
|
||||
|
||||
|
||||
def apply_bootstrap_patches():
|
||||
enter_srcdir()
|
||||
|
||||
# Apply bootstraps first
|
||||
for patch_file in list_files('../patches', suffix='*.bootstrap'):
|
||||
patch(patch_file)
|
||||
|
||||
leave_srcdir()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
apply_bootstrap_patches()
|
||||
|
|
@ -139,7 +139,7 @@ def main():
|
|||
includes=args.includes,
|
||||
fonts=args.fonts,
|
||||
new_file=new_name,
|
||||
os==args.os,
|
||||
os=args.os,
|
||||
)
|
||||
|
||||
print(f"Packaging complete for {args.os}")
|
||||
|
|
|
|||
|
|
@ -56,12 +56,15 @@ def run(cmd, exit_on_fail=True, do_print=True):
|
|||
return retval
|
||||
|
||||
|
||||
def patch(patchfile, reverse=False):
|
||||
def patch(patchfile, reverse=False, silent=False):
|
||||
if reverse:
|
||||
cmd = f"patch -p1 -R -i {patchfile}"
|
||||
else:
|
||||
cmd = f"patch -p1 -i {patchfile}"
|
||||
print(f"\n*** -> {cmd}")
|
||||
if silent:
|
||||
cmd += ' > /dev/null'
|
||||
else:
|
||||
print(f"\n*** -> {cmd}")
|
||||
sys.stdout.flush()
|
||||
if options.no_execute:
|
||||
return
|
||||
|
|
@ -97,7 +100,7 @@ def leave_srcdir():
|
|||
os.chdir("..")
|
||||
|
||||
|
||||
def list_files(root_dir, suffix='*.patch'):
|
||||
def list_files(root_dir, suffix):
|
||||
for root, _, files in os.walk(root_dir):
|
||||
for file in fnmatch.filter(files, suffix):
|
||||
full_path = os.path.join(root, file)
|
||||
|
|
@ -105,6 +108,10 @@ def list_files(root_dir, suffix='*.patch'):
|
|||
yield os.path.join('..', 'patches', relative_path).replace('\\', '/')
|
||||
|
||||
|
||||
def list_patches(root_dir='../patches', suffix='*.patch'):
|
||||
return sorted(list_files(root_dir, suffix), key=lambda f: os.path.basename(f))
|
||||
|
||||
|
||||
def add_rustup(*targets):
|
||||
for rust_target in targets:
|
||||
os.system(f'~/.cargo/bin/rustup target add "{rust_target}"')
|
||||
|
|
@ -124,42 +131,10 @@ def camoufox_patches():
|
|||
print(f'Using target: {moz_target}')
|
||||
_update_mozconfig()
|
||||
|
||||
# Copy the search-config.json file
|
||||
run('cp -v ../assets/search-config.json services/settings/dumps/main/search-config.json')
|
||||
|
||||
# Then apply all other patches
|
||||
for patch_file in list_files('../patches'):
|
||||
for patch_file in list_patches():
|
||||
patch(patch_file)
|
||||
|
||||
# vs_pack.py issue... should be temporary
|
||||
run('cp -v ../patches/librewolf/pack_vs.py build/vs/')
|
||||
|
||||
"""
|
||||
Apply most recent `settings` repository files.
|
||||
"""
|
||||
|
||||
run('mkdir -p lw', exit_on_fail=False)
|
||||
enter_srcdir('lw')
|
||||
run('cp -v ../../settings/camoufox.cfg .')
|
||||
run('cp -v ../../settings/distribution/policies.json .')
|
||||
run('cp -v ../../settings/defaults/pref/local-settings.js .')
|
||||
run('cp -v ../../settings/chrome.css .')
|
||||
leave_srcdir()
|
||||
|
||||
# Copy ALL new files/folders from ../additions to .
|
||||
run('cp -r ../additions/* .')
|
||||
|
||||
# Provide a script that fetches and bootstraps Nightly and some mozconfigs
|
||||
run('cp -v ../scripts/mozfetch.sh lw/')
|
||||
|
||||
# Override the firefox version
|
||||
for file in ["browser/config/version.txt", "browser/config/version_display.txt"]:
|
||||
with open(file, "w") as f:
|
||||
f.write(f"{version}-{release}")
|
||||
|
||||
# Generate locales
|
||||
run("bash ../scripts/generate-locales.sh")
|
||||
|
||||
leave_srcdir()
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,2 @@
|
|||
REMOTE_URL=https://github.com/mozilla/gecko-dev
|
||||
BASE_BRANCH=release
|
||||
BASE_REVISION=bd7e0ac24a6fb1cddde3e45ea191b7abcc90cf56
|
||||
|
||||
version=128.0
|
||||
release=1
|
||||
version=128.0.3
|
||||
release=1
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue