spoom 1.0.4 → 1.0.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +0 -1
  3. data/README.md +296 -1
  4. data/Rakefile +1 -0
  5. data/lib/spoom.rb +21 -2
  6. data/lib/spoom/cli.rb +56 -10
  7. data/lib/spoom/cli/bump.rb +138 -0
  8. data/lib/spoom/cli/config.rb +51 -0
  9. data/lib/spoom/cli/coverage.rb +206 -0
  10. data/lib/spoom/cli/helper.rb +149 -0
  11. data/lib/spoom/cli/lsp.rb +165 -0
  12. data/lib/spoom/cli/run.rb +109 -0
  13. data/lib/spoom/coverage.rb +89 -0
  14. data/lib/spoom/coverage/d3.rb +110 -0
  15. data/lib/spoom/coverage/d3/base.rb +50 -0
  16. data/lib/spoom/coverage/d3/circle_map.rb +195 -0
  17. data/lib/spoom/coverage/d3/pie.rb +175 -0
  18. data/lib/spoom/coverage/d3/timeline.rb +486 -0
  19. data/lib/spoom/coverage/report.rb +308 -0
  20. data/lib/spoom/coverage/snapshot.rb +132 -0
  21. data/lib/spoom/file_tree.rb +196 -0
  22. data/lib/spoom/git.rb +98 -0
  23. data/lib/spoom/printer.rb +80 -0
  24. data/lib/spoom/sorbet.rb +99 -47
  25. data/lib/spoom/sorbet/config.rb +30 -0
  26. data/lib/spoom/sorbet/errors.rb +33 -15
  27. data/lib/spoom/sorbet/lsp.rb +2 -4
  28. data/lib/spoom/sorbet/lsp/structures.rb +108 -14
  29. data/lib/spoom/sorbet/metrics.rb +10 -79
  30. data/lib/spoom/sorbet/sigils.rb +98 -0
  31. data/lib/spoom/test_helpers/project.rb +112 -0
  32. data/lib/spoom/timeline.rb +53 -0
  33. data/lib/spoom/version.rb +2 -2
  34. data/templates/card.erb +8 -0
  35. data/templates/card_snapshot.erb +22 -0
  36. data/templates/page.erb +50 -0
  37. metadata +28 -11
  38. data/lib/spoom/cli/commands/base.rb +0 -36
  39. data/lib/spoom/cli/commands/config.rb +0 -67
  40. data/lib/spoom/cli/commands/lsp.rb +0 -156
  41. data/lib/spoom/cli/commands/run.rb +0 -92
  42. data/lib/spoom/cli/symbol_printer.rb +0 -71
  43. data/lib/spoom/config.rb +0 -11
