brakeman 4.5.0 → 4.5.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of brakeman might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGES.md +15 -0
- data/README.md +6 -6
- data/bundle/load.rb +3 -3
- data/bundle/ruby/2.5.0/gems/{highline-1.7.10 → highline-2.0.2}/AUTHORS +0 -0
- data/bundle/ruby/2.5.0/gems/{highline-1.7.10 → highline-2.0.2}/COPYING +0 -0
- data/bundle/ruby/2.5.0/gems/{highline-1.7.10 → highline-2.0.2}/Changelog.md +211 -15
- data/bundle/ruby/2.5.0/gems/highline-2.0.2/Gemfile +22 -0
- data/bundle/ruby/2.5.0/gems/{highline-1.7.10 → highline-2.0.2}/LICENSE +0 -0
- data/bundle/ruby/2.5.0/gems/highline-2.0.2/README.md +202 -0
- data/bundle/ruby/2.5.0/gems/{highline-1.7.10 → highline-2.0.2}/TODO +0 -0
- data/bundle/ruby/2.5.0/gems/highline-2.0.2/appveyor.yml +37 -0
- data/bundle/ruby/2.5.0/gems/highline-2.0.2/highline.gemspec +35 -0
- data/bundle/ruby/2.5.0/gems/highline-2.0.2/lib/highline.rb +650 -0
- data/bundle/ruby/2.5.0/gems/highline-2.0.2/lib/highline/builtin_styles.rb +129 -0
- data/bundle/ruby/2.5.0/gems/{highline-1.7.10 → highline-2.0.2}/lib/highline/color_scheme.rb +49 -32
- data/bundle/ruby/2.5.0/gems/highline-2.0.2/lib/highline/compatibility.rb +23 -0
- data/bundle/ruby/2.5.0/gems/highline-2.0.2/lib/highline/custom_errors.rb +57 -0
- data/bundle/ruby/2.5.0/gems/highline-2.0.2/lib/highline/import.rb +48 -0
- data/bundle/ruby/2.5.0/gems/highline-2.0.2/lib/highline/io_console_compatible.rb +37 -0
- data/bundle/ruby/2.5.0/gems/highline-2.0.2/lib/highline/list.rb +177 -0
- data/bundle/ruby/2.5.0/gems/highline-2.0.2/lib/highline/list_renderer.rb +261 -0
- data/bundle/ruby/2.5.0/gems/highline-2.0.2/lib/highline/menu.rb +576 -0
- data/bundle/ruby/2.5.0/gems/highline-2.0.2/lib/highline/menu/item.rb +32 -0
- data/bundle/ruby/2.5.0/gems/highline-2.0.2/lib/highline/paginator.rb +52 -0
- data/bundle/ruby/2.5.0/gems/{highline-1.7.10 → highline-2.0.2}/lib/highline/question.rb +281 -131
- data/bundle/ruby/2.5.0/gems/highline-2.0.2/lib/highline/question/answer_converter.rb +103 -0
- data/bundle/ruby/2.5.0/gems/highline-2.0.2/lib/highline/question_asker.rb +150 -0
- data/bundle/ruby/2.5.0/gems/highline-2.0.2/lib/highline/simulate.rb +59 -0
- data/bundle/ruby/2.5.0/gems/highline-2.0.2/lib/highline/statement.rb +88 -0
- data/bundle/ruby/2.5.0/gems/highline-2.0.2/lib/highline/string.rb +36 -0
- data/bundle/ruby/2.5.0/gems/highline-2.0.2/lib/highline/string_extensions.rb +130 -0
- data/bundle/ruby/2.5.0/gems/highline-2.0.2/lib/highline/style.rb +325 -0
- data/bundle/ruby/2.5.0/gems/highline-2.0.2/lib/highline/template_renderer.rb +62 -0
- data/bundle/ruby/2.5.0/gems/highline-2.0.2/lib/highline/terminal.rb +190 -0
- data/bundle/ruby/2.5.0/gems/highline-2.0.2/lib/highline/terminal/io_console.rb +36 -0
- data/bundle/ruby/2.5.0/gems/highline-2.0.2/lib/highline/terminal/ncurses.rb +38 -0
- data/bundle/ruby/2.5.0/gems/highline-2.0.2/lib/highline/terminal/unix_stty.rb +51 -0
- data/bundle/ruby/2.5.0/gems/{highline-1.7.10 → highline-2.0.2}/lib/highline/version.rb +3 -1
- data/bundle/ruby/2.5.0/gems/highline-2.0.2/lib/highline/wrapper.rb +53 -0
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.13.0 → ruby_parser-3.13.1}/History.rdoc +32 -0
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.13.0 → ruby_parser-3.13.1}/Manifest.txt +0 -0
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.13.0 → ruby_parser-3.13.1}/README.rdoc +0 -0
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.13.0 → ruby_parser-3.13.1}/compare/normalize.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.13.0 → ruby_parser-3.13.1}/debugging.md +0 -0
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.13.0 → ruby_parser-3.13.1}/lib/rp_extensions.rb +1 -1
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.13.0 → ruby_parser-3.13.1}/lib/rp_stringscanner.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.13.0 → ruby_parser-3.13.1}/lib/ruby20_parser.rb +2427 -2432
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.13.0 → ruby_parser-3.13.1}/lib/ruby20_parser.y +32 -29
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.13.0 → ruby_parser-3.13.1}/lib/ruby21_parser.rb +2101 -2109
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.13.0 → ruby_parser-3.13.1}/lib/ruby21_parser.y +32 -29
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.13.0 → ruby_parser-3.13.1}/lib/ruby22_parser.rb +2080 -2095
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.13.0 → ruby_parser-3.13.1}/lib/ruby22_parser.y +32 -29
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.13.0/lib/ruby25_parser.rb → ruby_parser-3.13.1/lib/ruby23_parser.rb} +2339 -2333
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.13.0 → ruby_parser-3.13.1}/lib/ruby23_parser.y +32 -29
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.13.0 → ruby_parser-3.13.1}/lib/ruby24_parser.rb +2347 -2335
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.13.0 → ruby_parser-3.13.1}/lib/ruby24_parser.y +32 -23
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.13.0/lib/ruby23_parser.rb → ruby_parser-3.13.1/lib/ruby25_parser.rb} +2349 -2337
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.13.0 → ruby_parser-3.13.1}/lib/ruby25_parser.y +32 -23
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.13.0 → ruby_parser-3.13.1}/lib/ruby26_parser.rb +2351 -2338
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.13.0 → ruby_parser-3.13.1}/lib/ruby26_parser.y +32 -23
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.13.0 → ruby_parser-3.13.1}/lib/ruby_lexer.rb +253 -161
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.13.0 → ruby_parser-3.13.1}/lib/ruby_lexer.rex +25 -25
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.13.0 → ruby_parser-3.13.1}/lib/ruby_lexer.rex.rb +68 -26
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.13.0 → ruby_parser-3.13.1}/lib/ruby_parser.rb +3 -1
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.13.0 → ruby_parser-3.13.1}/lib/ruby_parser.yy +34 -23
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.13.0 → ruby_parser-3.13.1}/lib/ruby_parser_extras.rb +64 -43
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.13.0 → ruby_parser-3.13.1}/tools/munge.rb +2 -1
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.13.0 → ruby_parser-3.13.1}/tools/ripper.rb +6 -1
- data/bundle/ruby/2.5.0/gems/{unicode-display_width-1.5.0 → unicode-display_width-1.6.0}/CHANGELOG.md +4 -0
- data/bundle/ruby/2.5.0/gems/{unicode-display_width-1.5.0 → unicode-display_width-1.6.0}/MIT-LICENSE.txt +0 -0
- data/bundle/ruby/2.5.0/gems/{unicode-display_width-1.5.0 → unicode-display_width-1.6.0}/README.md +1 -1
- data/bundle/ruby/2.5.0/gems/{unicode-display_width-1.5.0 → unicode-display_width-1.6.0}/data/display_width.marshal.gz +0 -0
- data/bundle/ruby/2.5.0/gems/{unicode-display_width-1.5.0 → unicode-display_width-1.6.0}/lib/unicode/display_width.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{unicode-display_width-1.5.0 → unicode-display_width-1.6.0}/lib/unicode/display_width/constants.rb +2 -2
- data/bundle/ruby/2.5.0/gems/{unicode-display_width-1.5.0 → unicode-display_width-1.6.0}/lib/unicode/display_width/index.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{unicode-display_width-1.5.0 → unicode-display_width-1.6.0}/lib/unicode/display_width/no_string_ext.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{unicode-display_width-1.5.0 → unicode-display_width-1.6.0}/lib/unicode/display_width/string_ext.rb +0 -0
- data/lib/brakeman.rb +7 -0
- data/lib/brakeman/app_tree.rb +34 -22
- data/lib/brakeman/checks.rb +7 -7
- data/lib/brakeman/checks/base_check.rb +9 -9
- data/lib/brakeman/checks/check_cross_site_scripting.rb +5 -0
- data/lib/brakeman/checks/check_default_routes.rb +5 -0
- data/lib/brakeman/checks/check_deserialize.rb +52 -0
- data/lib/brakeman/checks/check_dynamic_finders.rb +1 -1
- data/lib/brakeman/checks/check_force_ssl.rb +27 -0
- data/lib/brakeman/checks/check_json_parsing.rb +5 -0
- data/lib/brakeman/checks/check_link_to_href.rb +6 -1
- data/lib/brakeman/checks/check_mail_to.rb +1 -1
- data/lib/brakeman/checks/check_model_attr_accessible.rb +1 -1
- data/lib/brakeman/checks/check_model_attributes.rb +12 -50
- data/lib/brakeman/checks/check_model_serialize.rb +1 -1
- data/lib/brakeman/checks/check_nested_attributes_bypass.rb +3 -3
- data/lib/brakeman/checks/check_secrets.rb +1 -1
- data/lib/brakeman/checks/check_session_settings.rb +10 -10
- data/lib/brakeman/checks/check_simple_format.rb +5 -0
- data/lib/brakeman/checks/check_skip_before_filter.rb +1 -1
- data/lib/brakeman/checks/check_sql.rb +15 -17
- data/lib/brakeman/checks/check_validation_regex.rb +1 -1
- data/lib/brakeman/file_parser.rb +6 -8
- data/lib/brakeman/file_path.rb +71 -0
- data/lib/brakeman/options.rb +7 -0
- data/lib/brakeman/parsers/template_parser.rb +3 -3
- data/lib/brakeman/processor.rb +3 -4
- data/lib/brakeman/processors/alias_processor.rb +12 -6
- data/lib/brakeman/processors/base_processor.rb +8 -7
- data/lib/brakeman/processors/controller_alias_processor.rb +10 -7
- data/lib/brakeman/processors/controller_processor.rb +5 -9
- data/lib/brakeman/processors/haml_template_processor.rb +5 -0
- data/lib/brakeman/processors/lib/module_helper.rb +8 -8
- data/lib/brakeman/processors/lib/processor_helper.rb +3 -3
- data/lib/brakeman/processors/lib/rails2_config_processor.rb +3 -3
- data/lib/brakeman/processors/lib/rails2_route_processor.rb +2 -2
- data/lib/brakeman/processors/lib/rails3_config_processor.rb +3 -3
- data/lib/brakeman/processors/lib/rails3_route_processor.rb +2 -2
- data/lib/brakeman/processors/lib/render_helper.rb +2 -2
- data/lib/brakeman/processors/lib/render_path.rb +18 -1
- data/lib/brakeman/processors/library_processor.rb +5 -5
- data/lib/brakeman/processors/model_processor.rb +4 -5
- data/lib/brakeman/processors/output_processor.rb +5 -0
- data/lib/brakeman/processors/template_alias_processor.rb +4 -5
- data/lib/brakeman/processors/template_processor.rb +4 -4
- data/lib/brakeman/report.rb +3 -3
- data/lib/brakeman/report/ignore/config.rb +2 -3
- data/lib/brakeman/report/ignore/interactive.rb +2 -2
- data/lib/brakeman/report/pager.rb +1 -0
- data/lib/brakeman/report/report_base.rb +51 -6
- data/lib/brakeman/report/report_codeclimate.rb +3 -3
- data/lib/brakeman/report/report_hash.rb +1 -1
- data/lib/brakeman/report/report_html.rb +2 -2
- data/lib/brakeman/report/report_json.rb +1 -24
- data/lib/brakeman/report/report_table.rb +20 -4
- data/lib/brakeman/report/report_tabs.rb +1 -1
- data/lib/brakeman/report/report_text.rb +2 -2
- data/lib/brakeman/rescanner.rb +9 -12
- data/lib/brakeman/scanner.rb +19 -14
- data/lib/brakeman/tracker.rb +4 -4
- data/lib/brakeman/tracker/collection.rb +4 -3
- data/lib/brakeman/tracker/config.rb +6 -0
- data/lib/brakeman/util.rb +1 -147
- data/lib/brakeman/version.rb +1 -1
- data/lib/brakeman/warning.rb +23 -13
- data/lib/brakeman/warning_codes.rb +1 -0
- data/lib/ruby_parser/bm_sexp_processor.rb +1 -0
- metadata +78 -61
- data/bundle/ruby/2.5.0/gems/highline-1.7.10/Gemfile +0 -11
- data/bundle/ruby/2.5.0/gems/highline-1.7.10/INSTALL +0 -59
- data/bundle/ruby/2.5.0/gems/highline-1.7.10/README.rdoc +0 -74
- data/bundle/ruby/2.5.0/gems/highline-1.7.10/highline.gemspec +0 -37
- data/bundle/ruby/2.5.0/gems/highline-1.7.10/lib/highline.rb +0 -1048
- data/bundle/ruby/2.5.0/gems/highline-1.7.10/lib/highline/compatibility.rb +0 -16
- data/bundle/ruby/2.5.0/gems/highline-1.7.10/lib/highline/import.rb +0 -41
- data/bundle/ruby/2.5.0/gems/highline-1.7.10/lib/highline/menu.rb +0 -381
- data/bundle/ruby/2.5.0/gems/highline-1.7.10/lib/highline/simulate.rb +0 -48
- data/bundle/ruby/2.5.0/gems/highline-1.7.10/lib/highline/string_extensions.rb +0 -111
- data/bundle/ruby/2.5.0/gems/highline-1.7.10/lib/highline/style.rb +0 -192
- data/bundle/ruby/2.5.0/gems/highline-1.7.10/lib/highline/system_extensions.rb +0 -254
- data/bundle/ruby/2.5.0/gems/highline-1.7.10/setup.rb +0 -1360
File without changes
|
@@ -0,0 +1,37 @@
|
|
1
|
+
version: 2.0.{build}-{branch}
|
2
|
+
|
3
|
+
cache:
|
4
|
+
- vendor/bundle
|
5
|
+
|
6
|
+
environment:
|
7
|
+
matrix:
|
8
|
+
- RUBY_VERSION: "193"
|
9
|
+
- RUBY_VERSION: "200"
|
10
|
+
- RUBY_VERSION: "200-x64"
|
11
|
+
- RUBY_VERSION: "21"
|
12
|
+
- RUBY_VERSION: "21-x64"
|
13
|
+
- RUBY_VERSION: "22"
|
14
|
+
- RUBY_VERSION: "22-x64"
|
15
|
+
- RUBY_VERSION: "23"
|
16
|
+
- RUBY_VERSION: "23-x64"
|
17
|
+
- RUBY_VERSION: "24"
|
18
|
+
- RUBY_VERSION: "24-x64"
|
19
|
+
|
20
|
+
matrix:
|
21
|
+
allow_failures:
|
22
|
+
- RUBY_VERSION: "193"
|
23
|
+
|
24
|
+
install:
|
25
|
+
- set PATH=C:\Ruby%RUBY_VERSION%\bin;%PATH%
|
26
|
+
- bundle config --local path vendor/bundle
|
27
|
+
- bundle install --retry=3 --without code_quality
|
28
|
+
|
29
|
+
build: off
|
30
|
+
|
31
|
+
before_test:
|
32
|
+
- ruby -v
|
33
|
+
- gem -v
|
34
|
+
- bundle -v
|
35
|
+
|
36
|
+
test_script:
|
37
|
+
- bundle exec rake
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
lib = File.expand_path("../lib", __FILE__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
require "highline/version"
|
6
|
+
|
7
|
+
Gem::Specification.new do |spec|
|
8
|
+
spec.name = "highline"
|
9
|
+
spec.version = HighLine::VERSION
|
10
|
+
spec.author = "James Edward Gray II"
|
11
|
+
spec.email = "james@graysoftinc.com"
|
12
|
+
|
13
|
+
spec.summary = "HighLine is a high-level command-line IO library."
|
14
|
+
spec.description = <<DESCRIPTION
|
15
|
+
A high-level IO library that provides validation, type conversion, and more for
|
16
|
+
command-line interfaces. HighLine also includes a complete menu system that can
|
17
|
+
crank out anything from simple list selection to complete shells with just
|
18
|
+
minutes of work.
|
19
|
+
DESCRIPTION
|
20
|
+
spec.homepage = "https://github.com/JEG2/highline"
|
21
|
+
spec.license = "Ruby"
|
22
|
+
|
23
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
24
|
+
f.match(%r{^(test|spec|features)/})
|
25
|
+
end
|
26
|
+
spec.require_paths = ["lib"]
|
27
|
+
|
28
|
+
spec.extra_rdoc_files = %w[README.md TODO Changelog.md LICENSE]
|
29
|
+
|
30
|
+
spec.required_ruby_version = ">= 1.9.3"
|
31
|
+
|
32
|
+
spec.add_development_dependency "bundler"
|
33
|
+
spec.add_development_dependency "rake"
|
34
|
+
spec.add_development_dependency "minitest"
|
35
|
+
end
|
@@ -0,0 +1,650 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
#--
|
4
|
+
# highline.rb
|
5
|
+
#
|
6
|
+
# Created by James Edward Gray II on 2005-04-26.
|
7
|
+
# Copyright 2005 Gray Productions. All rights reserved.
|
8
|
+
#
|
9
|
+
# See HighLine for documentation.
|
10
|
+
#
|
11
|
+
# This is Free Software. See LICENSE and COPYING for details.
|
12
|
+
|
13
|
+
require "English"
|
14
|
+
require "erb"
|
15
|
+
require "optparse"
|
16
|
+
require "stringio"
|
17
|
+
require "abbrev"
|
18
|
+
require "highline/terminal"
|
19
|
+
require "highline/custom_errors"
|
20
|
+
require "highline/question"
|
21
|
+
require "highline/question_asker"
|
22
|
+
require "highline/menu"
|
23
|
+
require "highline/color_scheme"
|
24
|
+
require "highline/style"
|
25
|
+
require "highline/version"
|
26
|
+
require "highline/statement"
|
27
|
+
require "highline/list_renderer"
|
28
|
+
require "highline/builtin_styles"
|
29
|
+
|
30
|
+
#
|
31
|
+
# A HighLine object is a "high-level line oriented" shell over an input and an
|
32
|
+
# output stream. HighLine simplifies common console interaction, effectively
|
33
|
+
# replacing {Kernel#puts} and {Kernel#gets}. User code can simply specify the
|
34
|
+
# question to ask and any details about user interaction, then leave the rest
|
35
|
+
# of the work to HighLine. When {HighLine#ask} returns, you'll have the answer
|
36
|
+
# you requested, even if HighLine had to ask many times, validate results,
|
37
|
+
# perform range checking, convert types, etc.
|
38
|
+
#
|
39
|
+
# @example Basic usage
|
40
|
+
# cli = HighLine.new
|
41
|
+
# answer = cli.ask "What do you think?"
|
42
|
+
# puts "You have answered: #{answer}"
|
43
|
+
#
|
44
|
+
class HighLine
|
45
|
+
include BuiltinStyles
|
46
|
+
include CustomErrors
|
47
|
+
|
48
|
+
extend SingleForwardable
|
49
|
+
def_single_delegators :@default_instance, :agree, :ask, :choose, :say,
|
50
|
+
:use_color=, :use_color?, :reset_use_color,
|
51
|
+
:track_eof=, :track_eof?,
|
52
|
+
:color, :uncolor, :color_code
|
53
|
+
|
54
|
+
class << self
|
55
|
+
attr_accessor :default_instance
|
56
|
+
|
57
|
+
# Pass ColorScheme to set a HighLine color scheme.
|
58
|
+
attr_accessor :color_scheme
|
59
|
+
|
60
|
+
# Returns +true+ if HighLine is currently using a color scheme.
|
61
|
+
def using_color_scheme?
|
62
|
+
true if @color_scheme
|
63
|
+
end
|
64
|
+
|
65
|
+
# Reset color scheme to default (+nil+)
|
66
|
+
def reset_color_scheme
|
67
|
+
self.color_scheme = nil
|
68
|
+
end
|
69
|
+
|
70
|
+
# Reset HighLine to default.
|
71
|
+
# Clears Style index and resets color_scheme and use_color settings.
|
72
|
+
def reset
|
73
|
+
Style.clear_index
|
74
|
+
reset_color_scheme
|
75
|
+
reset_use_color
|
76
|
+
end
|
77
|
+
|
78
|
+
# For checking if the current version of HighLine supports RGB colors
|
79
|
+
# Usage: HighLine.supports_rgb_color? rescue false
|
80
|
+
# using rescue for compatibility with older versions
|
81
|
+
# Note: color usage also depends on HighLine.use_color being set
|
82
|
+
# TODO: Discuss removing this method
|
83
|
+
def supports_rgb_color?
|
84
|
+
true
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# The setting used to control color schemes.
|
89
|
+
@color_scheme = nil
|
90
|
+
|
91
|
+
#
|
92
|
+
# Create an instance of HighLine connected to the given _input_
|
93
|
+
# and _output_ streams.
|
94
|
+
#
|
95
|
+
# @param input [IO] the default input stream for HighLine.
|
96
|
+
# @param output [IO] the default output stream for HighLine.
|
97
|
+
# @param wrap_at [Integer] all statements outputed through
|
98
|
+
# HighLine will be wrapped to this column size if set.
|
99
|
+
# @param page_at [Integer] page size and paginating.
|
100
|
+
# @param indent_size [Integer] indentation size in spaces.
|
101
|
+
# @param indent_level [Integer] how deep is indentated.
|
102
|
+
def initialize(input = $stdin, output = $stdout,
|
103
|
+
wrap_at = nil, page_at = nil,
|
104
|
+
indent_size = 3, indent_level = 0)
|
105
|
+
@input = input
|
106
|
+
@output = output
|
107
|
+
|
108
|
+
@multi_indent = true
|
109
|
+
@indent_size = indent_size
|
110
|
+
@indent_level = indent_level
|
111
|
+
|
112
|
+
self.wrap_at = wrap_at
|
113
|
+
self.page_at = page_at
|
114
|
+
|
115
|
+
@header = nil
|
116
|
+
@prompt = nil
|
117
|
+
@key = nil
|
118
|
+
|
119
|
+
@use_color = default_use_color
|
120
|
+
@track_eof = true # The setting used to disable EOF tracking.
|
121
|
+
@terminal = HighLine::Terminal.get_terminal(input, output)
|
122
|
+
end
|
123
|
+
|
124
|
+
# Set it to false to disable ANSI coloring
|
125
|
+
attr_accessor :use_color
|
126
|
+
|
127
|
+
# Returns truethy if HighLine instance is currently using color escapes.
|
128
|
+
def use_color?
|
129
|
+
use_color
|
130
|
+
end
|
131
|
+
|
132
|
+
# Resets the use of color.
|
133
|
+
def reset_use_color
|
134
|
+
@use_color = true
|
135
|
+
end
|
136
|
+
|
137
|
+
# Pass +false+ to turn off HighLine's EOF tracking.
|
138
|
+
attr_accessor :track_eof
|
139
|
+
|
140
|
+
# Returns true if HighLine is currently tracking EOF for input.
|
141
|
+
def track_eof?
|
142
|
+
true if track_eof
|
143
|
+
end
|
144
|
+
|
145
|
+
# @return [Integer] The current column setting for wrapping output.
|
146
|
+
attr_reader :wrap_at
|
147
|
+
|
148
|
+
# @return [Integer] The current row setting for paging output.
|
149
|
+
attr_reader :page_at
|
150
|
+
|
151
|
+
# @return [Boolean] Indentation over multiple lines
|
152
|
+
attr_accessor :multi_indent
|
153
|
+
|
154
|
+
# @return [Integer] The indentation size in characters
|
155
|
+
attr_accessor :indent_size
|
156
|
+
|
157
|
+
# @return [Integer] The indentation level
|
158
|
+
attr_accessor :indent_level
|
159
|
+
|
160
|
+
# @return [IO] the default input stream for a HighLine instance
|
161
|
+
attr_reader :input
|
162
|
+
|
163
|
+
# @return [IO] the default output stream for a HighLine instance
|
164
|
+
attr_reader :output
|
165
|
+
|
166
|
+
# When gathering a Hash with {QuestionAsker#gather_hash},
|
167
|
+
# it tracks the current key being asked.
|
168
|
+
#
|
169
|
+
# @todo We should probably move this into the HighLine::Question
|
170
|
+
# object.
|
171
|
+
attr_accessor :key
|
172
|
+
|
173
|
+
# System specific that responds to #initialize_system_extensions,
|
174
|
+
# #terminal_size, #raw_no_echo_mode, #restore_mode, #get_character.
|
175
|
+
# It polymorphically handles specific cases for different platforms.
|
176
|
+
# @return [HighLine::Terminal]
|
177
|
+
attr_reader :terminal
|
178
|
+
|
179
|
+
#
|
180
|
+
# A shortcut to HighLine.ask() a question that only accepts "yes" or "no"
|
181
|
+
# answers ("y" and "n" are allowed) and returns +true+ or +false+
|
182
|
+
# (+true+ for "yes"). If provided a +true+ value, _character_ will cause
|
183
|
+
# HighLine to fetch a single character response. A block can be provided
|
184
|
+
# to further configure the question as in HighLine.ask()
|
185
|
+
#
|
186
|
+
# Raises EOFError if input is exhausted.
|
187
|
+
#
|
188
|
+
# @param yes_or_no_question [String] a question that accepts yes and no as
|
189
|
+
# answers
|
190
|
+
# @param character [Boolean, :getc] character mode to be passed to
|
191
|
+
# Question#character
|
192
|
+
# @see Question#character
|
193
|
+
def agree(yes_or_no_question, character = nil)
|
194
|
+
ask(yes_or_no_question, ->(yn) { yn.downcase[0] == "y" }) do |q|
|
195
|
+
q.validate = /\A(?:y(?:es)?|no?)\Z/i
|
196
|
+
q.responses[:not_valid] = 'Please enter "yes" or "no".'
|
197
|
+
q.responses[:ask_on_error] = :question
|
198
|
+
q.character = character
|
199
|
+
q.completion = %w[yes no]
|
200
|
+
|
201
|
+
yield q if block_given?
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
#
|
206
|
+
# This method is the primary interface for user input. Just provide a
|
207
|
+
# _question_ to ask the user, the _answer_type_ you want returned, and
|
208
|
+
# optionally a code block setting up details of how you want the question
|
209
|
+
# handled. See {#say} for details on the format of _question_, and
|
210
|
+
# {Question} for more information about _answer_type_ and what's
|
211
|
+
# valid in the code block.
|
212
|
+
#
|
213
|
+
# Raises EOFError if input is exhausted.
|
214
|
+
#
|
215
|
+
# @param (see Question.build)
|
216
|
+
# @return answer converted to the class in answer_type
|
217
|
+
def ask(template_or_question, answer_type = nil, &details)
|
218
|
+
question = Question.build(template_or_question, answer_type, &details)
|
219
|
+
|
220
|
+
if question.gather
|
221
|
+
QuestionAsker.new(question, self).gather_answers
|
222
|
+
else
|
223
|
+
QuestionAsker.new(question, self).ask_once
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
#
|
228
|
+
# This method is HighLine's menu handler. For simple usage, you can just
|
229
|
+
# pass all the menu items you wish to display. At that point, choose() will
|
230
|
+
# build and display a menu, walk the user through selection, and return
|
231
|
+
# their choice among the provided items. You might use this in a case
|
232
|
+
# statement for quick and dirty menus.
|
233
|
+
#
|
234
|
+
# However, choose() is capable of much more. If provided, a block will be
|
235
|
+
# passed a HighLine::Menu object to configure. Using this method, you can
|
236
|
+
# customize all the details of menu handling from index display, to building
|
237
|
+
# a complete shell-like menuing system. See HighLine::Menu for all the
|
238
|
+
# methods it responds to.
|
239
|
+
#
|
240
|
+
# Raises EOFError if input is exhausted.
|
241
|
+
#
|
242
|
+
# @param items [Array<String>]
|
243
|
+
# @param details [Proc] to be passed to Menu.new
|
244
|
+
# @return [String] answer
|
245
|
+
def choose(*items, &details)
|
246
|
+
menu = Menu.new(&details)
|
247
|
+
menu.choices(*items) unless items.empty?
|
248
|
+
|
249
|
+
# Set auto-completion
|
250
|
+
menu.completion = menu.options
|
251
|
+
|
252
|
+
# Set _answer_type_ so we can double as the Question for ask().
|
253
|
+
# menu.option = normal menu selection, by index or name
|
254
|
+
menu.answer_type = menu.shell ? shell_style_lambda(menu) : menu.options
|
255
|
+
|
256
|
+
selected = ask(menu)
|
257
|
+
return unless selected
|
258
|
+
|
259
|
+
if menu.shell
|
260
|
+
if menu.gather
|
261
|
+
selection = []
|
262
|
+
details = []
|
263
|
+
selected.each do |value|
|
264
|
+
selection << value[0]
|
265
|
+
details << value[1]
|
266
|
+
end
|
267
|
+
else
|
268
|
+
selection, details = selected
|
269
|
+
end
|
270
|
+
else
|
271
|
+
selection = selected
|
272
|
+
end
|
273
|
+
|
274
|
+
if menu.gather
|
275
|
+
menu.gather_selected(self, selection, details)
|
276
|
+
else
|
277
|
+
menu.select(self, selection, details)
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
281
|
+
# Convenience method to craft a lambda suitable for
|
282
|
+
# beind used in autocompletion operations by {#choose}
|
283
|
+
# @return [lambda] lambda to be used in autocompletion operations
|
284
|
+
|
285
|
+
def shell_style_lambda(menu)
|
286
|
+
lambda do |command| # shell-style selection
|
287
|
+
first_word = command.to_s.split.first || ""
|
288
|
+
|
289
|
+
options = menu.options
|
290
|
+
options.extend(OptionParser::Completion)
|
291
|
+
answer = options.complete(first_word)
|
292
|
+
|
293
|
+
raise Question::NoAutoCompleteMatch unless answer
|
294
|
+
|
295
|
+
[answer.last, command.sub(/^\s*#{first_word}\s*/, "")]
|
296
|
+
end
|
297
|
+
end
|
298
|
+
|
299
|
+
#
|
300
|
+
# This method provides easy access to ANSI color sequences, without the user
|
301
|
+
# needing to remember to CLEAR at the end of each sequence. Just pass the
|
302
|
+
# _string_ to color, followed by a list of _colors_ you would like it to be
|
303
|
+
# affected by. The _colors_ can be HighLine class constants, or symbols
|
304
|
+
# (:blue for BLUE, for example). A CLEAR will automatically be embedded to
|
305
|
+
# the end of the returned String.
|
306
|
+
#
|
307
|
+
# This method returns the original _string_ unchanged if use_color?
|
308
|
+
# is +false+.
|
309
|
+
#
|
310
|
+
# @param string [String] string to be colored
|
311
|
+
# @param colors [Array<Symbol>] array of colors like [:red, :blue]
|
312
|
+
# @return [String] (ANSI escaped) colored string
|
313
|
+
# @example
|
314
|
+
# cli = HighLine.new
|
315
|
+
# cli.color("Sustainable", :green, :bold)
|
316
|
+
# # => "\e[32m\e[1mSustainable\e[0m"
|
317
|
+
#
|
318
|
+
# # As class method (delegating to HighLine.default_instance)
|
319
|
+
# HighLine.color("Sustainable", :green, :bold)
|
320
|
+
#
|
321
|
+
def color(string, *colors)
|
322
|
+
return string unless use_color?
|
323
|
+
HighLine.Style(*colors).color(string)
|
324
|
+
end
|
325
|
+
|
326
|
+
# In case you just want the color code, without the embedding and
|
327
|
+
# the CLEAR sequence.
|
328
|
+
#
|
329
|
+
# @param colors [Array<Symbol>]
|
330
|
+
# @return [String] ANSI escape code for the given colors.
|
331
|
+
#
|
332
|
+
# @example
|
333
|
+
# s = HighLine.Style(:red, :blue)
|
334
|
+
# s.code # => "\e[31m\e[34m"
|
335
|
+
#
|
336
|
+
# HighLine.color_code(:red, :blue) # => "\e[31m\e[34m"
|
337
|
+
#
|
338
|
+
# cli = HighLine.new
|
339
|
+
# cli.color_code(:red, :blue) # => "\e[31m\e[34m"
|
340
|
+
#
|
341
|
+
def color_code(*colors)
|
342
|
+
HighLine.Style(*colors).code
|
343
|
+
end
|
344
|
+
|
345
|
+
# Remove color codes from a string.
|
346
|
+
# @param string [String] to be decolorized
|
347
|
+
# @return [String] without the ANSI escape sequence (colors)
|
348
|
+
def uncolor(string)
|
349
|
+
Style.uncolor(string)
|
350
|
+
end
|
351
|
+
|
352
|
+
# Renders a list of itens using a {ListRenderer}
|
353
|
+
# @param items [Array]
|
354
|
+
# @param mode [Symbol]
|
355
|
+
# @param option
|
356
|
+
# @return [String]
|
357
|
+
# @see ListRenderer#initialize ListRenderer#initialize for parameter details
|
358
|
+
def list(items, mode = :rows, option = nil)
|
359
|
+
ListRenderer.new(items, mode, option, self).render
|
360
|
+
end
|
361
|
+
|
362
|
+
#
|
363
|
+
# The basic output method for HighLine objects. If the provided _statement_
|
364
|
+
# ends with a space or tab character, a newline will not be appended (output
|
365
|
+
# will be flush()ed). All other cases are passed straight to Kernel.puts().
|
366
|
+
#
|
367
|
+
# The _statement_ argument is processed as an ERb template, supporting
|
368
|
+
# embedded Ruby code. The template is evaluated within a HighLine
|
369
|
+
# instance's binding for providing easy access to the ANSI color constants
|
370
|
+
# and the HighLine#color() method.
|
371
|
+
#
|
372
|
+
# @param statement [Statement, String] what to be said
|
373
|
+
def say(statement)
|
374
|
+
statement = render_statement(statement)
|
375
|
+
return if statement.empty?
|
376
|
+
|
377
|
+
statement = (indentation + statement)
|
378
|
+
|
379
|
+
# Don't add a newline if statement ends with whitespace, OR
|
380
|
+
# if statement ends with whitespace before a color escape code.
|
381
|
+
if /[ \t](\e\[\d+(;\d+)*m)?\Z/ =~ statement
|
382
|
+
output.print(statement)
|
383
|
+
output.flush
|
384
|
+
else
|
385
|
+
output.puts(statement)
|
386
|
+
end
|
387
|
+
end
|
388
|
+
|
389
|
+
# Renders a statement using {HighLine::Statement}
|
390
|
+
# @param statement [String] any string
|
391
|
+
# @return [Statement] rendered statement
|
392
|
+
def render_statement(statement)
|
393
|
+
Statement.new(statement, self).to_s
|
394
|
+
end
|
395
|
+
|
396
|
+
#
|
397
|
+
# Set to an integer value to cause HighLine to wrap output lines at the
|
398
|
+
# indicated character limit. When +nil+, the default, no wrapping occurs. If
|
399
|
+
# set to <tt>:auto</tt>, HighLine will attempt to determine the columns
|
400
|
+
# available for the <tt>@output</tt> or use a sensible default.
|
401
|
+
#
|
402
|
+
def wrap_at=(setting)
|
403
|
+
@wrap_at = setting == :auto ? output_cols : setting
|
404
|
+
end
|
405
|
+
|
406
|
+
#
|
407
|
+
# Set to an integer value to cause HighLine to page output lines over the
|
408
|
+
# indicated line limit. When +nil+, the default, no paging occurs. If
|
409
|
+
# set to <tt>:auto</tt>, HighLine will attempt to determine the rows available
|
410
|
+
# for the <tt>@output</tt> or use a sensible default.
|
411
|
+
#
|
412
|
+
def page_at=(setting)
|
413
|
+
@page_at = setting == :auto ? output_rows - 2 : setting
|
414
|
+
end
|
415
|
+
|
416
|
+
#
|
417
|
+
# Outputs indentation with current settings
|
418
|
+
#
|
419
|
+
def indentation
|
420
|
+
" " * @indent_size * @indent_level
|
421
|
+
end
|
422
|
+
|
423
|
+
#
|
424
|
+
# Executes block or outputs statement with indentation
|
425
|
+
#
|
426
|
+
# @param increase [Integer] how much to increase indentation
|
427
|
+
# @param statement [Statement, String] to be said
|
428
|
+
# @param multiline [Boolean]
|
429
|
+
# @return [void]
|
430
|
+
# @see #multi_indent
|
431
|
+
def indent(increase = 1, statement = nil, multiline = nil)
|
432
|
+
@indent_level += increase
|
433
|
+
multi = @multi_indent
|
434
|
+
@multi_indent ||= multiline
|
435
|
+
begin
|
436
|
+
if block_given?
|
437
|
+
yield self
|
438
|
+
else
|
439
|
+
say(statement)
|
440
|
+
end
|
441
|
+
ensure
|
442
|
+
@multi_indent = multi
|
443
|
+
@indent_level -= increase
|
444
|
+
end
|
445
|
+
end
|
446
|
+
|
447
|
+
#
|
448
|
+
# Outputs newline
|
449
|
+
#
|
450
|
+
def newline
|
451
|
+
@output.puts
|
452
|
+
end
|
453
|
+
|
454
|
+
#
|
455
|
+
# Returns the number of columns for the console, or a default it they cannot
|
456
|
+
# be determined.
|
457
|
+
#
|
458
|
+
def output_cols
|
459
|
+
return 80 unless @output.tty?
|
460
|
+
terminal.terminal_size.first
|
461
|
+
rescue NoMethodError
|
462
|
+
return 80
|
463
|
+
end
|
464
|
+
|
465
|
+
#
|
466
|
+
# Returns the number of rows for the console, or a default if they cannot be
|
467
|
+
# determined.
|
468
|
+
#
|
469
|
+
def output_rows
|
470
|
+
return 24 unless @output.tty?
|
471
|
+
terminal.terminal_size.last
|
472
|
+
rescue NoMethodError
|
473
|
+
return 24
|
474
|
+
end
|
475
|
+
|
476
|
+
# Call #puts on the HighLine's output stream
|
477
|
+
# @param args [String] same args for Kernel#puts
|
478
|
+
def puts(*args)
|
479
|
+
@output.puts(*args)
|
480
|
+
end
|
481
|
+
|
482
|
+
#
|
483
|
+
# Creates a new HighLine instance with the same options
|
484
|
+
#
|
485
|
+
def new_scope
|
486
|
+
self.class.new(@input, @output, @wrap_at,
|
487
|
+
@page_at, @indent_size, @indent_level)
|
488
|
+
end
|
489
|
+
|
490
|
+
private
|
491
|
+
|
492
|
+
# Adds a layer of scope (new_scope) to ask a question inside a
|
493
|
+
# question, without destroying instance data
|
494
|
+
def confirm(question)
|
495
|
+
new_scope.agree(question.confirm_question(self))
|
496
|
+
end
|
497
|
+
|
498
|
+
#
|
499
|
+
# A helper method used by HighLine::Question.verify_match
|
500
|
+
# for finding whether a list of answers match or differ
|
501
|
+
# from each other.
|
502
|
+
#
|
503
|
+
def unique_answers(list)
|
504
|
+
(list.respond_to?(:values) ? list.values : list).uniq
|
505
|
+
end
|
506
|
+
|
507
|
+
def last_answer(answers)
|
508
|
+
answers.respond_to?(:values) ? answers.values.last : answers.last
|
509
|
+
end
|
510
|
+
|
511
|
+
# Get response one line at time
|
512
|
+
# @param question [Question]
|
513
|
+
# @return [String] response
|
514
|
+
def get_response_line_mode(question)
|
515
|
+
if question.echo == true && !question.limit
|
516
|
+
get_line(question)
|
517
|
+
else
|
518
|
+
get_line_raw_no_echo_mode(question)
|
519
|
+
end
|
520
|
+
end
|
521
|
+
|
522
|
+
#
|
523
|
+
# Read a line of input from the input stream and process whitespace as
|
524
|
+
# requested by the Question object.
|
525
|
+
#
|
526
|
+
# If Question's _readline_ property is set, that library will be used to
|
527
|
+
# fetch input. *WARNING*: This ignores the currently set input stream.
|
528
|
+
#
|
529
|
+
# Raises EOFError if input is exhausted.
|
530
|
+
#
|
531
|
+
def get_line(question)
|
532
|
+
terminal.get_line(question, self)
|
533
|
+
end
|
534
|
+
|
535
|
+
def get_line_raw_no_echo_mode(question)
|
536
|
+
line = ""
|
537
|
+
|
538
|
+
terminal.raw_no_echo_mode_exec do
|
539
|
+
loop do
|
540
|
+
character = terminal.get_character
|
541
|
+
break unless character
|
542
|
+
break if ["\n", "\r"].include? character
|
543
|
+
|
544
|
+
# honor backspace and delete
|
545
|
+
if character == "\b" || character == "\u007F"
|
546
|
+
chopped = line.chop!
|
547
|
+
output_erase_char if chopped && question.echo
|
548
|
+
elsif character == "\e"
|
549
|
+
ignore_arrow_key
|
550
|
+
else
|
551
|
+
line << character
|
552
|
+
say_last_char_or_echo_char(line, question)
|
553
|
+
end
|
554
|
+
|
555
|
+
@output.flush
|
556
|
+
|
557
|
+
break if line_overflow_for_question?(line, question)
|
558
|
+
end
|
559
|
+
end
|
560
|
+
|
561
|
+
say_new_line_or_overwrite(question)
|
562
|
+
|
563
|
+
question.format_answer(line)
|
564
|
+
end
|
565
|
+
|
566
|
+
def say_new_line_or_overwrite(question)
|
567
|
+
if question.overwrite
|
568
|
+
@output.print("\r#{HighLine.Style(:erase_line).code}")
|
569
|
+
@output.flush
|
570
|
+
else
|
571
|
+
say("\n")
|
572
|
+
end
|
573
|
+
end
|
574
|
+
|
575
|
+
def ignore_arrow_key
|
576
|
+
2.times do
|
577
|
+
terminal.get_character
|
578
|
+
end
|
579
|
+
end
|
580
|
+
|
581
|
+
def say_last_char_or_echo_char(line, question)
|
582
|
+
@output.print(line[-1]) if question.echo == true
|
583
|
+
@output.print(question.echo) if question.echo && question.echo != true
|
584
|
+
end
|
585
|
+
|
586
|
+
def line_overflow_for_question?(line, question)
|
587
|
+
question.limit && line.size == question.limit
|
588
|
+
end
|
589
|
+
|
590
|
+
def output_erase_char
|
591
|
+
@output.print("\b#{HighLine.Style(:erase_char).code}")
|
592
|
+
end
|
593
|
+
|
594
|
+
# Get response using #getc
|
595
|
+
# @param question [Question]
|
596
|
+
# @return [String] response
|
597
|
+
def get_response_getc_mode(question)
|
598
|
+
terminal.raw_no_echo_mode_exec do
|
599
|
+
response = @input.getc
|
600
|
+
question.format_answer(response)
|
601
|
+
end
|
602
|
+
end
|
603
|
+
|
604
|
+
# Get response each character per turn
|
605
|
+
# @param question [Question]
|
606
|
+
# @return [String] response
|
607
|
+
def get_response_character_mode(question)
|
608
|
+
terminal.raw_no_echo_mode_exec do
|
609
|
+
response = terminal.get_character
|
610
|
+
if question.overwrite
|
611
|
+
erase_current_line
|
612
|
+
else
|
613
|
+
echo = question.get_echo_for_response(response)
|
614
|
+
say("#{echo}\n")
|
615
|
+
end
|
616
|
+
question.format_answer(response)
|
617
|
+
end
|
618
|
+
end
|
619
|
+
|
620
|
+
def erase_current_line
|
621
|
+
@output.print("\r#{HighLine.Style(:erase_line).code}")
|
622
|
+
@output.flush
|
623
|
+
end
|
624
|
+
|
625
|
+
public :get_response_character_mode, :get_response_line_mode
|
626
|
+
public :get_response_getc_mode
|
627
|
+
|
628
|
+
def actual_length(text)
|
629
|
+
Wrapper.actual_length text
|
630
|
+
end
|
631
|
+
|
632
|
+
# Check to see if there's already a HighLine.default_instance or if
|
633
|
+
# this is the first time the method is called (eg: at
|
634
|
+
# HighLine.default_instance initialization).
|
635
|
+
# If there's already one, copy use_color settings.
|
636
|
+
# This is here most to help migrate code from HighLine 1.7.x to 2.0.x
|
637
|
+
#
|
638
|
+
# @return [Boolean]
|
639
|
+
def default_use_color
|
640
|
+
if HighLine.default_instance
|
641
|
+
HighLine.default_instance.use_color
|
642
|
+
else
|
643
|
+
true
|
644
|
+
end
|
645
|
+
end
|
646
|
+
end
|
647
|
+
|
648
|
+
HighLine.default_instance = HighLine.new
|
649
|
+
|
650
|
+
require "highline/string"
|