1 | #!/bin/bash |
---|
2 | # |
---|
3 | # Copyright (C) 2009-2011 Roy Liu |
---|
4 | # All rights reserved. |
---|
5 | # |
---|
6 | # Redistribution and use in source and binary forms, with or without |
---|
7 | # modification, are permitted provided that the following conditions are met: |
---|
8 | # |
---|
9 | # * Redistributions of source code must retain the above copyright notice, |
---|
10 | # this list of conditions and the following disclaimer. |
---|
11 | # * Redistributions in binary form must reproduce the above copyright notice, |
---|
12 | # this list of conditions and the following disclaimer in the documentation |
---|
13 | # and/or other materials provided with the distribution. |
---|
14 | # * Neither the name of the author nor the names of any contributors may be |
---|
15 | # used to endorse or promote products derived from this software without |
---|
16 | # specific prior written permission. |
---|
17 | # |
---|
18 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
---|
19 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
---|
20 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
---|
21 | # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE |
---|
22 | # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
---|
23 | # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
---|
24 | # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
---|
25 | # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
---|
26 | # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
---|
27 | # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
---|
28 | # POSSIBILITY OF SUCH DAMAGE. |
---|
29 | |
---|
30 | if [[ ! -d "$1" ]] || [[ ! -d "$2" ]]; then |
---|
31 | |
---|
32 | echo "Please specify two directories." >&2 |
---|
33 | exit 1 |
---|
34 | fi |
---|
35 | |
---|
36 | WORK_DIR="patch" |
---|
37 | |
---|
38 | if [[ -d "$WORK_DIR" ]]; then |
---|
39 | |
---|
40 | echo "Directory '$WORK_DIR' already exists. Exiting ..." |
---|
41 | exit 1 |
---|
42 | fi |
---|
43 | |
---|
44 | SRC_DIR=$1 |
---|
45 | DST_DIR=$2 |
---|
46 | |
---|
47 | FILES_PATCH=() |
---|
48 | FILES_ADD=() |
---|
49 | |
---|
50 | rm -f patch.tgz |
---|
51 | |
---|
52 | mkdir -p "$WORK_DIR/files-patch" |
---|
53 | mkdir -p "$WORK_DIR/files-add" |
---|
54 | |
---|
55 | while read RSYNC_CHANGE; do |
---|
56 | |
---|
57 | case "${RSYNC_CHANGE:0:1}" in |
---|
58 | |
---|
59 | ">") |
---|
60 | # Consider a file as patched if it's being transferred and changed. |
---|
61 | if [[ "${RSYNC_CHANGE:3:1}" == "s" ]]; then |
---|
62 | FILES_PATCH=("${FILES_PATCH[@]}" "${RSYNC_CHANGE:13}") |
---|
63 | fi |
---|
64 | ;; |
---|
65 | |
---|
66 | "*") |
---|
67 | # Consider a file as added if it's being deleted by the receiver and not a directory. |
---|
68 | if [[ "${RSYNC_CHANGE:1:8}" == "deleting" ]] && [[ ! -d "$DST_DIR/${RSYNC_CHANGE:12}" ]]; then |
---|
69 | FILES_ADD=("${FILES_ADD[@]}" "${RSYNC_CHANGE:12}") |
---|
70 | fi |
---|
71 | ;; |
---|
72 | |
---|
73 | *) |
---|
74 | ;; |
---|
75 | esac |
---|
76 | |
---|
77 | done < <(rsync -r -i -n --delete --exclude=.DS_Store --exclude=.svn --exclude=/.git "$SRC_DIR"/ "$DST_DIR") |
---|
78 | |
---|
79 | # |
---|
80 | |
---|
81 | TMP_DIR=$(mktemp -d /tmp/gen_macports_patches.XXXXXX) |
---|
82 | |
---|
83 | for FILE in "${FILES_PATCH[@]}"; do |
---|
84 | |
---|
85 | mkdir -p "$(dirname -- "$TMP_DIR/$FILE")" |
---|
86 | |
---|
87 | cp "$SRC_DIR/$FILE" "$TMP_DIR/$FILE.orig" |
---|
88 | cp "$DST_DIR/$FILE" "$TMP_DIR/$FILE" |
---|
89 | |
---|
90 | (cd "$TMP_DIR" && diff -u "$FILE.orig" "$FILE") >> "$WORK_DIR/files-patch/patch-$(basename -- "$FILE").diff" |
---|
91 | done |
---|
92 | |
---|
93 | rm -rf "$TMP_DIR" |
---|
94 | |
---|
95 | # |
---|
96 | |
---|
97 | for FILE in "${FILES_ADD[@]}"; do |
---|
98 | |
---|
99 | FILE_ADD_DIR=$(dirname -- "$WORK_DIR/files-add/$FILE") |
---|
100 | mkdir -p "$FILE_ADD_DIR" |
---|
101 | |
---|
102 | cp "$DST_DIR/$FILE" "$FILE_ADD_DIR" |
---|
103 | done |
---|
104 | |
---|
105 | # Create the patch archive. |
---|
106 | |
---|
107 | cat <<EOF > "$WORK_DIR/README" |
---|
108 | This is an autogenerated MacPorts patch archive. In the 'files-patch' |
---|
109 | directory, you will find the directory hierarchy of files that require |
---|
110 | patching. Analogously, the 'files-add' directory contains files not found in |
---|
111 | the original package that may have to be added. |
---|
112 | EOF |
---|
113 | |
---|
114 | tar -C "$WORK_DIR/.." -c -z -f patch.tgz "$(basename -- "$WORK_DIR")" |
---|
115 | |
---|
116 | rm -rf "$WORK_DIR" |
---|