-
Notifications
You must be signed in to change notification settings - Fork 4
/
xr.sh
161 lines (146 loc) · 5.78 KB
/
xr.sh
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
153
154
155
156
157
158
159
160
161
# Main plugin file.
# Constants.
_exo_config=".exercism/metadata.json"
# Finding the location of the sourced script is shell-specific
# Currently, zsh and bash are the only supported shells
if [ -n "$ZSH_VERSION" ]; then
_dir="$(dirname "$(readlink -f "$0")")"
elif [ -n "$BASH_VERSION" ]; then
_dir="$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")"
else
echo "This is an unsupported shell." >&2
return 1
fi
read -r -d '' _short_doc << EOF
Usage: xr [<command>] [<uuid>]
h, help Display a more complete help message.
c, clean Remove all the downloaded student submissions.
n, notes Print the mentoring notes for the current or given exercise.
e, edit Open the mentoring notes in an editor.
t, test Run the tests.
b, bench Copy the custom benchmarks into the local project and run them.
EOF
read -r -d '' _long_doc << EOF
Usage: xr [<command>] [<uuid>]
Arguments:
command Optional subcommand, see below; when ommitted, defaults to 'test'.
uuid Unique identifier for a submission: a 32-digit hex value. If a
UUID is given -- when using the 'test' or 'bench' commands, first
the corresponding exercise is downloaded using \`exercism\` and
the shell's current directory is changed to the returned value,
then the command's actual operation is executed.
Commands:
h, help Display this message.
c, clean Confirm and remove all the downloaded student submissions from
the file system using \`exercism\` in order to determine their
location.
n, notes Dump the contents of the mentoring notes for the current exercise
to the standard output, as deduced by reading the exercise config,
or from an exercise or topic of your choice through a second
argument, but in this case it must be explicitly prefixed with the
track name like so for example: \`xr notes rust/anagram\`.
e, edit Open the mentoring notes for the current exercise in the editor
specified by the EDITOR environment variable, as deduced by
reading the exercise's configuration, or from an exercise or topic
of your choice through a second argument with the same rules as
'notes'.
t, test Source the current track's script functions and run the unit tests
of the local exercise according to the dedicated function. This is
the default command when not specifying one but still giving a UUID.
b, bench Source the current track's script functions and run the benchmarks
of the local exercise according to the dedicated function. It is
usually copying a file to its correct place and call the bencher.
The path of the file to copy is deduced from the exercise's local
\`$_exo_config\` configuration file.
EOF
# Returns the value associated to the given key in the exercise's configuration.
function _config_get() {
grep -Eo "\"$1\""':"[a-zA-Z0-9-]+"' "$_exo_config" \
| cut -d':' -f2 \
| cut -d'"' -f2
}
# Downloads and goes to the directory of the given UUID's exercise.
function _dl_exo() {
cd $(exercism download --uuid="$1" 2>/dev/null | tail -n 1)
}
# Fetches the track-specific functions from the dedicated script.
function _src_track() {
local script="$_dir/tracks/$(_config_get track).sh"
if [[ -f "$script" ]]; then
source "$script"
else
echo "Unknown track script file: $script" >&2
return 1
fi
}
# Tests whether the given string is a valid UUID or not.
function _is_uuid() {
[[ "$1" =~ ^[[:xdigit:]]{32}$ ]]
}
# Public function.
function xr() {
if [[ "$#" == "0" || "$#" -gt "2" ]]; then
echo "$_short_doc" >&2
return 1
else
case "$1" in
"h" | "help")
echo "$_long_doc"
;;
"c" | "clean")
local dir="$(exercism workspace)/users" \
&& echo "Will delete: $dir" \
&& rm -rI "$dir"
;;
"n" | "notes" | "e" | "edit")
local note="$_dir/notes"
if [[ "$#" == "2" ]]; then
note="$note/$2.md"
else
note="$note/$(_config_get track)/$(_config_get exercise).md"
fi
if [[ ( "$1" == "n" ) || ( "$1" == "notes" ) ]]; then
if [[ -f "$note" ]]; then
cat "$note"
else
echo "Unknown exercise or topic note: $note" >&2
return 1
fi
elif [[ "$(basename $note)" != ".md" ]]; then
$EDITOR "$note"
else
echo "Current directory is not an exercise." >&2
return 1
fi
;;
"t" | "test" | "b" | "bench")
if [[ "$#" == "2" ]]; then
if _is_uuid "$2"; then
_dl_exo "$2"
else
echo "Invalid UUID: $2" >&2
return 1
fi
fi
case "$1" in
"t" | "test")
_src_track && _run_tests
;;
"b" | "bench")
_src_track && _run_benches
;;
esac
;;
*)
if _is_uuid "$1"; then
_dl_exo "$1" \
&& _src_track \
&& _run_tests
else
echo "Unsupported command: $1" >&2
return 1
fi
;;
esac
fi
}