terminal 0.0.1.alpha → 0.0.1.alpha.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5bfa777b9424757d7607650d21662d2a97986253
4
- data.tar.gz: ef1d951d1e07c1feda0ffa1d8992cf56eea77460
3
+ metadata.gz: 487092c63dea202f02bd076d7e4158eea89bd58a
4
+ data.tar.gz: 6199129f8e34c4216edb4300334305e9b3846deb
5
5
  SHA512:
6
- metadata.gz: 1d336c6efb98167cfeb871a32b219abeaf6299cdf21782d42e83fa861fb73fb36eceec9da4644a48078917d0cec364002b1c043eddaa4cbb5d1aaa98d87d3c0e
7
- data.tar.gz: 29439ee72bea5d033cd551551e4b71caad28ce69c800a7e41e4f8252beac2eba836574c28143064b84750816ee2c9e04fac466eb7409f27753e7dfdd1929a2e3
6
+ metadata.gz: db1e32fcb67aa51ffaa827864a0bbabb2d1bbd96853df00e4b8696fa1ea7d2c5f27f4d7a0015140524e2912dbfbf1fcca3a6493191cb7631cd3930cb67fc8200
7
+ data.tar.gz: fcdda1990aec64e1bbd7795f2f10b7fe133abeeb754782b85a9041b8e0823ecab7bbee44d27b7e9f6f938e5ebfbab50903ccaa0106688059e329fca8446e1f43
data/Rakefile CHANGED
@@ -1,2 +1,8 @@
1
1
  require "bundler/gem_tasks"
2
+ require 'rspec/core/rake_task'
2
3
 
