This commit is contained in:
InkerBot
2026-03-05 13:33:05 +08:00
commit 648aa93360
22 changed files with 1427 additions and 0 deletions
Executable
+68
View File
@@ -0,0 +1,68 @@
#!/bin/sh
set -e
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
ROOT="$(dirname "$SCRIPT_DIR")"
SING_BOX="$ROOT/works/sing-box"
PATCH_DIR="$ROOT/works/patch"
OUTPUT="$ROOT/works/core"
if [ ! -d "$SING_BOX/.git" ]; then
echo "Error: works/sing-box not found. Run update first." >&2
exit 1
fi
echo "Initializing works/core/..."
rm -rf "$OUTPUT"
mkdir -p "$OUTPUT"
git init "$OUTPUT"
echo "Syncing sing-box files to works/core/..."
rsync -a --exclude='.git/' "$SING_BOX/" "$OUTPUT/"
VERSION="$(git -C "$SING_BOX" describe --tags --always 2>/dev/null || git -C "$SING_BOX" rev-parse --short HEAD)"
git -C "$OUTPUT" add -A
git -C "$OUTPUT" commit -m "upstream: $VERSION"
echo "Applying patches..."
applied=0
failed=0
failed_list=""
if [ -d "$PATCH_DIR" ]; then
patch_list="$(mktemp)"
trap 'rm -f "$patch_list"' EXIT
find "$PATCH_DIR" -name "*.patch" | sort > "$patch_list"
while IFS= read -r patch_file; do
rel="${patch_file#$PATCH_DIR/}"
rel="${rel%.patch}"
dst="$OUTPUT/$rel"
mkdir -p "$(dirname "$dst")"
if patch --merge --no-backup-if-mismatch --force "$dst" < "$patch_file"; then
applied=$((applied + 1))
else
echo " FAILED: $rel" >&2
failed=$((failed + 1))
failed_list="${failed_list} ${rel}
"
fi
done < "$patch_list"
fi
git -C "$OUTPUT" add -A
git -C "$OUTPUT" commit -m "patches applied" --allow-empty
total=$((applied + failed))
echo ""
echo "Result: $applied/$total patches applied."
if [ "$failed" -gt 0 ]; then
echo ""
echo "Failed patches (merge conflicts written to files):"
printf "%s" "$failed_list"
echo ""
echo "Resolve conflicts in works/core/, then run 'bin/generate' to update patches."
exit 1
fi
echo "Done."
+74
View File
@@ -0,0 +1,74 @@
$ErrorActionPreference = 'Stop'
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
$Root = Split-Path -Parent $ScriptDir
$SingBox = Join-Path $Root 'works/sing-box'
$PatchDir = Join-Path $Root 'works/patch'
$Output = Join-Path $Root 'works/core'
if (-not (Test-Path (Join-Path $SingBox '.git'))) {
Write-Error 'works/sing-box not found. Run update first.'
exit 1
}
Write-Host 'Initializing works/core/...'
if (Test-Path $Output) { Remove-Item -Recurse -Force $Output }
New-Item -ItemType Directory -Path $Output -Force | Out-Null
git init $Output
Write-Host 'Syncing sing-box files to works/core/...'
Get-ChildItem -Path $SingBox -Recurse -File | Where-Object {
$_.FullName -notmatch [regex]::Escape((Join-Path $SingBox '.git'))
} | ForEach-Object {
$rel = $_.FullName.Substring($SingBox.Length + 1)
$dst = Join-Path $Output $rel
$dstDir = Split-Path -Parent $dst
if (-not (Test-Path $dstDir)) { New-Item -ItemType Directory -Path $dstDir -Force | Out-Null }
Copy-Item -Path $_.FullName -Destination $dst -Force
}
$version = git -C $SingBox describe --tags --always 2>$null
if (-not $version) { $version = git -C $SingBox rev-parse --short HEAD }
git -C $Output add -A
git -C $Output commit -m "upstream: $version"
Write-Host 'Applying patches...'
$applied = 0
$failed = 0
$failedList = @()
if (Test-Path $PatchDir) {
Get-ChildItem -Path $PatchDir -Recurse -Filter '*.patch' | Sort-Object FullName | ForEach-Object {
$rel = $_.FullName.Substring($PatchDir.Length + 1) -replace '\.patch$', ''
$dst = Join-Path $Output $rel
$dstDir = Split-Path -Parent $dst
if (-not (Test-Path $dstDir)) { New-Item -ItemType Directory -Path $dstDir -Force | Out-Null }
& patch --merge --no-backup-if-mismatch --force -i $_.FullName $dst 2>&1
if ($LASTEXITCODE -eq 0) {
$applied++
} else {
Write-Host " FAILED: $rel" -ForegroundColor Red
$failed++
$failedList += $rel
}
}
}
git -C $Output add -A
git -C $Output commit -m 'patches applied' --allow-empty
$total = $applied + $failed
Write-Host ""
Write-Host "Result: $applied/$total patches applied."
if ($failed -gt 0) {
Write-Host ""
Write-Host "Failed patches (merge conflicts written to files):" -ForegroundColor Red
foreach ($f in $failedList) {
Write-Host " $f" -ForegroundColor Red
}
Write-Host ""
Write-Host "Resolve conflicts in works/core/, then run 'bin/generate' to update patches."
exit 1
}
Write-Host 'Done.'
Executable
+80
View File
@@ -0,0 +1,80 @@
#!/bin/sh
set -e
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
ROOT="$(dirname "$SCRIPT_DIR")"
SING_BOX="$ROOT/works/sing-box"
PATCH_DIR="$ROOT/works/patch"
CORE="$ROOT/works/core"
if [ ! -d "$SING_BOX/.git" ]; then
echo "Error: works/sing-box not found. Run update first." >&2
exit 1
fi
if [ ! -d "$CORE" ]; then
echo "Error: works/core not found. Run generate first." >&2
exit 1
fi
IGNORE_FILE="$ROOT/works/ignore"
is_ignored() {
[ -f "$IGNORE_FILE" ] || return 1
_rel="$1"
_name="${_rel##*/}"
while IFS= read -r _pattern || [ -n "$_pattern" ]; do
case "$_pattern" in
''|\#*) continue ;;
esac
case "$_pattern" in
*/*)
case "$_rel" in $_pattern) return 0 ;; esac
;;
*)
case "$_name" in $_pattern) return 0 ;; esac
;;
esac
done < "$IGNORE_FILE"
return 1
}
echo "Clearing existing patches..."
rm -rf "$PATCH_DIR"
mkdir -p "$PATCH_DIR"
echo "Generating patches for modified/new files..."
find "$CORE" -not -path "$CORE/.git/*" -type f | sort | while read -r dst_file; do
rel="${dst_file#$CORE/}"
if is_ignored "$rel"; then continue; fi
src_file="$SING_BOX/$rel"
patch_file="$PATCH_DIR/$rel.patch"
if [ -f "$src_file" ]; then
if ! diff -q "$src_file" "$dst_file" > /dev/null 2>&1; then
mkdir -p "$(dirname "$patch_file")"
diff -u "$src_file" "$dst_file" > "$patch_file" || true
echo " Modified: $rel"
fi
else
mkdir -p "$(dirname "$patch_file")"
diff -u /dev/null "$dst_file" > "$patch_file" || true
echo " New: $rel"
fi
done
echo "Generating patches for deleted files..."
find "$SING_BOX" -not -path "$SING_BOX/.git/*" -type f | sort | while read -r src_file; do
rel="${src_file#$SING_BOX/}"
if is_ignored "$rel"; then continue; fi
dst_file="$CORE/$rel"
patch_file="$PATCH_DIR/$rel.patch"
if [ ! -f "$dst_file" ]; then
mkdir -p "$(dirname "$patch_file")"
diff -u "$src_file" /dev/null > "$patch_file" || true
echo " Deleted: $rel"
fi
done
echo "Done."
+82
View File
@@ -0,0 +1,82 @@
$ErrorActionPreference = 'Stop'
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
$Root = Split-Path -Parent $ScriptDir
$SingBox = Join-Path $Root 'works/sing-box'
$PatchDir = Join-Path $Root 'works/patch'
$Core = Join-Path $Root 'works/core'
if (-not (Test-Path (Join-Path $SingBox '.git'))) {
Write-Error 'works/sing-box not found. Run update first.'
exit 1
}
if (-not (Test-Path $Core)) {
Write-Error 'works/core not found. Run generate first.'
exit 1
}
$IgnoreFile = Join-Path $Root 'works/ignore'
$IgnorePatterns = @()
if (Test-Path $IgnoreFile) {
$IgnorePatterns = Get-Content $IgnoreFile | Where-Object { $_ -ne '' -and $_ -notmatch '^\s*#' }
}
function Test-Ignored {
param([string]$RelPath)
foreach ($pattern in $IgnorePatterns) {
if ($pattern -match '/') {
if ($RelPath -like $pattern) { return $true }
} else {
if ((Split-Path -Leaf $RelPath) -like $pattern) { return $true }
}
}
return $false
}
Write-Host 'Clearing existing patches...'
if (Test-Path $PatchDir) { Remove-Item -Recurse -Force $PatchDir }
New-Item -ItemType Directory -Path $PatchDir -Force | Out-Null
Write-Host 'Generating patches for modified/new files...'
Get-ChildItem -Path $Core -Recurse -File | Where-Object {
$_.FullName -notmatch [regex]::Escape((Join-Path $Core '.git'))
} | Sort-Object FullName | ForEach-Object {
$rel = $_.FullName.Substring($Core.Length + 1) -replace '\\', '/'
if (Test-Ignored $rel) { return }
$srcFile = Join-Path $SingBox $rel
$patchFile = Join-Path $PatchDir "$rel.patch"
$patchFileDir = Split-Path -Parent $patchFile
if (-not (Test-Path $patchFileDir)) { New-Item -ItemType Directory -Path $patchFileDir -Force | Out-Null }
if (Test-Path $srcFile) {
$srcHash = (Get-FileHash $srcFile -Algorithm MD5).Hash
$dstHash = (Get-FileHash $_.FullName -Algorithm MD5).Hash
if ($srcHash -ne $dstHash) {
diff -u $srcFile $_.FullName | Out-File -FilePath $patchFile -Encoding utf8
Write-Host " Modified: $rel"
}
} else {
diff -u /dev/null $_.FullName | Out-File -FilePath $patchFile -Encoding utf8
Write-Host " New: $rel"
}
}
Write-Host 'Generating patches for deleted files...'
Get-ChildItem -Path $SingBox -Recurse -File | Where-Object {
$_.FullName -notmatch [regex]::Escape((Join-Path $SingBox '.git'))
} | Sort-Object FullName | ForEach-Object {
$rel = $_.FullName.Substring($SingBox.Length + 1) -replace '\\', '/'
if (Test-Ignored $rel) { return }
$dstFile = Join-Path $Core $rel
$patchFile = Join-Path $PatchDir "$rel.patch"
if (-not (Test-Path $dstFile)) {
$patchFileDir = Split-Path -Parent $patchFile
if (-not (Test-Path $patchFileDir)) { New-Item -ItemType Directory -Path $patchFileDir -Force | Out-Null }
diff -u $_.FullName /dev/null | Out-File -FilePath $patchFile -Encoding utf8
Write-Host " Deleted: $rel"
}
}
Write-Host 'Done.'
Executable
+33
View File
@@ -0,0 +1,33 @@
#!/bin/sh
set -e
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
ROOT="$(dirname "$SCRIPT_DIR")"
SING_BOX="$ROOT/works/sing-box"
# defaults
REPO_URL="git@git.inker.bot:arknights/sing-box.git"
UPSTREAM_BRANCH="main"
CONFIG="$ROOT/works/config"
if [ -f "$CONFIG" ]; then
. "$CONFIG"
fi
if [ -d "$SING_BOX/.git" ]; then
echo "Updating sing-box..."
git -C "$SING_BOX" fetch --all
if [ -n "$UPSTREAM_BRANCH" ]; then
git -C "$SING_BOX" checkout "$UPSTREAM_BRANCH"
fi
git -C "$SING_BOX" pull
else
echo "Cloning sing-box..."
if [ -n "$UPSTREAM_BRANCH" ]; then
git clone -b "$UPSTREAM_BRANCH" "$REPO_URL" "$SING_BOX"
else
git clone "$REPO_URL" "$SING_BOX"
fi
fi
echo "Done. Version: $(git -C "$SING_BOX" describe --tags --always 2>/dev/null || git -C "$SING_BOX" rev-parse --short HEAD)"
+39
View File
@@ -0,0 +1,39 @@
$ErrorActionPreference = 'Stop'
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
$Root = Split-Path -Parent $ScriptDir
$SingBox = Join-Path $Root 'works/sing-box'
# defaults
$RepoUrl = 'git@git.inker.bot:arknights/sing-box.git'
$UpstreamBranch = 'main'
$ConfigFile = Join-Path $Root 'works/config'
if (Test-Path $ConfigFile) {
Get-Content $ConfigFile | ForEach-Object {
if ($_ -match '^([^#=]+)=(.*)$') {
$key = $Matches[1].Trim()
$val = $Matches[2].Trim()
if ($key -eq 'REPO_URL') { $RepoUrl = $val }
elseif ($key -eq 'UPSTREAM_BRANCH') { $UpstreamBranch = $val }
}
}
}
if (Test-Path (Join-Path $SingBox '.git')) {
Write-Host 'Updating sing-box...'
git -C $SingBox fetch --all
if ($UpstreamBranch) { git -C $SingBox checkout $UpstreamBranch }
git -C $SingBox pull
} else {
Write-Host 'Cloning sing-box...'
if ($UpstreamBranch) {
git clone -b $UpstreamBranch $RepoUrl $SingBox
} else {
git clone $RepoUrl $SingBox
}
}
$version = git -C $SingBox describe --tags --always 2>$null
if (-not $version) { $version = git -C $SingBox rev-parse --short HEAD }
Write-Host "Done. Version: $version"