terminal 0.0.1.alpha → 0.0.1.alpha.2

Sign up to get free protection for your applications and to get access to all the features.
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