4
+ RSpec::Core::RakeTask.new('spec') do |t|
5
+ t.verbose = false
6
+ end
7
+
8
+ task :default => :spec
@@ -0,0 +1,94 @@
1
+ ![logo](http://buildboxhq.github.io/terminal/images/logo.png)
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/terminal.png)](https://rubygems.org/gems/terminal)
4
+
5
+ Terminal takes any arbitrary crazy shell output (ASCII), and turns it into beautifully rendered HTML.
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'terminal'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ ```bash
18
+ $ bundle
19
+ ```
20
+
21
+ Or install it yourself as:
22
+
23
+ ```bash
24
+ gem install terminal
25
+ ```
26
+
27
+ ## Usage
28
+
29
+ ```ruby
30
+ Terminal.render("...")
31
+ ```
32
+
33
+ ### Command Line
34
+
35
+ Terminal ships with a command line utility. For example, you can pipe `rspec` output to it:
36
+
37
+ ```bash
38
+ rspec --color --tty | terminal
39
+ ```
40
+
41
+ Or use output saved earlier:
42
+
43
+ ```bash
44
+ rspec --tty --color > output.txt
45
+ terminal output.txt
46
+ ```
47
+
48
+ With `rspec`, you'll need to use the `--tty` and `--color` options to force it to output colors.
49
+
50
+ ### With the Buildbox API
51
+
52
+ First install [jq](http://stedolan.github.io/jq/), if you have [Homebrew](http://brew.sh/) installed, you can just `brew install jq`.
53
+
54
+ Then, you can:
55
+
56
+ ```bash
57
+ $JOB_LOG_URL="https://api.buildbox.io/v1/accounts/[account]/projects/[project]/builds/[build]/jobs/[job]/log?api_key=[api-key]"
58
+ echo $(curl $JOB_LOG_URL -s | jq '.content') | terminal
59
+ ```
60
+
61
+ For more information on the Buildbox Builds API, see: https://buildbox.io/docs/api/builds
62
+
63
+ ## Contributing
64
+
65
+ 1. Fork it ( https://github.com/[my-github-username]/terminal/fork )
66
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
67
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
68
+ 4. Push to the branch (`git push origin my-new-feature`)
69
+ 5. Create a new Pull Request
70
+
71
+ ## Licence
72
+
73
+ > Copyright (c) 2014 Keith Pitt, Buildbox
74
+ >
75
+ > MIT License
76
+ >
77
+ > Permission is hereby granted, free of charge, to any person obtaining
78
+ > a copy of this software and associated documentation files (the
79
+ > "Software"), to deal in the Software without restriction, including
80
+ > without limitation the rights to use, copy, modify, merge, publish,
81
+ > distribute, sublicense, and/or sell copies of the Software, and to
82
+ > permit persons to whom the Software is furnished to do so, subject to
83
+ > the following conditions:
84
+ >
85
+ > The above copyright notice and this permission notice shall be
86
+ > included in all copies or substantial portions of the Software.
87
+ >
88
+ > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
89
+ > EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
90
+ > MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
91
+ > NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
92
+ > LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
93
+ > OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
94
+ > WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift(File.join(File.expand_path(File.dirname(__FILE__)), '..', 'lib'))
4
+
5
+ require 'terminal'
6
+
7
+ def help
8
+ puts <<-usage
9
+ Usage:
10
+ $ cat output.text | terminal
11
+ $ terminal output.text
12
+
13
+ Help:
14
+ $ terminal -h
15
+
16
+ See https://buildboxhq.github.io/terminal for more information.
17
+ usage
18
+ end
19
+
20
+ if ($stdin.tty? && ARGV.empty?) || ARGV.delete('-h') || ARGV.delete('--help')
21
+ help
22
+ else
23
+ puts Terminal.render(ARGF.read)
24
+ end
@@ -1,5 +1,12 @@
1
1
  require "terminal/version"
2
+ require "terminal/node"
3
+ require "terminal/color"
4
+ require "terminal/reset"
5
+ require "terminal/renderer"
6
+ require "terminal/cli"
2
7
 
3
8
  module Terminal
4
- # Your code goes here...
9
+ def self.render(output)
10
+ Terminal::Renderer.new.render(output)
11
+ end
5
12
  end
@@ -0,0 +1,16 @@
1
+ module Terminal
2
+ class CLI
3
+ def self.run(*args, file)
4
+ new(args, file).run
5
+ end
6
+
7
+ def initialize(args, file)
8
+ @args = args
9
+ @file = file
10
+ end
11
+
12
+ def run
13
+ puts @file
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,7 @@
1
+ module Terminal
2
+ class Color < Terminal::Node
3
+ def to_debug
4
+ "[color:#{@code}]"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,15 @@
1
+ module Terminal
2
+ class Node
3
+ def initialize(code)
4
+ @code = code
5
+ end
6
+
7
+ def to_s
8
+ "\e[#{@code}m"
9
+ end
10
+
11
+ def to_debug
12
+ "[node:#{@code}]"
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,169 @@
1
+ require 'escape_utils'
2
+
3
+ module Terminal
4
+ class Renderer
5
+ def render(output)
6
+ return "" if output.nil? || output.strip.length == 0
7
+
8
+ # Limit the entire size of the output to 4 meg (4 * megabyte * kilabyte)
9
+ max_total_size = 4 * 1024 * 1024
10
+ if output.bytesize > max_total_size
11
+ output = output.byteslice(0, max_total_size)
12
+ output << "\n\nWarning: Terminal has chopped off the rest of the build as it's over the allowed #{number_to_human_size(max_total_size)} limit for logs."
13
+ end
14
+
15
+ # Limit each line to (x) chars
16
+ max_line_length = 50_000
17
+ output = output.split("\n").map do |line|
18
+ if line.length > max_line_length
19
+ line = line[0..max_line_length]
20
+ line << " Warning: Terminal has chopped the rest of this line off as it's over the allowed #{max_line_length} characters per line limit."
21
+ else
22
+ line
23
+ end
24
+ end.join("\n")
25
+
26
+ # Now do the terminal rendering
27
+ output = emulate_terminal_rendering(sanitize(output))
28
+
29
+ # Replace empty lines with a non breaking space.
30
+ output.gsub(/$^/, "&nbsp;")
31
+ end
32
+
33
+ private
34
+
35
+ # \n moves the cursor to a new line
36
+ # \r moves the cursor to the begining of the line
37
+ # \b moves the cursor back one
38
+ # \e[0m reset color information
39
+ # \e[?m use the ? color going forward
40
+ def emulate_terminal_rendering(string)
41
+ # Splits the output into intersting parts.
42
+ parts = string.scan(/[\n\r\b]|\e\[[\d;]+m|\e|[^\n\r\b\e]+/)
43
+
44
+ lines = []
45
+
46
+ index = 0
47
+ length = string.length
48
+
49
+ line = []
50
+ cursor = 0
51
+
52
+ # Every time a color is found, we increment this
53
+ # counter, every time it resets, we decrement.
54
+ # We do this so we close all the open spans at the
55
+ # end of the output.
56
+ colors_opened = 0
57
+
58
+ parts.each do |char|
59
+ case char
60
+ when "\n"
61
+ lines << line
62
+ line = []
63
+ cursor = 0
64
+ when "\r"
65
+ cursor = 0
66
+ when "\b"
67
+ pointer = cursor-1
68
+
69
+ # Seek backwards until something that isn't a color is reached.
70
+ # Colors aren't affected by \b
71
+ while pointer > 0
72
+ char_at_pointer = line[pointer]
73
+ break unless char_at_pointer.kind_of?(Terminal::Color)
74
+
75
+ pointer -= 1
76
+ end
77
+
78
+ cursor -= (cursor - pointer)
79
+ when "\e"
80
+ # Seek the next few characters to tell if theres a color present
81
+ seeked = string[index..(index + 10)]
82
+
83
+ # Does the next lot of characters look like a color code?
84
+ matched = seeked.to_s.match(/\A\e\[(.*)m\z/)
85
+
86
+ # If it does, skip over the characters that are the color,
87
+ # and track it at a single color object in the line. We do this
88
+ # so when we \b after a color, we skip back across the whole color
89
+ # not just the last character in the color sequence.
90
+ if matched
91
+ color_code = matched[1].to_s
92
+
93
+ # Determine what sort of color code it is.
94
+ if color_code == "0"
95
+ line[cursor] = Terminal::Reset.new(colors_opened)
96
+
97
+ colors_opened = 0
98
+ else
99
+ line[cursor] = Terminal::Color.new(color_code)
100
+
101
+ colors_opened += 1
102
+ end
103
+
104
+ index += 3 + color_code.length
105
+ cursor += 1
106
+
107
+ next
108
+ end
109
+ else
110
+ line[cursor] = char
111
+ cursor += 1
112
+ end
113
+
114
+ # The cursor can't go back furthur than 0, so if you \b at the begining
115
+ # of a line, nothing happens.
116
+ cursor = 0 if cursor < 0
117
+
118
+ index += 1
119
+ end
120
+
121
+ # Add back in the last line if the end of the output
122
+ # didn't end with a \n
123
+ lines << line if line.any?
124
+
125
+ # Be sure to reset any unclosed colors.
126
+ if colors_opened > 0
127
+ lines << [ Terminal::Reset.new(colors_opened) ]
128
+ end
129
+
130
+ # Join all the strings back together again
131
+ lines = lines.map do |parts|
132
+ completed_line = parts.map(&:to_s).join("")
133
+ end.join("\n")
134
+
135
+ # Now escape all the things
136
+ lines = EscapeUtils.escape_html(lines)
137
+
138
+ matches = []
139
+
140
+ # Now we can easily gsub colors like a baws
141
+ lines.gsub!(/\e\[([0-9;]+)m/) do |match|
142
+ color_codes = $1.split(';')
143
+
144
+ if color_codes == [ "0" ]
145
+ "</span>"
146
+ else
147
+ classes = color_codes.map { |code| "c#{code}" }
148
+
149
+ "<span class='#{classes.join(" ")}'>"
150
+ end
151
+ end
152
+
153
+ lines
154
+ end
155
+
156
+ def sanitize(string)
157
+ string = string.dup.force_encoding('UTF-8')
158
+ if string.valid_encoding?
159
+ string
160
+ else
161
+ string.
162
+ force_encoding('ASCII-8BIT').
163
+ encode!('UTF-8',
164
+ invalid: :replace,
165
+ undef: :replace)
166
+ end
167
+ end
168
+ end
169
+ end
@@ -0,0 +1,16 @@
1
+ module Terminal
2
+ class Reset < Terminal::Node
3
+ def initialize(opened)
4
+ @opened = opened
5
+ @code = "0"
6
+ end
7
+
8
+ def to_s
9
+ super * @opened
10
+ end
11
+
12
+ def to_debug
13
+ "[reset:#{@opened}]"
14
+ end
15
+ end
16
+ end
@@ -1,3 +1,3 @@
1
1
  module Terminal
2
- VERSION = "0.0.1.alpha"
2
+ VERSION = "0.0.1.alpha.2"
3
3
  end
@@ -0,0 +1,4 @@
1
+ require 'bundler/setup'
2
+ Bundler.setup
3
+
4
+ require 'terminal'
File without changes
@@ -18,6 +18,9 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ["lib"]
20
20
 
21
+ spec.add_dependency "escape_utils", "~> 1.0"
22
+
21
23
  spec.add_development_dependency "bundler", "~> 1.6"
22
24
  spec.add_development_dependency "rake"
25
+ spec.add_development_dependency "rspec"
23
26
  end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: terminal
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1.alpha
4
+ version: 0.0.1.alpha.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Keith Pitt
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-07-08 00:00:00.000000000 Z
11
+ date: 2014-07-09 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: escape_utils
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.0'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: bundler
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -38,20 +52,42 @@ dependencies:
38
52
  - - ">="
39
53
  - !ruby/object:Gem::Version
40
54
  version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
41
69
  description: Renders ASCII as HTML
42
70
  email:
43
71
  - me@keithpitt.com
44
- executables: []
72
+ executables:
73
+ - terminal
45
74
  extensions: []
46
75
  extra_rdoc_files: []
47
76
  files:
48
77
  - ".gitignore"
49
78
  - Gemfile
50
- - LICENSE.txt
51
- - README.md
52
79
  - Rakefile
80
+ - Readme.md
81
+ - bin/terminal
53
82
  - lib/terminal.rb
83
+ - lib/terminal/cli.rb
84
+ - lib/terminal/color.rb
85
+ - lib/terminal/node.rb
86
+ - lib/terminal/renderer.rb
87
+ - lib/terminal/reset.rb
54
88
  - lib/terminal/version.rb
89
+ - spec/spec_helper.rb
90
+ - spec/terminal/renderer_spec.rb
55
91
  - terminal.gemspec
56
92
  homepage: https://github.com/buildboxhq/terminal
57
93
  licenses:
@@ -77,4 +113,6 @@ rubygems_version: 2.3.0
77
113
  signing_key:
78
114
  specification_version: 4
79
115
  summary: Renders ASCII as HTML
80
- test_files: []
116
+ test_files:
117
+ - spec/spec_helper.rb
118
+ - spec/terminal/renderer_spec.rb
@@ -1,22 +0,0 @@
1
- Copyright (c) 2014 Keith Pitt
2
-
3
- MIT License
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining
6
- a copy of this software and associated documentation files (the
7
- "Software"), to deal in the Software without restriction, including
8
- without limitation the rights to use, copy, modify, merge, publish,
9
- distribute, sublicense, and/or sell copies of the Software, and to
10
- permit persons to whom the Software is furnished to do so, subject to
11
- the following conditions:
12
-
13
- The above copyright notice and this permission notice shall be
14
- included in all copies or substantial portions of the Software.
15
-
16
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md DELETED
@@ -1,29 +0,0 @@
1
- # Terminal
2
-
3
- TODO: Write a gem description
4
-
5
- ## Installation
6
-
7
- Add this line to your application's Gemfile:
8
-
9
- gem 'terminal'
10
-
11
- And then execute:
12
-
13
- $ bundle
14
-
15
- Or install it yourself as:
16
-
17
- $ gem install terminal
18
-
19
- ## Usage
20
-
21
- TODO: Write usage instructions here
22
-
23
- ## Contributing
24
-
25
- 1. Fork it ( https://github.com/[my-github-username]/terminal/fork )
26
- 2. Create your feature branch (`git checkout -b my-new-feature`)
27
- 3. Commit your changes (`git commit -am 'Add some feature'`)
28
- 4. Push to the branch (`git push origin my-new-feature`)
29
- 5. Create a new Pull Request