Browse Source

Merge pull request #1987 from infosiftr/diff-pr

Add hacky "diff-pr.sh" script for generating diffs of PRs
yosifkit 9 years ago
parent
commit
facd0a7162
1 changed files with 159 additions and 0 deletions
  1. 159 0
      diff-pr.sh

+ 159 - 0
diff-pr.sh

@@ -0,0 +1,159 @@
+#!/bin/bash
+set -eo pipefail
+
+# make sure we can GTFO
+trap 'echo >&2 Ctrl+C captured, exiting; exit 1' SIGINT
+
+usage() {
+	cat <<-EOUSAGE
+		usage: $0 [PR number] [repo[:tag]]
+		   ie: $0 1024
+		       $0 9001 debian php django
+	EOUSAGE
+}
+
+# TODO flags parsing
+allFiles=
+listTarballContents=1
+findCopies='20%'
+
+if [ "$#" -eq 0 ]; then
+	usage >&2
+	exit 1
+fi
+pull="$1" # PR number
+shift
+
+#dir="$(dirname "$(readlink -f "$BASH_SOURCE")")"
+
+tempDir="$(mktemp -d)"
+trap "rm -rf '$tempDir'" EXIT
+cd "$tempDir"
+
+git clone --quiet --depth 1 \
+	https://github.com/docker-library/official-images.git \
+	oi
+
+git -C oi fetch --quiet --depth 1 \
+	origin "pull/$pull/merge":pull
+
+images=( "$@" )
+if [ "${#images[@]}" -eq 0 ]; then
+	images=( $(git -C oi/library diff --name-only master...pull -- . | xargs -n1 basename) )
+fi
+
+export BASHBREW_CACHE="${BASHBREW_CACHE:-${XDG_CACHE_HOME:-$HOME/.cache}/bashbrew}"
+export BASHBREW_LIBRARY="$PWD/oi/library"
+
+# TODO something less hacky than "git archive" hackery, like a "bashbrew archive" or "bashbrew context" or something
+template='
+{{- range $.Entries -}}
+	{{- $from := $.DockerFrom . -}}
+	git -C "$BASHBREW_CACHE/git" archive --format=tar
+	{{- " " -}}
+	{{- "--prefix=" -}}
+	{{- $.RepoName -}}
+	_
+	{{- .Tags | last -}}
+	{{- "/" -}}
+	{{- " " -}}
+	{{- .GitCommit -}}
+	{{- ":" -}}
+	{{- (eq .Directory ".") | ternary "" .Directory -}}
+	{{- "\n" -}}
+{{- end -}}
+'
+
+copy-tar() {
+	local src="$1"; shift
+	local dst="$1"; shift
+
+	if [ "$allFiles" ]; then
+		mkdir -p "$dst"
+		cp -al "$src"/*/ "$dst/"
+		return
+	fi
+
+	# "Dockerfile*" at the end here ensures we capture "Dockerfile.builder" style repos in a useful way too (busybox, hello-world)
+	for d in "$src"/*/Dockerfile*; do
+		dDir="$(dirname "$d")"
+		dDirName="$(basename "$dDir")"
+
+		IFS=$'\n'
+		files=(
+			"$(basename "$d")"
+			$(awk '
+				toupper($1) == "COPY" || toupper($1) == "ADD" {
+					for (i = 2; i < NF; i++) {
+						print $i
+					}
+				}
+			' "$d")
+
+			# some extra files which are likely interesting if they exist, but no big loss if they do not
+			' *.manifest' # debian/ubuntu "package versions" list
+			' *.ks' # fedora "kickstart" (rootfs build script)
+			' build*.txt' # ubuntu "build-info.txt", debian "build-command.txt"
+
+			# usefulness yet to be proven:
+			#' *.log'
+			#' {MD5,SHA1,SHA256}SUMS'
+			#' *.{md5,sha1,sha256}'
+
+			# (the space prefix is removed below and is used to ignore non-matching globs so that bad "Dockerfile" entries appropriately lead to failure)
+		)
+		unset IFS
+
+		mkdir -p "$dst/$dDirName"
+
+		for origF in "${files[@]}"; do
+			f="${origF# }" # trim off leading space (indicates we don't care about failure)
+			[ "$f" = "$origF" ] && failureMatters=1 || failureMatters=
+
+			globbed=( $(cd "$dDir" && eval "echo $f") )
+
+			for g in "${globbed[@]}"; do
+				if [ -z "$failureMatters" ] && [ ! -e "$dDir/$g" ]; then
+					continue
+				fi
+
+				mkdir -p "$(dirname "$dst/$dDirName/$g")"
+				cp -alT "$dDir/$g" "$dst/$dDirName/$g"
+
+				if [ "$listTarballContents" ]; then
+					case "$g" in
+						*.tar.*|*.tgz)
+							tar -tf "$dst/$dDirName/$g" | sort > "$dst/$dDirName/$g  'tar -t'"
+							;;
+					esac
+				fi
+			done
+		done
+	done
+}
+
+mkdir temp
+git -C temp init --quiet
+
+for image in "${images[@]}"; do
+	if script="$(bashbrew cat -f "$template" "$image")"; then
+		mkdir tar
+		( eval "$script" | tar -xiC tar )
+		copy-tar tar temp
+		rm -rf tar
+	fi
+done
+git -C temp add . || :
+git -C temp commit --quiet --allow-empty -m 'initial' || :
+
+git -C oi checkout --quiet pull
+
+git -C temp rm --quiet -rf . || :
+script="$(bashbrew cat -f "$template" "${images[@]}")"
+mkdir tar
+( eval "$script" | tar -xiC tar )
+copy-tar tar temp
+rm -rf tar
+git -C temp add .
+
+git -C temp diff --minimal --find-copies="$findCopies" --find-copies-harder --irreversible-delete --staged