Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#!/usr/bin/env bash
# A little helper for copying built tests into an implementation's repo, for
# testing changes.
#
# The destination directory is specified with `-d`, `--dest` or `--destination`.
# Source files can be positional (in which case, they are ignored if not found
# to be relative to the test directory), or specified via utilities such as
# `--head` (tests changed in the current working directory), or `--since N`
# (tests changed in the last N commits).
script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
root_dir="$( dirname "$script_dir" )"
tests_dir="$root_dir/test"
help_msg="$(cat <<-END
Help:
-d <argument> | -d=<argument>
--dest <argument> | --dest=<argument>
--destination <argument> | --destination=<argument>
Specify a destination directory to receive copied tests. If not present,
the script runs in dry-run mode and does not copy files.
-n
--dryrun
--dry-run
Don't copy files, but print the operations which would be performed.
Useful for debugging.
--head
Copy test files which have changed in the working directory since the
last commit. Performs \`git diff HEAD --name-only\`.
-s <argument> | -s=<argument>
--diff <argument> | --diff=<argument>
--since <argument> | --since=<argument>
Copy files which have changed in the past N commits. Also includes
changes in the current working directory since the last commit. Performs
\`git diff HEAD~\<argument> --name-only\`.
-h
--help
Print this help message.
END
)"
check_path() {
local file="$1"
if ( [ ! -f "$file" ] ); then
return
fi
local path=$(echo "$( realpath --relative-to="$root_dir/test" "$file" )" | tr "/" " ")
for part in $path; do
if [ "$part" = ".." ]; then
return
fi
done
echo "$file"
}
files=( )
dry_run=0
while [[ $# -gt 0 ]]; do
case "$1" in
-d|--dest|--destination)
# Select the destination to copy into (value is following
# positional parameter)
destination="$2"
shift
shift
;;
-d=*|--dest=*|--destination=*)
# Select the destination to copy into (value follows `=` sign)
destination="${i#*=}"
shift
;;
-n|--dryrun|--dry-run)
# Don't actually copy files, but instead list the files to copy
dry_run=1
shift
;;
--head)
# Add test files changed since the last commit
files+=( "$( git diff HEAD --name-only --diff-filter=d | grep "^test/" )" )
shift
;;
-s|--diff|--since)
# Add test files changed in the last N commits (N is following
# positional parameter)
files+=( "$( git diff HEAD~$2 --name-only --diff-filter=d | grep "^test/" )" )
shift
shift
;;
-s=*|--diff=*|--since=*)
# Add test files changed in the last N commits (N follows `=` sign)
files+=( "$( git diff HEAD~${i#*=} --name-only --diff-filter=d | grep "^test/" )" )
shift
;;
-h|--help)
echo -n "$help_msg"
exit 0
;;
*)
# Add a specific test, if it's a file relative to $tests_dir
if [ -n "$( check_path "$1" )" ]; then
files+=( "$1" )
fi
shift
;;
esac
done
if [ ${#destination} -eq 0 ]; then
echo -n "Error: No destination specified."
echo -n "$help_msg"
exit 1
fi
function main {
for file in $files; do
# Convert absolute path to relative path
file="$( realpath --relative-to="$root_dir" "$file" )"
target_path="$destination/$( dirname "$file" )"
cmd=$( cat <<-END
mkdir -p "$target_path"
cp -f "$file" "$target_path"
END
)
if [ $dry_run -eq 0 ]; then
eval "$cmd"
else
echo "$cmd"
echo ""
fi
done
}
old_dir=$( pwd )
cd "$root_dir"
main
cd "$old_dir"