Match hunk edit format and upload build artifacts

This commit is contained in:
Joe Tretter
2026-05-19 12:10:44 -05:00
parent bea901acfe
commit b48244d4c2
6 changed files with 58 additions and 11 deletions

1
.gitignore vendored
View File

@@ -10,6 +10,7 @@ jdk/
.setup-build-environment.state .setup-build-environment.state
.android-project-tooling.state .android-project-tooling.state
commit-summary.txt commit-summary.txt
upload2DL.sh
keystore.properties keystore.properties
*.keystore *.keystore
*.jks *.jks

View File

@@ -11,6 +11,7 @@ GRADLE_USER_HOME_DIR="$PROJECT_DIR/.gradle-user-home"
STATE_FILE="$PROJECT_DIR/.android-project-tooling.state" STATE_FILE="$PROJECT_DIR/.android-project-tooling.state"
LEGACY_STATE_FILE="$PROJECT_DIR/.setup-build-environment.state" LEGACY_STATE_FILE="$PROJECT_DIR/.setup-build-environment.state"
COMMIT_SUMMARY_FILE="$PROJECT_DIR/commit-summary.txt" COMMIT_SUMMARY_FILE="$PROJECT_DIR/commit-summary.txt"
UPLOAD_SCRIPT="$PROJECT_DIR/upload2DL.sh"
CMDLINE_TOOLS_DIR="$SDK_DIR/cmdline-tools" CMDLINE_TOOLS_DIR="$SDK_DIR/cmdline-tools"
CMDLINE_TOOLS_LATEST_DIR="$CMDLINE_TOOLS_DIR/latest" CMDLINE_TOOLS_LATEST_DIR="$CMDLINE_TOOLS_DIR/latest"
WRAPPER_JAR_PATH="$PROJECT_DIR/gradle/wrapper/gradle-wrapper.jar" WRAPPER_JAR_PATH="$PROJECT_DIR/gradle/wrapper/gradle-wrapper.jar"
@@ -103,6 +104,7 @@ auto_commit_if_needed() {
git -C "$PROJECT_DIR" reset -q HEAD -- \ git -C "$PROJECT_DIR" reset -q HEAD -- \
keystore.properties \ keystore.properties \
commit-summary.txt \ commit-summary.txt \
upload2DL.sh \
'*.keystore' \ '*.keystore' \
'*.jks' 2>/dev/null || true '*.jks' 2>/dev/null || true
@@ -268,6 +270,23 @@ print(match.group(1))
PY PY
} }
upload_build_artifact_if_possible() {
local artifact_path="$1"
if [ ! -f "$artifact_path" ]; then
echo "Upload artifact not found: $artifact_path" >&2
exit 1
fi
if [ ! -f "$UPLOAD_SCRIPT" ]; then
log "No upload2DL.sh found; skipping artifact upload"
return
fi
log "Uploading $(basename "$artifact_path") with upload2DL.sh"
bash "$UPLOAD_SCRIPT" "$artifact_path"
}
setup_env() { setup_env() {
setup_java_env setup_java_env
export ANDROID_HOME="$SDK_DIR" export ANDROID_HOME="$SDK_DIR"
@@ -563,6 +582,7 @@ maybe_run_operation() {
if [ -n "$artifact_source" ] && [ -f "$artifact_source" ]; then if [ -n "$artifact_source" ] && [ -f "$artifact_source" ]; then
log "Renaming $(basename "$artifact_source") to $(basename "$artifact_target")" log "Renaming $(basename "$artifact_source") to $(basename "$artifact_target")"
mv -f "$artifact_source" "$artifact_target" mv -f "$artifact_source" "$artifact_target"
upload_build_artifact_if_possible "$artifact_target"
elif [ -n "$artifact_source" ]; then elif [ -n "$artifact_source" ]; then
log "Expected build output not found for rename: ${artifact_source#$PROJECT_DIR/}" log "Expected build output not found for rename: ${artifact_source#$PROJECT_DIR/}"
fi fi

View File

@@ -83,6 +83,7 @@ When `--build` or `--build-release-aab` is used, the script also:
- increments the patch component of `versionName`, for example `0.1.0` to `0.1.1` - increments the patch component of `versionName`, for example `0.1.0` to `0.1.1`
- bundles full Git manpage source files from Git's `Documentation/` directory into app assets - bundles full Git manpage source files from Git's `Documentation/` directory into app assets
- renames the generated artifact to a `githug-android-*` filename that includes the post-bump `versionCode` - renames the generated artifact to a `githug-android-*` filename that includes the post-bump `versionCode`
- uploads the renamed APK/AAB with local `./upload2DL.sh` when that script exists
- attempts to create a git commit after a successful build if there are source changes - attempts to create a git commit after a successful build if there are source changes
The build commands currently run these Gradle tasks: The build commands currently run these Gradle tasks:

View File

@@ -19,8 +19,8 @@ android {
applicationId = "solutions.tretter.githugandroid" applicationId = "solutions.tretter.githugandroid"
minSdk = 26 minSdk = 26
targetSdk = 35 targetSdk = 35
versionCode = 158 versionCode = 159
versionName = "0.1.157" versionName = "0.1.158"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true vectorDrawables.useSupportLibrary = true

View File

@@ -51,9 +51,7 @@ internal object InteractiveAddEngine {
command = command, command = command,
kind = GitEditorCommandKind.PATCH_HUNK, kind = GitEditorCommandKind.PATCH_HUNK,
title = "Edit Patch Hunk", title = "Edit Patch Hunk",
initialContent = patchHunkLines(file) initialContent = editablePatchHunkContent(file),
.dropLastWhile { it == PatchHunkPrompt }
.joinToString("\n"),
) )
} }
@@ -208,21 +206,44 @@ internal object InteractiveAddEngine {
} }
private fun patchHunkLines(file: GitFile): List<String> { private fun patchHunkLines(file: GitFile): List<String> {
return patchDiffHeaderLines(file) + patchHunkBodyLines(file) + PatchHunkPrompt
}
private fun editablePatchHunkContent(file: GitFile): String {
return buildList {
add("# Manual hunk edit mode -- see bottom for a quick guide.")
addAll(patchHunkBodyLines(file))
add("# ---")
add("# To remove '-' lines, make them ' ' lines (context).")
add("# To remove '+' lines, delete them.")
add("# Lines starting with # will be removed.")
add("# If the patch applies cleanly, the edited hunk will immediately be marked for staging.")
add("# If it does not apply cleanly, you will be given an opportunity to")
add("# edit again. If all lines of the hunk are removed, then the edit is")
add("# aborted and the hunk is left unchanged.")
}.joinToString("\n")
}
private fun patchDiffHeaderLines(file: GitFile): List<String> {
return listOf(
"diff --git a/${file.name} b/${file.name}",
"index 0000000..0000001 100644",
"--- a/${file.name}",
"+++ b/${file.name}",
)
}
private fun patchHunkBodyLines(file: GitFile): List<String> {
val lines = file.content.lines() val lines = file.content.lines()
val nonEmptyLines = lines.dropLastWhile { it.isEmpty() } val nonEmptyLines = lines.dropLastWhile { it.isEmpty() }
val addedCount = nonEmptyLines.size.coerceAtLeast(1) val addedCount = nonEmptyLines.size.coerceAtLeast(1)
return buildList { return buildList {
add("diff --git a/${file.name} b/${file.name}")
add("index 0000000..0000001 100644")
add("--- a/${file.name}")
add("+++ b/${file.name}")
add("@@ -1 +1,$addedCount @@") add("@@ -1 +1,$addedCount @@")
if (nonEmptyLines.isEmpty()) { if (nonEmptyLines.isEmpty()) {
add("+") add("+")
} else { } else {
nonEmptyLines.forEach { line -> add("+$line") } nonEmptyLines.forEach { line -> add("+$line") }
} }
add(PatchHunkPrompt)
} }
} }