@@ -1,156 +0,0 @@
1
- # typed: true
2
- # frozen_string_literal: true
3
-
4
- require 'shellwords'
5
-
6
- require_relative "base"
7
- require_relative "../symbol_printer"
8
- require_relative "../../sorbet/lsp"
9
-
10
- module Spoom
11
- module Cli
12
- module Commands
13
- class LSP < Base
14
- default_task :show
15
-
16
- desc "interactive", "interactive LSP mode"
17
- def show
18
- in_sorbet_project!
19
- lsp = lsp_client
20
- # TODO: run interactive mode
21
- puts lsp
22
- end
23
-
24
- desc "list", "list all known symbols"
25
- # TODO: options, filter, limit, kind etc.. filter rbi
26
- def list
27
- run do |client|
28
- Dir["**/*.rb"].each do |file|
29
- res = client.document_symbols(file.to_uri)
30
- next if res.empty?
31
- puts "Symbols from `#{file}`:"
32
- SymbolPrinter.print_object(res, options["no_color"])
33
- end
34
- end
35
- end
36
-
37
- desc "hover", "request hover informations"
38
- # TODO: options, filter, limit, kind etc.. filter rbi
39
- def hover(file, line, col)
40
- run do |client|
41
- res = client.hover(file.to_uri, line.to_i, col.to_i)
42
- say "Hovering `#{file}:#{line}:#{col}`:"
43
- if res
44
- SymbolPrinter.print_object(res, options["no_color"])
45
- else
46
- puts "<no data>"
47
- end
48
- end
49
- end
50
-
51
- desc "defs", "list definitions of a symbol"
52
- # TODO: options, filter, limit, kind etc.. filter rbi
53
- def defs(file, line, col)
54
- run do |client|
55
- res = client.definitions(file.to_uri, line.to_i, col.to_i)
56
- puts "Definitions for `#{file}:#{line}:#{col}`:"
57
- SymbolPrinter.print_list(res, options["no_color"])
58
- end
59
- end
60
-
61
- desc "find", "find symbols matching a query"
62
- # TODO: options, filter, limit, kind etc.. filter rbi
63
- def find(query)
64
- run do |client|
65
- res = client.symbols(query)
66
- puts "Symbols matching `#{query}`:"
67
- printer = SymbolPrinter.new(2, options["no_color"])
68
- res.each do |symbol|
69
- next if symbol.location.uri.start_with?("https")
70
- printer.visit(symbol)
71
- end
72
- end
73
- end
74
-
75
- desc "symbols", "list symbols from a file"
76
- # TODO: options, filter, limit, kind etc.. filter rbi
77
- def symbols(file)
78
- run do |client|
79
- res = client.document_symbols(file.to_uri)
80
- puts "Symbols from `#{file}`:"
81
- SymbolPrinter.print_object(res, options["no_color"])
82
- end
83
- end
84
-
85
- desc "refs", "list references to a symbol"
86
- # TODO: options, filter, limit, kind etc.. filter rbi
87
- def refs(file, line, col)
88
- run do |client|
89
- res = client.references(file.to_uri, line.to_i, col.to_i)
90
- puts "References to `#{file}:#{line}:#{col}`:"
91
- SymbolPrinter.print_list(res, options["no_color"])
92
- end
93
- end
94
-
95
- desc "sigs", "list signatures for a symbol"
96
- # TODO: options, filter, limit, kind etc.. filter rbi
97
- def sigs(file, line, col)
98
- run do |client|
99
- res = client.signatures(file.to_uri, line.to_i, col.to_i)
100
- puts "Signature for `#{file}:#{line}:#{col}`:"
101
- SymbolPrinter.print_list(res, options["no_color"])
102
- end
103
- end
104
-
105
- desc "types", "display type of a symbol"
106
- # TODO: options, filter, limit, kind etc.. filter rbi
107
- def types(file, line, col)
108
- run do |client|
109
- res = client.type_definitions(file.to_uri, line.to_i, col.to_i)
110
- say "Type for `#{file}:#{line}:#{col}`:"
111
- SymbolPrinter.print_list(res, options["no_color"])
112
- end
113
- end
114
-
115
- no_commands do
116
- def lsp_client
117
- in_sorbet_project!
118
- client = Spoom::LSP::Client.new(
119
- Spoom::Config::SORBET_PATH,
120
- "--lsp",
121
- "--enable-all-experimental-lsp-features",
122
- "--disable-watchman",
123
- )
124
- client.open(Spoom::Config::WORKSPACE_PATH)
125
- client
126
- end
127
-
128
- def run(&block)
129
- client = lsp_client
130
- block.call(client)
131
- rescue Spoom::LSP::Error::Diagnostics => err
132
- say_error("Sorbet returned typechecking errors for `#{err.uri.from_uri}`")
133
- err.diagnostics.each do |d|
134
- say_error("#{d.message} (#{d.code})", " #{d.range}")
135
- end
136
- exit(1)
137
- rescue Spoom::LSP::Error::BadHeaders => err
138
- say_error("Sorbet didn't answer correctly (#{err.message})")
139
- exit(1)
140
- rescue Spoom::LSP::Error => err
141
- say_error(err.message)
142
- exit(1)
143
- ensure
144
- begin
145
- client&.close
146
- rescue
147
- # We can't do much if Sorbet refuse to close.
148
- # We kill the parent process and let the child be killed.
149
- exit(1)
150
- end
151
- end
152
- end
153
- end
154
- end
155
- end
156
- end
@@ -1,92 +0,0 @@
1
- # typed: true
2
- # frozen_string_literal: true
3
-
4
- require_relative "base"
5
-
6
- module Spoom
7
- module Cli
8
- module Commands
9
- class Run < Base
10
- default_task :tc
11
-
12
- desc "tc", "run srb tc"
13
- option :limit, type: :numeric, aliases: :l
14
- option :code, type: :numeric, aliases: :c
15
- option :sort, type: :string, aliases: :s
16
- def tc
17
- in_sorbet_project!
18
-
19
- limit = options[:limit]
20
- sort = options[:sort]
21
- code = options[:code]
22
- colors = !options[:no_color]
23
-
24
- unless limit || code || sort
25
- return Spoom::Sorbet.srb_tc(capture_err: false).last
26
- end
27
-
28
- output, status = Spoom::Sorbet.srb_tc(capture_err: true)
29
- if status
30
- $stderr.print(output)
31
- return 0
32
- end
33
-
34
- errors = Spoom::Sorbet::Errors::Parser.parse_string(output)
35
- errors_count = errors.size
36
-
37
- errors = sort == "code" ? errors.sort_by { |e| [e.code, e.file, e.line, e.message] } : errors.sort
38
- errors = errors.select { |e| e.code == code } if code
39
- errors = T.must(errors.slice(0, limit)) if limit
40
-
41
- errors.each do |e|
42
- code = colorize_code(e.code, colors)
43
- message = colorize_message(e.message, colors)
44
- $stderr.puts "#{code} - #{e.file}:#{e.line}: #{message}"
45
- end
46
-
47
- if errors_count == errors.size
48
- $stderr.puts "Errors: #{errors_count}"
49
- else
50
- $stderr.puts "Errors: #{errors.size} shown, #{errors_count} total"
51
- end
52
-
53
- 1
54
- end
55
-
56
- desc "metrics", "run srb tc and display metrics"
57
- def metrics
58
- in_sorbet_project!
59
-
60
- metrics = Spoom::Sorbet.srb_metrics(capture_err: false)
61
- if metrics
62
- metrics.show
63
- else
64
- puts "no data"
65
- end
66
- end
67
-
68
- no_commands do
69
- def colorize_code(code, colors = true)
70
- return code.to_s unless colors
71
- code.to_s.light_black
72
- end
73
-
74
- def colorize_message(message, colors = true)
75
- return message unless colors
76
-
77
- cyan = T.let(false, T::Boolean)
78
- word = StringIO.new
79
- message.chars.each do |c|
80
- if c == '`'
81
- cyan = !cyan
82
- next
83
- end
84
- word << (cyan ? c.cyan : c.red)
85
- end
86
- word.string
87
- end
88
- end
89
- end
90
- end
91
- end
92
- end
@@ -1,71 +0,0 @@
1
- # typed: true
2
- # frozen_string_literal: true
3
-
4
- require "colorize"
5
-
6
- module Spoom
7
- module Cli
8
- class SymbolPrinter
9
- attr_accessor :seen, :no_color
10
-
11
- def self.print_list(list, no_color)
12
- printer = SymbolPrinter.new(2, no_color)
13
- list.each do |item|
14
- printer.print(" * ")
15
- printer.visit(item)
16
- printer.printn
17
- end
18
- end
19
-
20
- def self.print_object(object, no_color)
21
- printer = SymbolPrinter.new(2, no_color)
22
- printer.visit(object)
23
- end
24
-
25
- def initialize(default_indent, no_color = false)
26
- @seen = Set.new
27
- @current_indent = default_indent
28
- @no_color = no_color
29
- String.disable_colorization = no_color
30
- end
31
-
32
- def indent
33
- @current_indent += 2
34
- end
35
-
36
- def dedent
37
- @current_indent -= 2
38
- end
39
-
40
- def print(string)
41
- Kernel.print(string)
42
- end
43
-
44
- def printn
45
- print("\n")
46
- end
47
-
48
- def printt
49
- print(" " * @current_indent)
50
- end
51
-
52
- def visit(object)
53
- if object.is_a?(Array)
54
- object.each { |e| visit(e) }
55
- else
56
- object.accept_printer(self)
57
- end
58
- end
59
- end
60
- end
61
- end
62
-
63
- class String
64
- def to_uri
65
- "file://" + File.join(Spoom::Config::WORKSPACE_PATH, self)
66
- end
67
-
68
- def from_uri
69
- sub("file://#{Spoom::Config::WORKSPACE_PATH}", "")
70
- end
71
- end
data/lib/spoom/config.rb DELETED
@@ -1,11 +0,0 @@
1
- # typed: true
2
- # frozen_string_literal: true
3
-
4
- module Spoom
5
- module Config
6
- SORBET_CONFIG = "sorbet/config"
7
- SORBET_GEM_PATH = Gem::Specification.find_by_name("sorbet-static").full_gem_path
8
- SORBET_PATH = (Pathname.new(SORBET_GEM_PATH) / "libexec" / "sorbet").to_s
9
- WORKSPACE_PATH = (Pathname.new(ENV['BUNDLE_GEMFILE']) / "..").to_s
10
- end
11
- end