drakkon 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +50 -0
  3. data/bin/drakkon +16 -0
  4. data/lib/drakkon/build.rb +126 -0
  5. data/lib/drakkon/cli.rb +64 -0
  6. data/lib/drakkon/gem/bundle.rb +116 -0
  7. data/lib/drakkon/gem/cli.rb +46 -0
  8. data/lib/drakkon/gem/configure.rb +73 -0
  9. data/lib/drakkon/gem/gem.rb +56 -0
  10. data/lib/drakkon/gem/helpers/check.rb +110 -0
  11. data/lib/drakkon/gem/helpers/files.rb +57 -0
  12. data/lib/drakkon/gem/helpers/general.rb +21 -0
  13. data/lib/drakkon/gem/helpers/modules.rb +51 -0
  14. data/lib/drakkon/gem/helpers/source.rb +43 -0
  15. data/lib/drakkon/gem/install.rb +24 -0
  16. data/lib/drakkon/init.rb +85 -0
  17. data/lib/drakkon/lib/hub.rb +112 -0
  18. data/lib/drakkon/lib/images/biggest.rb +43 -0
  19. data/lib/drakkon/lib/images/blur.rb +76 -0
  20. data/lib/drakkon/lib/images/bulk_rename.rb +86 -0
  21. data/lib/drakkon/lib/images/canvas.rb +74 -0
  22. data/lib/drakkon/lib/images/cli.rb +78 -0
  23. data/lib/drakkon/lib/images/desaturate.rb +58 -0
  24. data/lib/drakkon/lib/images/flip_flop.rb +76 -0
  25. data/lib/drakkon/lib/images/gif.rb +61 -0
  26. data/lib/drakkon/lib/images/index.rb +185 -0
  27. data/lib/drakkon/lib/images/list.rb +56 -0
  28. data/lib/drakkon/lib/images/modulate.rb +69 -0
  29. data/lib/drakkon/lib/images/resize.rb +83 -0
  30. data/lib/drakkon/lib/images/roll.rb +68 -0
  31. data/lib/drakkon/lib/images/rotate.rb +60 -0
  32. data/lib/drakkon/lib/images/scale.rb +86 -0
  33. data/lib/drakkon/lib/images/sepia.rb +64 -0
  34. data/lib/drakkon/lib/images/shift.rb +89 -0
  35. data/lib/drakkon/lib/images/split.rb +93 -0
  36. data/lib/drakkon/lib/images/spritesheet.rb +85 -0
  37. data/lib/drakkon/lib/images/trim.rb +56 -0
  38. data/lib/drakkon/lib/images/white.rb +56 -0
  39. data/lib/drakkon/lib/logbot.rb +86 -0
  40. data/lib/drakkon/lib/manifest.rb +74 -0
  41. data/lib/drakkon/lib/pastel.rb +49 -0
  42. data/lib/drakkon/lib/settings.rb +130 -0
  43. data/lib/drakkon/lib/shims.rb +8 -0
  44. data/lib/drakkon/lib/version.rb +79 -0
  45. data/lib/drakkon/release.rb +3 -0
  46. data/lib/drakkon/run/commands/images.rb +14 -0
  47. data/lib/drakkon/run/commands/log.rb +57 -0
  48. data/lib/drakkon/run/commands/restart.rb +14 -0
  49. data/lib/drakkon/run/helpers.rb +60 -0
  50. data/lib/drakkon/run/reader_shim.rb +110 -0
  51. data/lib/drakkon/run/tty.rb +119 -0
  52. data/lib/drakkon/run.rb +80 -0
  53. data/lib/drakkon/setup.rb +31 -0
  54. data/lib/drakkon/skeleton/cli.rb +46 -0
  55. data/lib/drakkon/skeleton/deploy.rb +105 -0
  56. data/lib/drakkon/skeleton/helpers/check.rb +143 -0
  57. data/lib/drakkon/skeleton/helpers/general.rb +21 -0
  58. data/lib/drakkon/skeleton/helpers/source.rb +43 -0
  59. data/lib/drakkon/skeleton/install.rb +31 -0
  60. data/lib/drakkon/skeleton/template.rb +14 -0
  61. data/lib/drakkon/web.rb +68 -0
  62. data/lib/drakkon.rb +43 -0
  63. metadata +302 -0