View File

@@ -156,7 +156,11 @@ class InteractiveAddEngineTest {
assertEquals(GitEditorCommandKind.PATCH_HUNK, invocation?.kind) assertEquals(GitEditorCommandKind.PATCH_HUNK, invocation?.kind)
assertEquals("Edit Patch Hunk", invocation?.title) assertEquals("Edit Patch Hunk", invocation?.title)
assertTrue(invocation?.initialContent.orEmpty().contains("diff --git a/README b/README")) assertTrue(invocation?.initialContent.orEmpty().startsWith("# Manual hunk edit mode -- see bottom for a quick guide."))
assertFalse(invocation?.initialContent.orEmpty().contains("diff --git a/README b/README"))
assertFalse(invocation?.initialContent.orEmpty().contains("--- a/README"))
assertTrue(invocation?.initialContent.orEmpty().contains("# ---"))
assertTrue(invocation?.initialContent.orEmpty().contains("# To remove '+' lines, delete them."))
assertTrue(invocation?.initialContent.orEmpty().contains("+A")) assertTrue(invocation?.initialContent.orEmpty().contains("+A"))
assertFalse(invocation?.initialContent.orEmpty().contains("Stage this hunk")) assertFalse(invocation?.initialContent.orEmpty().contains("Stage this hunk"))
} }