Class: TypeProf::CLI::CLI
- Inherits:
-
Object
- Object
- TypeProf::CLI::CLI
- Defined in:
- lib/typeprof/cli/cli.rb
Instance Attribute Summary collapse
-
#cli_options ⇒ Object
readonly
Returns the value of attribute cli_options.
-
#core_options ⇒ Object
readonly
Returns the value of attribute core_options.
-
#lsp_options ⇒ Object
readonly
Returns the value of attribute lsp_options.
Instance Method Summary collapse
- #find_files ⇒ Object
- #generate_config_file ⇒ Object
-
#initialize(argv) ⇒ CLI
constructor
A new instance of CLI.
- #run ⇒ Object
- #run_cli ⇒ Object
- #run_lsp ⇒ Object
- #set_profiler ⇒ Object
- #setup_rbs_collection(path) ⇒ Object
Constructor Details
#initialize(argv) ⇒ CLI
Returns a new instance of CLI.
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 |
# File 'lib/typeprof/cli/cli.rb', line 3 def initialize(argv) opt = OptionParser.new opt. = "Usage: #{ opt.program_name } [options] files_or_dirs..." = {} = {} = {} output = nil rbs_collection_path = nil initialize_config_file = false exclude_patterns = [] opt.separator "" opt.separator "Options:" opt.on("-o OUTFILE", "Output to OUTFILE instead of stdout") {|v| output = v } opt.on("-q", "--quiet", "Quiet mode") do [:display_indicator] = false end opt.on("-v", "--verbose", "Verbose mode") do [:show_errors] = true end opt.on("--version", "Display typeprof version") { [:display_version] = true } opt.on("--collection PATH", "File path of collection configuration") { |v| rbs_collection_path = v } opt.on("--no-collection", "Ignore collection configuration") { rbs_collection_path = :no } opt.on("--exclude PATTERN", "Exclude files matching glob PATTERN (can be specified multiple times)") { |v| exclude_patterns << v } opt.on("--lsp", "LSP server mode") do |v| [:display_indicator] = false [:lsp] = true end opt.separator "" opt.separator "Analysis output options:" opt.on("--[no-]show-typeprof-version", "Display TypeProf version in a header") {|v| [:output_typeprof_version] = v } opt.on("--[no-]show-errors", "Display possible errors found during the analysis") {|v| [:output_diagnostics] = v } opt.on("--[no-]show-parameter-names", "Display parameter names for methods") {|v| [:output_parameter_names] = v } opt.on("--[no-]show-source-locations", "Display definition source locations for methods") {|v| [:output_source_locations] = v } opt.on("--[no-]show-stats", "Display type inference statistics after analysis (for debugging purpose)") {|v| [:output_stats] = v } opt.separator "" opt.separator "Advanced options:" opt.on("--[no-]stackprof MODE", /\Acpu|wall|object\z/, "Enable stackprof (for debugging purpose)") {|v| [:stackprof] = v.to_sym } opt.on("--init", 'Generate TypeProf configuration file') {|v| initialize_config_file = true} opt.separator "" opt.separator "LSP options:" opt.on("--port PORT", Integer, "Specify a port number to listen for requests on") {|v| [:port] = v } opt.on("--stdio", "Use stdio for LSP transport") {|v| [:stdio] = v } opt.parse!(argv) if initialize_config_file generate_config_file exit 0 end if ![:lsp] && !.empty? raise OptionParser::InvalidOption.new("lsp options with non-lsp mode") end @core_options = { rbs_collection: setup_rbs_collection(rbs_collection_path), display_indicator: $stderr.tty?, output_typeprof_version: true, output_errors: false, output_parameter_names: false, output_source_locations: false, output_stats: false, exclude_patterns: exclude_patterns, }.merge() @lsp_options = { port: 0, stdio: false, }.merge() @cli_options = { argv:, output: output ? open(output, "w") : $stdout.dup, display_version: false, stackprof: nil, lsp: false, }.merge() rescue OptionParser::InvalidOption, OptionParser::MissingArgument puts $! exit 1 end |
Instance Attribute Details
#cli_options ⇒ Object (readonly)
Returns the value of attribute cli_options.
113 114 115 |
# File 'lib/typeprof/cli/cli.rb', line 113 def @cli_options end |
#core_options ⇒ Object (readonly)
Returns the value of attribute core_options.
113 114 115 |
# File 'lib/typeprof/cli/cli.rb', line 113 def @core_options end |
#lsp_options ⇒ Object (readonly)
Returns the value of attribute lsp_options.
113 114 115 |
# File 'lib/typeprof/cli/cli.rb', line 113 def @lsp_options end |
Instance Method Details
#find_files ⇒ Object
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 |
# File 'lib/typeprof/cli/cli.rb', line 155 def find_files files = [] @cli_options[:argv].each do |path| if File.directory?(path) files.concat(Dir.glob("#{ path }/**/*.{rb,rbs}").select {|f| File.file?(f) }) elsif File.file?(path) files << path else raise OptionParser::InvalidOption.new("no such file or directory -- #{ path }") end end if files.empty? exit if @cli_options[:display_version] raise OptionParser::InvalidOption.new("no input files") end files end |
#generate_config_file ⇒ Object
191 192 193 194 195 196 197 198 199 200 201 202 |
# File 'lib/typeprof/cli/cli.rb', line 191 def generate_config_file exist_dirs = ["app", "lib"].select { |dir| File.exist?(File.join(Dir.pwd, dir)) } File.write('typeprof.conf.jsonc', <<~JSONC, mode: "wx") { "typeprof_version": "experimental", "rbs_dir": "sig/", "analysis_unit_dirs": #{exist_dirs.inspect}, // "exclude": ["**/templates/**/*.rb"], // "diagnostic_severity": "warning" } JSONC end |
#run ⇒ Object
115 116 117 118 119 120 121 122 |
# File 'lib/typeprof/cli/cli.rb', line 115 def run if @cli_options[:lsp] run_lsp else run_cli end end |
#run_cli ⇒ Object
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 |
# File 'lib/typeprof/cli/cli.rb', line 135 def run_cli core = TypeProf::Core::Service.new(@core_options) puts "typeprof #{ TypeProf::VERSION }" if @cli_options[:display_version] files = find_files set_profiler do output = @cli_options[:output] core.batch(files, @cli_options[:output]) output.close end rescue OptionParser::InvalidOption, OptionParser::MissingArgument puts $! exit 1 end |
#run_lsp ⇒ Object
124 125 126 127 128 129 130 131 132 133 |
# File 'lib/typeprof/cli/cli.rb', line 124 def run_lsp if @lsp_options[:stdio] TypeProf::LSP::Server.start_stdio(@core_options) else TypeProf::LSP::Server.start_socket(@core_options, @lsp_options[:port]) end rescue Exception puts $!.(highlight: false).gsub(/^/, "---") raise end |
#set_profiler ⇒ Object
175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 |
# File 'lib/typeprof/cli/cli.rb', line 175 def set_profiler if @cli_options[:stackprof] require "stackprof" out = "typeprof-stackprof-#{ @cli_options[:stackprof] }.dump" StackProf.start(mode: @cli_options[:stackprof], out: out, raw: true) end yield ensure if @cli_options[:stackprof] && defined?(StackProf) StackProf.stop StackProf.results end end |
#setup_rbs_collection(path) ⇒ Object
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
# File 'lib/typeprof/cli/cli.rb', line 93 def setup_rbs_collection(path) return nil if path == :no unless path path = RBS::Collection::Config::PATH.exist? ? RBS::Collection::Config::PATH.to_s : nil return nil unless path end if !File.readable?(path) raise OptionParser::InvalidOption.new("file not found: #{ path }") end lock_path = RBS::Collection::Config.to_lockfile_path(Pathname(path)) if !File.readable?(lock_path) raise OptionParser::InvalidOption.new("file not found: #{ lock_path.to_s }; please run 'rbs collection install") end RBS::Collection::Config::Lockfile.from_lockfile(lockfile_path: lock_path, data: YAML.load_file(lock_path)) end |