@@ -0,0 +1,86 @@
1
+ # Log Helper
2
+ module LogBot
3
+ # For Amazing Print
4
+ def self.settings
5
+ { ruby19_syntax: true, multiline: false }
6
+ end
7
+
8
+ def self.output(name, message, level, duration = nil)
9
+ time = Time.now.strftime('%I:%M:%S').pastel(:bright_black)
10
+ output = time
11
+ output += " #{color_level(level)}"
12
+ output += " - #{name.to_s.pastel(:bright_blue)} "
13
+ output += "(#{duration.round(2)}) ".pastel(:magenta) if duration
14
+
15
+ output += ' '
16
+ if message
17
+ output += case message
18
+ when String then message
19
+ else
20
+ message.ai(settings)
21
+ end
22
+ end
23
+
24
+ puts output unless ENV['TESTING']
25
+ end
26
+
27
+ def self.color_level(level)
28
+ case level
29
+ when :debug
30
+ level.to_s.upcase.pastel(:bright_cyan)
31
+ when :info
32
+ level.to_s.upcase.pastel(:cyan)
33
+ when :warn
34
+ level.to_s.upcase.pastel(:yellow)
35
+ when :error
36
+ level.to_s.upcase.pastel(:bright_red)
37
+ when :fatal
38
+ level.to_s.upcase.pastel(:red)
39
+ end
40
+ end
41
+
42
+ def self.info(name, message = nil, level = :info)
43
+ output(name, message, level)
44
+ end
45
+
46
+ def self.debug(name, message = nil, level = :debug)
47
+ output(name, message, level)
48
+ end
49
+
50
+ def self.warn(name, message = nil, level = :warn)
51
+ output(name, message, level)
52
+ end
53
+
54
+ def self.error(name, message = nil, level = :error)
55
+ output(name, message, level)
56
+ end
57
+
58
+ def self.fatal(name, message = nil, level = :fatal)
59
+ output(name, message, level)
60
+ end
61
+
62
+ def self.do(name, message = nil, level = nil)
63
+ began_at = clock_time
64
+
65
+ level ||= :info
66
+ result = yield
67
+
68
+ duration = (clock_time - began_at).round(3)
69
+
70
+ output(name, message, level, duration)
71
+
72
+ result
73
+ end
74
+
75
+ def self.measure
76
+ began_at = clock_time
77
+ result = yield
78
+ duration = (clock_time - began_at).round(3)
79
+ [result, duration]
80
+ end
81
+
82
+ # From Rack Time
83
+ def self.clock_time
84
+ Process.clock_gettime(Process::CLOCK_MONOTONIC)
85
+ end
86
+ end
@@ -0,0 +1,74 @@
1
+ # ======================
2
+ # Debug Helpers
3
+ # ======================
4
+ # Manifest.list
5
+ # Manifest.search('app')
6
+ # ======================
7
+
8
+ module Drakkon
9
+ # Helper to Generate Manifest
10
+ module Manifest
11
+ def self.root_directory
12
+ "#{Dir.pwd}/"
13
+ end
14
+
15
+ def self.run!(force: false)
16
+ list
17
+ search("#{Dir.pwd}/app")
18
+
19
+ # No Dupes please
20
+ list.reject! { |x| x.include? 'app/drakkon/manifest.rb' }
21
+
22
+ list.map! do |file|
23
+ file.gsub(root_directory, '')
24
+ end
25
+
26
+ if Settings.config[:manifest_digest] == digest
27
+ LogBot.info('Manifest', 'Nothing New')
28
+ return unless force
29
+ end
30
+
31
+ Settings.update(:manifest_digest, digest)
32
+
33
+ LogBot.info('Manifest', 'Saved!')
34
+
35
+ # Make Directory `app/drakkon` if it doesn't exist
36
+ FileUtils.mkdir_p('app/drakkon') unless File.directory?('app/drakkon')
37
+
38
+ File.write('app/drakkon/manifest.rb', required)
39
+ end
40
+
41
+ def self.digest
42
+ Digest::MD5.hexdigest(list.map { |x| Digest::MD5.file(x).hexdigest }.join)
43
+ end
44
+
45
+ def self.list
46
+ @list ||= []
47
+
48
+ @list
49
+ end
50
+
51
+ def self.search(dir)
52
+ @list.concat Dir["#{dir}/*.rb"]
53
+
54
+ Dir["#{dir}/*"].each do |file|
55
+ next unless File.directory?(file)
56
+
57
+ Manifest.search(file)
58
+ end
59
+ end
60
+
61
+ # Generate Require Statements
62
+ # Sure there gonna be plenty of opinions on this bad boi
63
+ def self.required
64
+ <<~TEMPLATE
65
+ #{Manifest.list.reverse.inspect}.each do |file|
66
+ require file
67
+ end
68
+ TEMPLATE
69
+ end
70
+
71
+ # ----------------------
72
+ end
73
+ # ----------------------
74
+ end
@@ -0,0 +1,49 @@
1
+ # Top level namespace
2
+ module Drakkon
3
+ # Replace Colorize with Pastel Monkey Patch String Shim
4
+ # https://github.com/piotrmurach/pastel#features
5
+
6
+ # Looping in GreenHat to allow disabling of Color
7
+ module Color
8
+ def self.pastel
9
+ @pastel ||= Pastel.new
10
+ end
11
+
12
+ def self.decorate(args)
13
+ pastel.decorate(*args)
14
+ end
15
+ end
16
+ end
17
+
18
+ # Monkey Patch
19
+ class String
20
+ def pastel(*args)
21
+ Drakkon::Color.decorate(args.unshift(self))
22
+ end
23
+
24
+ def unpastel
25
+ Drakkon::Color.pastel.strip self
26
+ end
27
+
28
+ def snake_case
29
+ return downcase if match(/\A[A-Z]+\z/)
30
+
31
+ gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
32
+ .gsub(/([a-z])([A-Z])/, '\1_\2')
33
+ .downcase
34
+ end
35
+ end
36
+
37
+ # Monkey Patch
38
+ class Symbol
39
+ def pastel(*args)
40
+ Drakkon::Color.decorate(args.unshift(to_s))
41
+ end
42
+ end
43
+
44
+ # Monkey Patch
45
+ class Array
46
+ def pastel(*args)
47
+ Drakkon::Color.decorate(args.unshift(to_s))
48
+ end
49
+ end
@@ -0,0 +1,130 @@
1
+ module Drakkon
2
+ # Project Specific Config Settings
3
+ module Settings
4
+ def self.init?
5
+ if File.directory?(config_file)
6
+ LogBot.fatal('Settings', "Conflicting Config / Directory #{config_file}")
7
+ exit 0
8
+ end
9
+
10
+ File.exist?(config_file)
11
+ end
12
+
13
+ # Helper to exit if project isn't ready for drakkon usage
14
+ def self.ready?
15
+ return if init?
16
+
17
+ LogBot.warn('Setup', "Drakkon not configured. Run #{'init'.pastel(:green)} first")
18
+
19
+ exit 1
20
+ end
21
+
22
+ def self.prompt
23
+ TTY::Prompt.new(active_color: :cyan)
24
+ end
25
+
26
+ def self.version
27
+ config.version
28
+ end
29
+
30
+ def self.gems
31
+ config[:gems]
32
+ end
33
+
34
+ def self.platforms?
35
+ !config[:platforms].empty?
36
+ end
37
+
38
+ def self.platforms
39
+ config[:platforms]
40
+ end
41
+
42
+ def self.app_dir
43
+ "#{Dir.pwd}/app"
44
+ end
45
+
46
+ def self.drakkon_dir
47
+ "#{Dir.pwd}/app/drakkon"
48
+ end
49
+
50
+ def self.image_index?
51
+ config[:image_index]
52
+ end
53
+
54
+ def self.manifest?
55
+ config[:manifest]
56
+ end
57
+
58
+ def self.config_file
59
+ "#{Dir.pwd}/.drakkon"
60
+ end
61
+
62
+ def self.config_defaults
63
+ # Defaults
64
+ @config[:platforms] ||= []
65
+ @config[:version] ||= Hub.version_latest
66
+ @config[:image_index] ||= true
67
+ @config[:manifest] ||= true
68
+ @config[:gems] ||= {}
69
+ end
70
+
71
+ def self.config
72
+ # Write Default
73
+ File.write(config_file, JSON.pretty_generate({})) unless File.exist?(config_file)
74
+
75
+ if @config.nil?
76
+ @config ||= JSON.parse(File.read(config_file), { symbolize_names: true })
77
+ # @config ||= Oj.load File.read(config_file)
78
+ config_defaults
79
+ end
80
+
81
+ @config
82
+ end
83
+
84
+ def self.update(key, value)
85
+ config[key] = value
86
+ write
87
+ end
88
+
89
+ def self.delete(key)
90
+ config.delete key
91
+ write
92
+ end
93
+
94
+ def self.write
95
+ # LogBot.debug('Settings', "Writing Config: #{config_file}")
96
+ File.write(config_file, JSON.pretty_generate(config))
97
+ # File.write(config_file, Oj.dump(config))
98
+ end
99
+
100
+ def self.menu
101
+ prompt.select('Change Settings:', filter: true) do |menu|
102
+ menu.choice name: 'platforms', value: :platforms
103
+ menu.choice name: 'version', value: :version
104
+ menu.choice name: 'image_index', value: :image_index
105
+ menu.choice name: 'manifest', value: :manifest
106
+ menu.choice name: 'exit', value: :exit
107
+ end
108
+ rescue TTY::Reader::InputInterrupt
109
+ exit 0
110
+ end
111
+
112
+ def self.menu_do(arg)
113
+ case arg
114
+ when :platforms
115
+ Settings.update(:platforms, Build.platform_setup)
116
+ when :version
117
+ Version.set
118
+ when :image_index
119
+ Settings.update(:image_index, prompt.yes?("Index Images? (Enabled: #{image_index?})"))
120
+ when :manifest
121
+ Settings.update(:image_index, prompt.yes?("Write Manifest? (Enabled: #{manifest?})"))
122
+ when :exit
123
+ exit 0
124
+ end
125
+ end
126
+
127
+ # ======================================================================
128
+ end
129
+ # ======================================================================
130
+ end
@@ -0,0 +1,8 @@
1
+ # Make it easier to check for animations
2
+ class String
3
+ def numeric?
4
+ !Float(self).nil?
5
+ rescue StandardError
6
+ false
7
+ end
8
+ end
@@ -0,0 +1,79 @@
1
+ module Drakkon
2
+ # Run Command for CLI
3
+ module Version
4
+ def self.args(raw = nil)
5
+ @args ||= raw
6
+
7
+ @args
8
+ end
9
+
10
+ def self.list
11
+ LogBot.info('Versions', Hub.versions.join(', '))
12
+ end
13
+
14
+ def self.set
15
+ current = "(Current: #{Settings.version.pastel(:bright_blue)})"
16
+ version = prompt.select("Select version #{current}", Hub.versions_sorted, filter: true)
17
+
18
+ Settings.update(:version, version)
19
+ end
20
+
21
+ # General Run
22
+ def self.install!(raw)
23
+ zip = raw.first
24
+ if File.extname(zip) != '.zip'
25
+ LogBot.fatal('Version', "Invalid Argument! Must be a zip file! '#{zip}'")
26
+ exit(1)
27
+ end
28
+
29
+ Dir.mktmpdir('drakkon-sauce-') do |tmp|
30
+ # full_path = "#{Dir.pwd}/#{zip}"
31
+
32
+ # Execut Unzip / Better Way to do this?
33
+ system("unzip -q -d #{tmp} #{zip}")
34
+
35
+ # Find Dir
36
+ dr_dir = Dir["#{tmp}/*"].first
37
+ unless dr_dir.include?('dragonruby-')
38
+ LogBot.fatal('Version', "Valid Zip? Not finding DragonRuby Directory, #{dr_dir}")
39
+ exit(2)
40
+ end
41
+
42
+ # Find Version
43
+ unless File.exist?("#{dr_dir}/CHANGELOG-CURR.txt")
44
+ LogBot.fatal('Version', "Version File Missing! #{"#{dr_dir}/CHANGELOG-CURR.txt"}")
45
+ exit(2)
46
+ end
47
+
48
+ # Collect Version
49
+ dr_version = File.open("#{dr_dir}/CHANGELOG-CURR.txt", &:readline)&.chomp&.split(' ', 2)&.last
50
+ if dr_version.nil?
51
+ LogBot.fatal('Version', "Unable to find DragonRuby Version!, #{dr_version}")
52
+ exit(2)
53
+ end
54
+
55
+ # TODO: add overwrite
56
+ if Hub.version?(dr_version)
57
+ LogBot.fatal('Version', "Version already exists!, #{dr_version}")
58
+ exit(3)
59
+ end
60
+
61
+ # Copy
62
+ FileUtils.cp_r(dr_dir, "#{Hub.dir}/#{dr_version}/")
63
+
64
+ # Save
65
+ Hub.version_add(dr_version)
66
+
67
+ # Finish
68
+ LogBot.info('Version', "#{dr_version} Installed!")
69
+ end
70
+ end
71
+
72
+ def self.prompt
73
+ TTY::Prompt.new(active_color: :cyan)
74
+ end
75
+
76
+ #=======================================================
77
+ end
78
+ #=======================================================
79
+ end
@@ -0,0 +1,3 @@
1
+ module Drakkon
2
+ VERSION = '0.0.3'.freeze
3
+ end
@@ -0,0 +1,14 @@
1
+ module Drakkon
2
+ # Run Command for CLI
3
+ module Run
4
+ # Runnable Terminal Commands
5
+ module Commands
6
+ def self.cmd_images(_args)
7
+ Images::Index.run!(force: true, dir: Run.context)
8
+ end
9
+
10
+ # ========================================================================
11
+ end
12
+ # ==========================================================================
13
+ end
14
+ end
@@ -0,0 +1,57 @@
1
+ module Drakkon
2
+ # Run Command for CLI
3
+ module Run
4
+ # Runnable Terminal Commands
5
+ module Commands
6
+ def self.cmd_logs(_args)
7
+ TTY::Pager.page(command: 'less +G') do |pager|
8
+ Run.logs.each do |line|
9
+ pager.write line
10
+ end
11
+ end
12
+ end
13
+
14
+ def self.cmd_tail(_args)
15
+ loop do
16
+ if Run.dragonruby.ready?
17
+ $stdin.cooked!
18
+ line = Run.dragonruby.readline
19
+ Run.logs.push line # Store
20
+ puts line
21
+ elsif key_pressed?
22
+ key = $stdin.readchar
23
+ if key.ord >= 32 && key.ord <= 126
24
+ break
25
+ else
26
+ break if key == "\u0003" # 'CTRL C'
27
+ break if key == "\u0004" # 'CTRL D'
28
+
29
+ $stdin.cooked!
30
+ puts "any key to stop following: #{key.inspect}".pastel(:green)
31
+ end
32
+
33
+ else
34
+ $stdin.raw!
35
+ sleep 0.1
36
+ end
37
+ end
38
+
39
+ # Restore the previous raw mode
40
+ $stdin.cooked!
41
+ rescue EOFError
42
+ :ignore
43
+ end
44
+
45
+ def self.key_pressed?
46
+ # Set raw mode to ensure immediate input
47
+ $stdin.raw(&:ready?)
48
+ ensure
49
+ # Restore the previous raw mode
50
+ $stdin.cooked!
51
+ end
52
+
53
+ # ========================================================================
54
+ end
55
+ # ==========================================================================
56
+ end
57
+ end
@@ -0,0 +1,14 @@
1
+ module Drakkon
2
+ # Run Command for CLI
3
+ module Run
4
+ # Runnable Terminal Commands
5
+ module Commands
6
+ def self.cmd_restart(_args)
7
+ Run.restart
8
+ end
9
+
10
+ # ========================================================================
11
+ end
12
+ # ==========================================================================
13
+ end
14
+ end
@@ -0,0 +1,60 @@
1
+ module Drakkon
2
+ # Run Command for CLI
3
+ module Run
4
+ def self.index
5
+ @index ||= build_index
6
+ @index
7
+ end
8
+
9
+ def self.build_index
10
+ Commands.public_methods.select { |x| x.to_s[0..3] == 'cmd_' }.map do |cmd|
11
+ cmd.to_s.gsub('cmd_', '')
12
+ end
13
+ end
14
+
15
+ def self.readline_notch
16
+ "#{'drakkon'.pastel(:bright_black)} » "
17
+ end
18
+
19
+ # Exec skips the weird shell stuff
20
+ def self.run_cmd
21
+ "PATH=#{version_dir}:$PATH exec dragonruby #{@context}"
22
+ # "PATH=#{version_dir}:$PATH exec dragonruby #{@context} > #{log_file}"
23
+ end
24
+
25
+ def self.log_file
26
+ "#{Hub.dir}/log.txt"
27
+ end
28
+
29
+ def self.dragonruby(value = nil)
30
+ @dragonruby ||= value
31
+
32
+ @dragonruby
33
+ end
34
+
35
+ def self.args(raw = [])
36
+ @args ||= raw
37
+
38
+ @args
39
+ end
40
+
41
+ def self.version_dir
42
+ "#{Hub.dir}/#{Settings.version}"
43
+ end
44
+
45
+ def self.force_images?
46
+ args.include?('images')
47
+ end
48
+
49
+ def self.force_manifest?
50
+ args.include?('manifest')
51
+ end
52
+
53
+ def self.prompt
54
+ TTY::Prompt.new(active_color: :cyan)
55
+ end
56
+
57
+ #=======================================================
58
+ end
59
+ #=======================================================
60
+ end
@@ -0,0 +1,110 @@
1
+ # frozen_string_literal: true
2
+
3
+ # https :/ / github.com / piotrmurach / tty - reader / blob / master / lib / tty / reader.rb
4
+
5
+ # Disabling Since this is a Shim
6
+ # rubocop:disable all
7
+
8
+ module TTY
9
+ # A class responsible for reading character input from STDIN
10
+ #
11
+ # Used internally to provide key and line reading functionality
12
+ #
13
+ # @api public
14
+ class Reader
15
+ attr_accessor :line, :breaker
16
+
17
+ def read_line(prompt = '', value: '', echo: true, raw: true, nonblock: false)
18
+ # Greenhat Shim:: Store Line
19
+ self.breaker = false
20
+ self.line = Line.new(value, prompt: prompt)
21
+ screen_width = TTY::Screen.width
22
+ buffer = ''
23
+
24
+ output.print(line)
25
+
26
+ while (codes = get_codes(echo: echo, raw: raw, nonblock: nonblock)) &&
27
+ (code = codes[0])
28
+ char = codes.pack('U*')
29
+
30
+ # GreenHat Shim / Back Tab Down Submodule
31
+ if [:back_tab, :ctrl_c].include? console.keys[char]
32
+ clear_display(line, screen_width)
33
+ trigger_key_event(char, line: line.to_s)
34
+ break
35
+ end
36
+
37
+ # Greenhat Shim
38
+ if EXIT_KEYS.include?(console.keys[char])
39
+ trigger_key_event(char, line: line.to_s)
40
+ raise Interrupt
41
+ end
42
+
43
+ clear_display(line, screen_width) if raw && echo
44
+
45
+ if console.keys[char] == :backspace || code == BACKSPACE
46
+ unless line.start?
47
+ line.left
48
+ line.delete
49
+ end
50
+ elsif console.keys[char] == :delete || code == DELETE
51
+ line.delete
52
+ elsif console.keys[char].to_s =~ /ctrl_/
53
+ # skip
54
+ elsif console.keys[char] == :up
55
+ line.replace(history_previous) if history_previous?
56
+ elsif console.keys[char] == :down
57
+ line.replace(history_next? ? history_next : buffer) if track_history?
58
+ elsif console.keys[char] == :left
59
+ line.left
60
+ elsif console.keys[char] == :right
61
+ line.right
62
+ elsif console.keys[char] == :home
63
+ line.move_to_start
64
+ elsif console.keys[char] == :end
65
+ line.move_to_end
66
+ else
67
+ if raw && [CARRIAGE_RETURN, NEWLINE].include?(code)
68
+ char = "\n"
69
+ line.move_to_end
70
+ end
71
+ line.insert(char)
72
+ buffer = line.text
73
+ end
74
+
75
+ if (console.keys[char] == :backspace || code == BACKSPACE) && echo
76
+ if raw
77
+ output.print("\e[1X") unless line.start?
78
+ else
79
+ output.print("\s" + (line.start? ? '' : "\b"))
80
+ end
81
+ end
82
+
83
+ # trigger before line is printed to allow for line changes
84
+ trigger_key_event(char, line: line.to_s)
85
+
86
+ if raw && echo
87
+ output.print(line.to_s)
88
+ if char == "\n"
89
+ line.move_to_start
90
+ elsif !line.end? # readjust cursor position
91
+ output.print(cursor.backward(line.text_size - line.cursor))
92
+ end
93
+ end
94
+
95
+ # Greenhat Shim do things
96
+ next unless [CARRIAGE_RETURN, NEWLINE].include?(code) || breaker
97
+
98
+ buffer = ''
99
+ output.puts unless echo
100
+ break
101
+ end
102
+
103
+ add_to_history(line.text.rstrip) if track_history? && echo
104
+
105
+ line.text
106
+ end
107
+ end
108
+ end
109
+
110
+ # rubocop:enable all