referral 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +61 -48
- data/exe/referral +4 -0
- data/lib/referral.rb +4 -3
- data/lib/referral/cli.rb +1 -0
- data/lib/referral/ensures_working_ruby.rb +27 -0
- data/lib/referral/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6e9c718aeaa911a43d9f908ff6627f237b4d060d24c70ffe5266f997acc13e6d
|
4
|
+
data.tar.gz: 0e37e4bc4ea3b095ba44ba3a89398940e56e7672302ce1ee7b856a1312f59b63
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a5eeb557ef3127b448d868a292f0eca478c66c918d77abace17c0141a75795816a9ea3acc86db29ca82a6199cdc2cd86bc0cf1ddbcca088a4ed5c62b4d91f534
|
7
|
+
data.tar.gz: 011312e247b8aeca7acfe0a200c1c14e8eb799daac38d645ec30bef5a39659bd26e0760320fd82db64c6a35d8ded79dfc0f2e944a80f267745bd68a94236846e
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -1,29 +1,30 @@
|
|
1
|
-
#
|
1
|
+
# Referral 🔍
|
2
2
|
|
3
|
-
Referral is a CLI
|
4
|
-
|
5
|
-
identifiers (e.g. classes, methods, and variables) throughout
|
3
|
+
Referral is a CLI to help you undertake complex analyses and refactorings of
|
4
|
+
Ruby codebases. It finds, filters, and sorts the definitions & references of
|
5
|
+
most types of Ruby identifiers (e.g. classes, methods, and variables) throughout
|
6
|
+
your code.
|
6
7
|
|
7
|
-
Think of `referral` as a toolkit for tracking down references
|
8
|
-
|
9
|
-
you to
|
8
|
+
Think of `referral` as a toolkit for tracking down references in your code for
|
9
|
+
any number of purposes, offering a boatload of command-line options to
|
10
|
+
enable you to efficiently accomplish things like:
|
10
11
|
|
11
12
|
* Size up a codebase by gathering basic statistics and spotting usage hotspots
|
12
13
|
* Build a to-do list to help you manage a large or complex refactor
|
13
|
-
*
|
14
|
-
|
14
|
+
* Quickly make a list of every call to a deprecated method, rather than wait for
|
15
|
+
warnings at runtime
|
16
|
+
* Get a sense for how many callers would be impacted if you were to delete a method
|
17
|
+
* Before renaming a module, verify there aren't already any other modules with
|
15
18
|
the new name
|
16
19
|
* Verify that you removed every reference to a deleted class before you merge
|
17
20
|
* Identify dead code, like method definitions that aren't invoked anywhere
|
18
21
|
* Catch references that haven't been updated since a change that affected them
|
19
|
-
(
|
20
|
-
* Rather than wait for warnings at runtime, quickly make a list of every call to
|
21
|
-
deprecated methods
|
22
|
+
(according to `git-blame`)
|
22
23
|
|
23
24
|
Because Referral is powered by the introspection made possible by Ruby 2.6's
|
24
25
|
[RubyVM::AbstractSyntaxTree](https://ruby-doc.org/core-2.6.3/RubyVM/AbstractSyntaxTree.html)
|
25
|
-
API, it
|
26
|
-
Rubies.
|
26
|
+
API, it must be run with Ruby 2.6 or later. Nevertheless, it can often analyze
|
27
|
+
code _listings_ designed to run on older Rubies.
|
27
28
|
|
28
29
|
## Install
|
29
30
|
|
@@ -39,12 +40,12 @@ Or in your `Gemfile`
|
|
39
40
|
gem "referral", require: false, group: :development
|
40
41
|
```
|
41
42
|
|
42
|
-
##
|
43
|
+
## How to use Referral
|
43
44
|
|
44
45
|
### Basic usage
|
45
46
|
|
46
47
|
At its most basic, you can just run `referral` and it'll scan `**/*.rb` from the
|
47
|
-
current working directory and print
|
48
|
+
current working directory and print every reference it finds:
|
48
49
|
|
49
50
|
```
|
50
51
|
$ referral
|
@@ -57,21 +58,28 @@ app/channels/application_cable/channel.rb:2:18: constant ApplicationCable::Chann
|
|
57
58
|
By default, Referral will sort entries by file, line, and column. Default output
|
58
59
|
is broken into 4 columns: `location`, `type`, `scope`, and `name`.
|
59
60
|
|
61
|
+
If you'd like to scan a subset of files, you can pass a final argument with file
|
62
|
+
paths and directories. For example, if you only wanted to search code in the
|
63
|
+
top-level of `app/lib` you could run `referral app/lib/*.rb`. Or, if you wanted
|
64
|
+
to include subdirectories, `referral app/lib`.
|
65
|
+
|
60
66
|
Everything above can be custom-tailored to your purposes, so let's work through
|
61
|
-
some
|
67
|
+
some example recipes to teach you Referral's various features below. (Or, feel
|
68
|
+
free to skip to the [full list of
|
69
|
+
options](https://github.com/testdouble/referral#options)).
|
62
70
|
|
63
|
-
###
|
71
|
+
### Recipe: build a refactoring to-do spreadsheet
|
64
72
|
|
65
73
|
When I'm undergoing a large refactor, I like to start by grepping around for all
|
66
|
-
the obvious definitions and references that might be affected. Suppose I'm
|
67
|
-
|
68
|
-
|
74
|
+
the obvious definitions and references that might be affected. Suppose I'm going
|
75
|
+
to make major changes to my `User` class. I might use Referral's `--exact-name`
|
76
|
+
filter like this:
|
69
77
|
|
70
78
|
```
|
71
79
|
referral --exact-name User,user,@user,@current_user
|
72
80
|
```
|
73
81
|
|
74
|
-
[Fun fact
|
82
|
+
[**Fun fact:** if I'd have wanted to match on partial names, I could have used the looser
|
75
83
|
`--name`, or for fully-qualified names (e.g. `API::User`), the stricter
|
76
84
|
`--full-name` option.]
|
77
85
|
|
@@ -84,10 +92,13 @@ makes more sense to sort by the fully-qualified scope, which can be done with
|
|
84
92
|
referral --exact-name User,user,@user,@current_user --sort scope
|
85
93
|
```
|
86
94
|
|
95
|
+
The above will sort results by their fully-qualified names (e.g. `A::B#c`),
|
96
|
+
rather than their filenames.
|
97
|
+
|
87
98
|
Of course, if we want a checklist, the default output could be made a lot nicer
|
88
99
|
for export to a spreadsheet app like [Numbers](https://www.apple.com/numbers/).
|
89
|
-
|
90
|
-
|
100
|
+
Here's how you might invoke `referral` to save a tab-separated-values (TSV)
|
101
|
+
file:
|
91
102
|
|
92
103
|
```
|
93
104
|
referral --exact-name User,user,@user,@current_user --sort scope --print-headers --delimiter "\t" > user_refs.tsv
|
@@ -104,12 +115,12 @@ Now, to open it in Numbers, I'd run:
|
|
104
115
|
open -a Numbers user_refs.tsv
|
105
116
|
```
|
106
117
|
|
107
|
-
And be
|
108
|
-
there while
|
118
|
+
And you'll be greeted by a spreadsheet. And hey, why not throw a checkbox column
|
119
|
+
on there while you're at it:
|
109
120
|
|
110
121
|
<img width="1272" alt="Screen Shot 2019-06-27 at 1 27 42 PM" src="https://user-images.githubusercontent.com/79303/60287234-64560a00-98df-11e9-9fed-46c68fdaac58.png">
|
111
122
|
|
112
|
-
###
|
123
|
+
### Recipe: detect references you forgot to update
|
113
124
|
|
114
125
|
When working in a large codebase, it can be really tough to figure out if you
|
115
126
|
remembered to update every reference to a class or method across thousands of
|
@@ -129,21 +140,20 @@ test/lib/splits_furigana_test.rb 56 634edc04 searls@gmail.com 2017-09-04T13:34:0
|
|
129
140
|
test/lib/splits_furigana_test.rb 56 634edc04 searls@gmail.com 2017-09-04T13:34:09Z @subject.call
|
130
141
|
```
|
131
142
|
|
132
|
-
[Warning
|
143
|
+
[**Warning:** running `git-blame` on each file is, of course, a bit slow. Running
|
133
144
|
this command on the [KameSame](https://kamesame.com) codebase took 3 seconds of
|
134
145
|
wall-time, compared to 0.7 seconds by default.]
|
135
146
|
|
136
|
-
And it gets better! Since we're already running blame
|
137
|
-
by its most and least recent commit time
|
138
|
-
|
139
|
-
|
140
|
-
least_recent_commit`, which does just what it says on the tin:
|
147
|
+
And it gets better! Since we're already running `blame`, why not sort every line
|
148
|
+
by its most and least recent commit time? You can! To list the
|
149
|
+
least-recently-changed references first, add the option `--sort
|
150
|
+
least_recent_commit`:
|
141
151
|
|
142
152
|
```
|
143
|
-
referral --column file,line,git_sha,git_author,git_commit_at,full_name
|
153
|
+
referral --sort least_recent_commit --column file,line,git_sha,git_author,git_commit_at,full_name
|
144
154
|
```
|
145
155
|
|
146
|
-
|
156
|
+
In my case, I see that my least-recently-updated Ruby reference is:
|
147
157
|
|
148
158
|
```
|
149
159
|
app/channels/application_cable/channel.rb 1 searls@gmail.com 2017-08-20T14:59:35Z ApplicationCable
|
@@ -152,7 +162,7 @@ app/channels/application_cable/channel.rb 1 searls@gmail.com 2017-08-20T14:59:3
|
|
152
162
|
The inclusion of `git-blame` fields and sorting can be a powerful tool to
|
153
163
|
spot-check a large refactor before deciding to merge it in.
|
154
164
|
|
155
|
-
###
|
165
|
+
### Recipe: search for a regex pattern and print the source
|
156
166
|
|
157
167
|
Once in a while, I'll want to scan line-by-line in a codebase for lines that
|
158
168
|
match a given pattern, and in those cases, the `--pattern` option and `source`
|
@@ -183,17 +193,19 @@ with a lot of (apparent) arguments? You could filter the matches down with
|
|
183
193
|
referral --pattern "/^([^,]*,){4,}[^,]*$/" -c location,git_commit_at,source -s most_recent_commit --type instance_method,class_method
|
184
194
|
```
|
185
195
|
|
186
|
-
|
187
|
-
method definition
|
196
|
+
In my results, I learned that as recently as June 6th, I wrote a very
|
197
|
+
long method definition:
|
188
198
|
|
189
199
|
```
|
190
200
|
app/lib/presents_review_result.rb:60:2: 2019-06-02T02:38:01Z def item_result(study_card_identifier, user, answer, item, learning, judgment, reward)
|
191
201
|
```
|
192
202
|
|
203
|
+
`find` couldn't have told me that (I don't think)!
|
204
|
+
|
193
205
|
## Options
|
194
206
|
|
195
|
-
The help output of `referral --help` will
|
196
|
-
defaults:
|
207
|
+
Referral provides a lot of options. The help output of `referral --help` will
|
208
|
+
print out the available options and their defaults:
|
197
209
|
|
198
210
|
```
|
199
211
|
Usage: referral [options] files
|
@@ -214,28 +226,29 @@ Usage: referral [options] files
|
|
214
226
|
A few things to note:
|
215
227
|
|
216
228
|
* Each of `--name`, `--exact-name`, `--full-name`, `--type`, and `--columns`
|
217
|
-
accept comma-separated arrays (e.g.
|
229
|
+
accept comma-separated arrays (e.g. `--name foo,bar,baz`)
|
218
230
|
|
219
231
|
* You can browse available sort functions [in
|
220
|
-
|
232
|
+
Referral::SORT_FUNCTIONS](/lib/referral/sorts_tokens.rb) for use with
|
221
233
|
`--sort`. Each key is the name to be specified on the command line. (If you're
|
222
234
|
feeling adventurous, we've left the hash unfrozen so you can define your own
|
223
235
|
custom sorts dynamically, but YMMV.)
|
224
236
|
|
225
237
|
* Just like sort functions, you can find the available column types [in
|
226
|
-
|
238
|
+
Referral::COLUMN_FUNCTIONS](/lib/referral/prints_results.rb) when passing a
|
227
239
|
comma-separated list to `--column`. (This hash has
|
228
240
|
also been left mutable for you, dear user.)
|
229
241
|
|
230
242
|
* The types of AST nodes that Referral supports can be found [in
|
231
|
-
|
232
|
-
certain `--type`
|
243
|
+
Referral::TOKEN_TYPES](/lib/referral/token_types.rb) when filtering to
|
244
|
+
certain definition & reference types with `--type`
|
233
245
|
|
234
246
|
* Note that the columns `git_sha`, `git_author`, `git_commit_at` and the sort
|
235
|
-
functions `most_recent_commit` and `least_recent_commit` will
|
236
|
-
`git-blame`
|
247
|
+
functions `most_recent_commit` and `least_recent_commit` will slow things down
|
248
|
+
a bit, by invoking `git-blame` for each file included in the filtered
|
249
|
+
results
|
237
250
|
|
238
|
-
*
|
251
|
+
* The `source` column and `--pattern` options will read each file in
|
239
252
|
the result set twice: once when parsing the AST, and again when printing
|
240
253
|
results
|
241
254
|
|
data/exe/referral
CHANGED
data/lib/referral.rb
CHANGED
@@ -1,11 +1,12 @@
|
|
1
|
-
require "referral/runner"
|
2
|
-
|
3
1
|
require "referral/version"
|
4
2
|
require "referral/error"
|
5
|
-
require "referral/cli"
|
6
3
|
|
7
4
|
module Referral
|
8
5
|
def self.run(*args, **kwargs, &blk)
|
6
|
+
require "referral/ensures_working_ruby"
|
7
|
+
Referral::EnsuresWorkingRuby.new.call
|
8
|
+
|
9
|
+
require "referral/runner"
|
9
10
|
Runner.new.call(*args, **kwargs, &blk)
|
10
11
|
end
|
11
12
|
end
|
data/lib/referral/cli.rb
CHANGED
@@ -0,0 +1,27 @@
|
|
1
|
+
require "referral/error"
|
2
|
+
|
3
|
+
module Referral
|
4
|
+
class EnsuresWorkingRuby
|
5
|
+
def call
|
6
|
+
major, minor = RUBY_VERSION.split(".").map(&:to_i)
|
7
|
+
unless major >= 3 || (major == 2 && minor >= 6)
|
8
|
+
warn <<-ERROR.gsub(/^ {10}/, "")
|
9
|
+
Error: referral must be run with Ruby 2.6 or later, but this is #{RUBY_VERSION}.
|
10
|
+
You can often analyze older Ruby code by running this CLI with a newer
|
11
|
+
Ruby than the code being inspected.
|
12
|
+
|
13
|
+
Tools like rbenv may help you manage this issue. If you install
|
14
|
+
referral into a supported Ruby, you can specify that it be run with
|
15
|
+
an environment variable, even if the current directory is locked
|
16
|
+
to an older version of Ruby. Just specify the Ruby you want to use:
|
17
|
+
|
18
|
+
RBENV_VERSION=2.6.3 referral
|
19
|
+
|
20
|
+
ERROR
|
21
|
+
raise Referral::Error.new(
|
22
|
+
"Unsupported Ruby version (expected 2.6.0 or later, was #{RUBY_VERSION}"
|
23
|
+
)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/referral/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: referral
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Justin Searls
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-06-
|
11
|
+
date: 2019-06-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -87,6 +87,7 @@ files:
|
|
87
87
|
- exe/referral
|
88
88
|
- lib/referral.rb
|
89
89
|
- lib/referral/cli.rb
|
90
|
+
- lib/referral/ensures_working_ruby.rb
|
90
91
|
- lib/referral/error.rb
|
91
92
|
- lib/referral/expands_directories.rb
|
92
93
|
- lib/referral/file_store.rb
|