-
Notifications
You must be signed in to change notification settings - Fork 9
/
findref.bash
executable file
·164 lines (127 loc) · 3.61 KB
/
findref.bash
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
162
163
#!/bin/bash
DEBUG_MODE=0
# Uncomment the next line to turn on debug output
# DEBUG_MODE=1
TEMP_FILE=$(mktemp)
ABS_PATH_COMMAND="realpath"
IN_GIT_REPO=0
color_light_blue='\033[1;34m'
color_restore='\033[0m'
cur_millis_since_epoch ()
{
echo $(date +%3N)
}
cur_secs_since_epoch ()
{
echo $(date +%s)
}
cur_secs_millis_since_epoch ()
{
echo $(date +%s%3N)
}
START_DEBUG_SECS="$(cur_secs_since_epoch)"
DEBUG ()
{
if (( $DEBUG_MODE )); then
echo -e "${color_light_blue}[*] $(( $(cur_secs_since_epoch) - $START_DEBUG_SECS)).$(cur_millis_since_epoch) - DEBUG: $1${color_restore}"
fi
}
print_usage ()
{
echo "Usage: findref [-f|--fast (skip git ignore list)] \"what text (RegEx) to look for\" \"[starting location (root dir)]\" \"[filenames to check (must match pattern)]\"";
}
if [ -z "$1" ]; then
print_usage
exit;
fi
# Need an absolute path - prefer realpath to readlink if we have it installed
if ! $(which realpath > /dev/null 2>&1); then
ABS_PATH_COMMAND="readlink -f"
fi
# skip this if given --fast or -f
if [ -n "$3" ]; then
DEBUG "Skipping git ignore check because we have filename specified ($3)"
elif [[ ! $@ =~ -f ]]; then
DEBUG "Checking if we're in a git repo"
# Determine if we are inside of a Git repo so we can consider the .gitignore file
prevDir="$(pwd)"
while true; do
if [ -d ".git" ]; then
IN_GIT_REPO=1
break
fi
if [ "$(pwd)" = "/" ]; then
break;
fi
cd ..
done
cd $prevDir
if (( DEBUG_MODE )); then
if (( IN_GIT_REPO )); then
DEBUG "In Git repo"
else
DEBUG "Not in a Git repo"
fi
fi
else
# need to shift away the --fast or -f
DEBUG "Fast mode turned on, not checking for git repo"
shift
fi
# where needs to have an absolute path to properly work with our git ignore list
if [ -z "$2" ] || [ ! -e "$2" ]; then
where="$(pwd)";
else
# prefer realpath if installed, otherwise use readlink to get absolute path
where="$(eval $ABS_PATH_COMMAND $2)"
fi
DEBUG "Determined to search from $where"
if [ -z "$1" ]; then
print_usage
exit;
else
what=$(echo "$1" | sed 's/ /\\s/g');
fi
DEBUG "Determined to search for lines matching $what"
if [ -z "$3" ]; then
filename="";
else
filename='-iname "$3"';
fi;
DEBUG "Determined to search filenames matching $filename"
DEBUG "Populating the TEMP_FILE $TEMP_FILE with filenames to search"
if (( $IN_GIT_REPO )); then
DEBUG "In Git repo, so using git's list of files"
for i in $(git ls-files --exclude-standard); do
[ -f "$i" ] && echo "$i" >> $TEMP_FILE
done
for i in $(git ls-files --others --exclude-standard); do
[ -f "$i" ] && echo "$i" >> $TEMP_FILE
done
else
DEBUG "Not in git repo, finding all filenames matching pattern $filename"
eval find "$where" -type f "$filename" > $TEMP_FILE;
fi
DEBUG "Done populating the TEMP_FILE"
numlines=$(cat $TEMP_FILE | wc -l);
DEBUG "Grepping $numlines files"
for ((i=1; ((1)); i+=1000 ))
do
if (( numlines > 1000 )); then
topBoundary=1000;
else
topBoundary=numlines;
fi;
sed -n $i,$(( i + topBoundary ))p $TEMP_FILE | sed 's/ /\\ /g' | sed "s/'//g" | xargs grep --color --binary-files=without-match --directories=skip --devices=skip --line-number $what;
numlines=$(( numlines - topBoundary ));
if (( numlines <= 0 )); then
break;
fi;
done;
DEBUG "Done grepping the files"
# clean up the temp files if they exist
if [ -f "$TEMP_FILE" ]; then
DEBUG "Deleting TEMP_FILE $TEMP_FILE"
rm -f "$TEMP_FILE";
fi
DEBUG "All done!"