mirror of
https://github.com/lucannez64/darling-lol.git
synced 2026-10-26 19:47:42 +00:00
Add an update script that re-applies changed patches
After a pull that changed a patch, prepare.py stopped: the patch neither applied nor reverse-applied to a tree holding its earlier version. Now it looks for the earlier version applied in that component -- the copy it records in build/applied-patches, or a version from this repository's history -- reverts exactly it and applies the new one. It never resets a repository; when nothing matches it stops and names the repository with other edits, and it restores the earlier version if the new one does not apply. scripts/update.sh runs build.sh, the base install and install-runtime.sh, and refuses to start while a Riot Client or League process is open, since the install steps stop Darling. Checked on a sandbox Indium checkout holding the previous patch: the result matches a clean apply, a second run is a no-op, an unrelated local edit survives and a conflicting one stops with the error. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
f5c46c6529
commit
3b90c550a7
4 files changed
+70
-3
No files matched your search
+28
-2
@@ -8,6 +8,21 @@ p.add_argument('--source',type=Path,default=ROOT/'build/darling-src')
|
||||
p.add_argument('--check-only',action='store_true',help='validate against temporary base indexes, without changing existing source')
|
||||
a=p.parse_args();source=a.source.resolve();manifest=json.loads((ROOT/'upstream/manifest.json').read_text())
|
||||
def run(args,**kwargs):return subprocess.run(args,check=True,**kwargs)
|
||||
def applies(repo,patch,reverse=False):
|
||||
return subprocess.run(['git','-C',str(repo),'apply',*(['--reverse'] if reverse else []),'--check','-'],input=patch,text=True,
|
||||
stdout=subprocess.DEVNULL,stderr=subprocess.DEVNULL).returncode==0
|
||||
# The rendered text of each patch as last applied, so a later version can revert exactly it.
|
||||
applied=ROOT/'build/applied-patches'
|
||||
def record_patch(component,patch):
|
||||
applied.mkdir(parents=True,exist_ok=True);(applied/Path(component['patch']).name).write_text(patch)
|
||||
def previous_patches(component):
|
||||
"""Earlier applied versions of a component's patch: the recorded copy, then each version in this repository's history."""
|
||||
recorded=applied/Path(component['patch']).name
|
||||
if recorded.exists():yield recorded.read_text()
|
||||
history=subprocess.run(['git','-C',str(ROOT),'log','--format=%H','--',component['patch']],text=True,capture_output=True).stdout.split()
|
||||
for commit in history:
|
||||
shown=subprocess.run(['git','-C',str(ROOT),'show',f"{commit}:{component['patch']}"],text=True,capture_output=True)
|
||||
if shown.returncode==0:yield render(shown.stdout)
|
||||
if not (source/'.git').exists():
|
||||
if a.check_only:p.error('check-only requires an existing pinned source checkout')
|
||||
source.parent.mkdir(parents=True,exist_ok=True)
|
||||
@@ -35,9 +50,20 @@ for component in manifest['components']:
|
||||
run(['git','-C',str(repo),'read-tree',component['revision']],env=env)
|
||||
run(['git','-C',str(repo),'apply','--cached','--check','--whitespace=nowarn','-'],input=patch,text=True,env=env)
|
||||
else:
|
||||
already=subprocess.run(['git','-C',str(repo),'apply','--reverse','--check','-'],input=patch,text=True,stdout=subprocess.DEVNULL,stderr=subprocess.DEVNULL).returncode==0
|
||||
already=applies(repo,patch,reverse=True)
|
||||
if not already and not applies(repo,patch):
|
||||
# An older version of this patch is applied (the checkout predates a pull). Revert exactly that
|
||||
# version, never a reset, so other edits in the repository survive.
|
||||
old=next((text for text in previous_patches(component) if applies(repo,text,reverse=True)),None)
|
||||
if old is None:raise SystemExit(f"{component['path']}: {component['patch']} neither applies nor matches an earlier applied version; "
|
||||
f"the checkout has other edits. Commit or discard them in {repo}, then run this again.")
|
||||
print(f"Replacing the earlier {component['patch']} in {component['path']}",flush=True)
|
||||
run(['git','-C',str(repo),'apply','--reverse','--whitespace=nowarn','-'],input=old,text=True)
|
||||
if not applies(repo,patch):
|
||||
run(['git','-C',str(repo),'apply','--whitespace=nowarn','-'],input=old,text=True)
|
||||
raise SystemExit(f"{component['path']}: the new {component['patch']} does not apply to the pinned revision; the earlier version was restored")
|
||||
if not already:
|
||||
run(['git','-C',str(repo),'apply','--check','-'],input=patch,text=True)
|
||||
run(['git','-C',str(repo),'apply','--whitespace=nowarn','-'],input=patch,text=True)
|
||||
record_patch(component,patch)
|
||||
print(('Checked ' if a.check_only else 'Prepared ')+component['path'],flush=True)
|
||||
print('All',len(manifest['components']),'component patches validated' if a.check_only else 'component patches ready')
|
||||
Executable
+29
@@ -0,0 +1,29 @@
|
||||
#!/bin/sh
|
||||
# Bring an existing build and installation up to date after `git pull`: re-apply the patches that changed
|
||||
# (prepare.py reverts the earlier version it finds applied), rebuild incrementally, and reinstall the base
|
||||
# runtime and the per-user overrides. Run it with no Riot/League session open; it never stops one.
|
||||
set -eu
|
||||
repo=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)
|
||||
cd "$repo"
|
||||
if [ ! -d build/darling-src/build ]; then
|
||||
echo 'No existing build; follow the first-time setup in README.md instead.' >&2
|
||||
exit 1
|
||||
fi
|
||||
# The install steps shut Darling down and stop leftover Riot processes, so refuse rather than end a session.
|
||||
python3 - <<'PY'
|
||||
from pathlib import Path
|
||||
for entry in Path('/proc').iterdir():
|
||||
if not entry.name.isdigit():
|
||||
continue
|
||||
try:
|
||||
command_line = (entry / 'cmdline').read_bytes()
|
||||
except OSError:
|
||||
continue
|
||||
if b'/Riot Client.app/' in command_line or b'/League of Legends.app/' in command_line:
|
||||
raise SystemExit('A Riot Client or League process is running; exit the game and both clients, then run this again.')
|
||||
PY
|
||||
./scripts/build.sh
|
||||
python3 build/runtime/tools/stop-darling-runtime.py
|
||||
sudo cmake --install build/darling-src/build
|
||||
./scripts/install-runtime.sh
|
||||
echo 'Update installed. Start Darling with: sh scripts/run.sh'
|
||||
Reference in new issue
Block a user