Skip to content

Commit d5b1dc9

Browse files
committed
Update patching.mdx
1 parent c0da8a3 commit d5b1dc9

File tree

1 file changed

+210
-50
lines changed

1 file changed

+210
-50
lines changed

docs/src/content/docs/patching.mdx

Lines changed: 210 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -29,33 +29,53 @@ import {
2929

3030
### Patching summary
3131

32-
The script supports the automatic patching of all modules when building, providing the prerequisite conditions are met. In summary it works like this:
33-
34-
- The script will look for a patch file, url file or sources directory in the `patches` sub directory of the build directory.
35-
- If none are found, then the script will check the default online patch directory `userdocs/qbittorrent-nox-static` for a patch or url file to apply (ignoring source files)
36-
- It will compare tag versions of the activated modules and if a match is found it will use an existing local patch or download and apply the patch.
37-
- Order of priorities:
38-
- local - patch file
39-
- local - patch url
40-
- local - sources directory
41-
- remote - patch file
42-
- remote - patch url
32+
The script supports automatic patching of all modules during build with a sophisticated three-method priority system. The patching system works hierarchically to ensure maximum flexibility:
33+
34+
#### Patching Methods (Priority Order)
35+
36+
**Method 1: Source Directory (Highest Priority)**
37+
- Complete source file replacement via `patches/{module}/{version}/source/` directory
38+
- Files are directly copied to the build directory, overwriting existing files
39+
- Most flexible method for extensive modifications
40+
41+
**Method 2: Patch Files (Local)**
42+
- Traditional unified diff patches applied via `git apply` or `patch` command
43+
- Multiple patch sources supported with intelligent merging:
44+
- `patch` file (primary patch)
45+
- `url` file (downloads and merges remote patches)
46+
- `*.patch` and `*.diff` files (merged in alphabetical order)
47+
- Auto-detects git repositories and uses appropriate patching method
48+
49+
**Method 3: Remote Patches (Fallback)**
50+
- Downloads patches from remote GitHub repositories when local patches are empty/missing
51+
- Uses GitHub API for comprehensive directory structure downloads
52+
- Supports both individual files and complete directory trees
53+
- Validates branch names for security
4354

4455
Here is an example local directory structure that the script will use to apply patches to libtorrent `v1.2.19` and qBittorrent `release-5.0.3`
4556

4657
<FileTree>
4758
- qbt-nox-static.bash
48-
- qbt-build
49-
- patches
59+
- qbt-build/
60+
- patches/
5061
- libtorrent/
51-
- v1.2.19
52-
- patch
53-
- Jamfile
54-
- sources/
55-
- qbittorrent/
56-
- 5.0.3
57-
- patch
58-
- sources/src/webui/webui.cpp
62+
- v1.2.19/
63+
- patch # Primary patch file
64+
- url # URL to download remote patch
65+
- 01.patch # Additional patch file
66+
- 02.diff # Additional diff file
67+
- source/ # Source directory (highest priority)
68+
- include/
69+
- src/
70+
- qbittorrent/
71+
- 5.0.3/
72+
- patch # Primary patch file
73+
- url # URL to download remote patch
74+
- custom.patch # Additional patch file
75+
- source/ # Source directory (highest priority)
76+
- src/
77+
- webui/
78+
- webui.cpp # Modified source file
5979
</FileTree>
6080

6181
:::tip
@@ -66,10 +86,30 @@ Use the help command to get more information
6686
```
6787
:::
6888

89+
#### Patch Processing Details
90+
91+
**Multi-Patch Merging:**
92+
- When multiple patches exist, they are intelligently merged into a single unified patch
93+
- Merge order: `patch` file → `url` download → `*.patch`/`*.diff` files (alphabetical)
94+
- Each merged patch is labeled with its source for debugging
95+
- Temporary atomic operations prevent corruption during merging
96+
97+
**Smart Patch Application:**
98+
- Auto-detects if source directory contains a git repository
99+
- Uses `git apply` for git repositories (with validation via `--check`)
100+
- Falls back to traditional `patch -p1` for non-git sources
101+
- Comprehensive error handling and status reporting
102+
103+
**Remote Patch Security:**
104+
- Branch name validation using regex `^[a-zA-Z0-9._-]+$`
105+
- GitHub API integration with proper error handling
106+
- Recursive directory download with JSON parsing validation
107+
- Automatic cleanup of zero-byte failed downloads
108+
69109
:::note
70-
The default remote patch repo if `userdocs/qbittorrent-nox-static` will only store critical patches required to build successfully or apply security fixes.
110+
The default remote patch repository `userdocs/qbittorrent-nox-static` stores only critical patches required for successful builds or security fixes.
71111

72-
There are no customisations or additional patches stored in the default repo. If it applies a remote patch consider that patch essnetial.
112+
No customizations or optional patches are stored in the default repository. Any applied remote patch should be considered essential.
73113
:::
74114

75115
### Boot strapping
@@ -100,54 +140,95 @@ When bootstrapping the script will create the required directory structure using
100140

101141
<Patchinfo/>
102142

103-
## Local patching via example
143+
## Local patching examples
144+
145+
### Method 1: Source Directory Method (Recommended)
104146

105-
In this example we will apply a real patch that can be used with this script from this pinned issue: https://github.com/userdocs/qbittorrent-nox-static/issues/149
147+
This is the most flexible method for extensive modifications. Instead of creating patches, you directly modify source files:
106148

107149
:::note
108150
We will assume you are in folder with the `qbt-nox-static.bash` script.
109151
:::
110152

111-
Step 1: Boot strap the patches directory
153+
**Step 1:** Bootstrap the patches directory
154+
```bash
155+
./qbt.bash -bs-p
156+
```
157+
158+
**Step 2:** Clone the target repository with the specific version
159+
```bash
160+
git clone --branch release-5.0.3 --depth 1 https://github.com/qbittorrent/qBittorrent.git
161+
```
162+
163+
**Step 3:** Copy the entire source tree to your patch directory
164+
```bash
165+
cp -r qBittorrent/* qbt-build/patches/qbittorrent/5.0.3/source/
166+
```
112167

168+
**Step 4:** Edit files directly in the source directory
113169
```bash
114-
qbt.bash -bs-p
170+
# Edit the file you need to modify
171+
nano qbt-build/patches/qbittorrent/5.0.3/source/src/webui/webui.cpp
115172
```
116173

117-
Step 2: Clone the qBittorrent repo targeting the specific tag we want to patch - `--branch release-5.0.3`
174+
**Step 5:** Build with your modifications
175+
```bash
176+
./qbt.bash all
177+
```
118178

179+
The script will automatically detect the `source` directory and copy all files to the build location, overwriting the original source.
180+
181+
### Method 2: Traditional Patch File Method
182+
183+
For smaller, targeted changes, traditional patch files are more efficient:
184+
185+
**Step 1:** Bootstrap and prepare source
119186
```bash
187+
./qbt.bash -bs-p
120188
git clone --branch release-5.0.3 --depth 1 https://github.com/qbittorrent/qBittorrent.git
121189
```
122190

123-
Step 3: Copy the file that we need to edit to our home directory.
124-
191+
**Step 2:** Make a backup and edit the file
125192
```bash
193+
cp qBittorrent/src/webui/webui.cpp webui.cpp.orig
126194
cp qBittorrent/src/webui/webui.cpp webui.cpp
195+
# Edit webui.cpp with your changes
196+
nano webui.cpp
127197
```
128198

129-
Step 4: Now edit the `~/webui.cpp` as per this [example of the applied patch](https://github.com/userdocs/qbittorrent-nox-static-test/blob/9b48000c7faa8baabbab57b733eceb20431d5d77/patches/qbittorrent/5.0.3/source/src/webui/webui.cpp#L41-L75)
130-
131-
Step 5: Once you have finished making your changes you can create a patch file using this command
199+
**Step 3:** Create the patch file
200+
```bash
201+
diff -Naru webui.cpp.orig webui.cpp > qbt-build/patches/qbittorrent/5.0.3/patch
202+
```
132203

204+
**Step 4:** Build with the patch
133205
```bash
134-
diff -Naru qBittorrent/src/webui/webui.cpp webui.cpp > ~/patch
206+
./qbt.bash all
135207
```
136208

137-
You will now have a `patch` file that looks like this: [qbittorrent/5.0.3/patch](https://github.com/userdocs/qbittorrent-nox-static-test/blob/main/patches/qbittorrent/5.0.3/patch)
209+
### Method 3: Multiple Patch Files
210+
211+
The script supports merging multiple patch files automatically:
138212

139-
Step 6:
213+
```bash
214+
# Place multiple patches in the patch directory
215+
echo "patch content 1" > qbt-build/patches/qbittorrent/5.0.3/01-feature-a.patch
216+
echo "patch content 2" > qbt-build/patches/qbittorrent/5.0.3/02-feature-b.patch
217+
echo "patch content 3" > qbt-build/patches/qbittorrent/5.0.3/99-final-fixes.diff
218+
```
140219

141-
The directory structure that will be created will look like this:
220+
The script will merge all `*.patch` and `*.diff` files in alphabetical order into a single unified patch.
142221

222+
### Method 4: URL-based Patches
143223

144-
Place your patch file named `patch` inside the relevant directories. So it would look something like this:
224+
Download and apply patches from remote URLs:
145225

146226
```bash
147-
qbt-build/patches/qbittorrent/5.0.3/patch
227+
# Create a URL file pointing to a remote patch
228+
echo "https://github.com/qbittorrent/qBittorrent/pull/18271.patch" > qbt-build/patches/qbittorrent/5.0.3/url
148229
```
149230

150-
Then the patch file will be automatically matched to the tag used by the script and loaded.
231+
The script will download and apply the patch automatically during build.
151232

152233
### Using custom github tags
153234

@@ -183,35 +264,63 @@ Only the env variables will persist between uses of the script.
183264
qbt.bash -qt master -lt RC_2_0 all
184265
```
185266

186-
### Git based patching
267+
### Remote GitHub-based patching
187268

188-
Instead of a local patch you can use github hosted patch files. Your patches need to be hosted in the root of the repo like this:
269+
The script can automatically download patches from GitHub repositories using the `-pr` switch or `qbt_patches_url` environment variable.
270+
271+
#### Repository Structure
272+
273+
Your patches need to be hosted in a GitHub repository with this structure:
189274

190275
<Tabs>
191276
<TabItem value="qbittorrent" label="qbittorrent" default>
192277

193278
```bash
194279
patches/qbittorrent/master/patch
280+
patches/qbittorrent/master/url
281+
patches/qbittorrent/master/01-custom.patch
282+
patches/qbittorrent/master/source/src/webui/webui.cpp
195283
patches/qbittorrent/4.5.0/patch
284+
patches/qbittorrent/4.5.0/source/
196285
```
197286

198287
</TabItem>
199288
<TabItem value="libtorrent" label="libtorrent">
200289

201290
```bash
202291
patches/libtorrent/RC_2_0/patch
292+
patches/libtorrent/RC_2_0/source/include/
203293
patches/libtorrent/RC_1_2/patch
204-
patches/libtorrent/v1.2.12/patch
294+
patches/libtorrent/v1.2.12/url
205295
```
206296

207297
</TabItem>
208298
</Tabs>
209299

210-
The all you do is use the `pr` switch when using the script. The repo URL is abbreviated to your username and repo:
300+
#### Using Remote Patches
301+
302+
**Method 1:** Command line switch
303+
```bash
304+
./qbt.bash all -pr username/repository
305+
```
306+
307+
**Method 2:** Environment variable
308+
```bash
309+
export qbt_patches_url="username/repository"
310+
./qbt.bash all
311+
```
312+
313+
#### Advanced Remote Patch Features
211314

212-
`bash ~/qbt.bash all -pr username/repo`
315+
**Recursive Directory Downloads:** The script uses GitHub API to recursively download entire directory structures, including nested `source/` directories and multiple patch files.
213316

214-
Then the patch file will be automatically matched to the tag used by the script and loaded.
317+
**Comprehensive File Support:** Downloads all patch-related files:
318+
- `patch` files (primary patches)
319+
- `url` files (for chained remote patches)
320+
- `*.patch` and `*.diff` files
321+
- Complete `source/` directory trees
322+
323+
**Fallback System:** If GitHub API fails, the script falls back to downloading common patch filenames directly.
215324

216325
### How to make a patch
217326

@@ -263,12 +372,63 @@ https://github.com/qbittorrent/qBittorrent/commit/c924904308e806db6e1b321da18c1f
263372

264373
You can download these using `curl` or `wget` and use these as patches in custom builds.
265374

375+
## Troubleshooting and Best Practices
376+
377+
### Debug Information
378+
379+
The script provides detailed output during patch application:
380+
- **Method Selection:** Shows which patching method is being used
381+
- **File Merging:** Labels each merged patch with its source
382+
- **Application Status:** Reports success/failure of patch operations
383+
- **Git Detection:** Indicates whether git apply or traditional patch is used
384+
385+
### Best Practices
386+
387+
**Patch Organization:**
388+
- Use descriptive filenames for multiple patches (e.g., `01-security-fix.patch`, `02-performance.patch`)
389+
- Keep patches atomic - one logical change per patch file
390+
- Test patches individually before combining
391+
392+
**Source Directory Method:**
393+
- Only include modified files to minimize disk usage
394+
- Maintain directory structure matching the original source
395+
- Consider using git to track your modifications in the source directory
396+
397+
**Remote Patch Security:**
398+
- Always review remote patches before applying
399+
- Use trusted repositories for remote patches
400+
- Consider forking and hosting your own patch repositories
401+
402+
**Version Management:**
403+
- Keep patches aligned with specific module versions
404+
- Test patches when updating module versions
405+
- Document patch purposes and compatibility
406+
407+
### Common Issues
408+
409+
**Patch Application Failures:**
410+
- Check patch format (unified diff with `-Naru` options)
411+
- Verify patch applies to correct source version
412+
- Ensure proper line endings (Unix LF, not Windows CRLF)
413+
414+
**Remote Download Issues:**
415+
- Verify GitHub repository structure matches expected format
416+
- Check network connectivity and GitHub API limits
417+
- Use local patches as fallback for critical builds
418+
266419
### Cache folder based patching
267420

268-
The cache folder system is essentially an offline dependency system that allows you to store source files for modules that you want to patch.
421+
The cache folder system serves as an offline dependency system for storing and modifying source files:
269422

270-
This allows the cached folder system to serve as a way patch modules. Source folders are stored in the cache folder and they are copied over to the build directory when the script is run.
423+
**Advantages:**
424+
- Persistent modifications across builds
425+
- Version-specific source storage via git checkout
426+
- More flexible than patch directory method
427+
- Allows comprehensive source tree modifications
271428

272-
This means you can edit the source files in the cache folder and they will be copied over to the build directory when the script is run.
429+
**Usage:**
430+
1. Enable cache folder system in script configuration
431+
2. Modify source files directly in cached directories
432+
3. Files are automatically copied to build directory during compilation
273433

274-
This method is similar to the `source` directory method but it is more flexible and allows you to store multiple versions of the source files via checking out a specific tag or branch.
434+
This method complements the patch system and provides another layer of source customization flexibility.

0 commit comments

Comments
 (0)