console 1.7.2 → 1.9.1

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
  SHA256:
3
- metadata.gz: dc774cc54d5e3bf9c96be4e34c314467e2ce8434a7acf7b059c24b86865ecdc6
4
- data.tar.gz: be5c6cf385afaf2e6c9722d595c63907842839003e49aeb95e1163026a7d2639
3
+ metadata.gz: ebadd29a9248f8a155c3bc22550a6433e53af806acae2112fe96a3924c92fb8d
4
+ data.tar.gz: fd23c8cb36efc9a36f688c2caa0383feb85fe7fdab2992d269239650faa8f92a
5
5
  SHA512:
6
- metadata.gz: 6133aad107df630aa40f63f56905c1afff80837baebe78f13a5a5610c6279c41757c14b91b34e3abdb83e2f8e574720a0a0614f18808e19beb700cf6a77f84f8
7
- data.tar.gz: f8a4fe934e7a8b3777ae94effeb61fe62b55ed0d740ea8c9030028bd2092b405d14556f077b19f1eeefad8654511b97e8bd51d8ff7a1635216071d5c304e502e
6
+ metadata.gz: 02b4cecf9844a7d6bb733da31953805d89590b5a43b68e7d6cc379bde7e2660e3064438385d40b147cde4c89b50b7f7f9f4cf3f58aa69e1498e0085f56015a86
7
+ data.tar.gz: 3bba83e7c801994f6fdb6a1a248fbac746a8a9987f786d30df73c91ba7d79032226d4f78d3eed9fb1a5d0eb9c339f89864c15fcceb823a2f877e81fe90c977f7
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Increase the verbosity of the logger to info.
4
+ def info
5
+ require_relative '../lib/console'
6
+
7
+ Console.logger.info!
8
+ end
9
+
10
+ # Increase the verbosity of the logger to debug.
11
+ def debug
12
+ require_relative '../lib/console'
13
+
14
+ Console.logger.debug!
15
+ end
@@ -43,14 +43,32 @@ module Console
43
43
  end
44
44
  end
45
45
 
46
+ # You can change the log level for different classes using CONSOLE_<LEVEL> env vars.
47
+ #
48
+ # e.g. `CONSOLE_WARN=Acorn,Banana CONSOLE_DEBUG=Cat` will set the log level for Acorn and Banana to warn and Cat to
49
+ # debug. This overrides the default log level.
50
+ #
51
+ # @param logger [Logger] A logger instance to set the logging levels on.
52
+ # @param env [Hash] Environment to read levels from.
53
+ #
54
+ # @return [nil] if there were no custom logging levels specified in the environment.
55
+ # @return [Resolver] if there were custom logging levels, then the created resolver is returned.
46
56
  def default_resolver(logger, env = ENV)
47
- if names = env['CONSOLE_DEBUG']&.split(',')
57
+ # find all CONSOLE_<LEVEL> variables from environment
58
+ levels = Logger::LEVELS
59
+ .map { |label, level| [level, env["CONSOLE_#{label.to_s.upcase}"]&.split(',')] }
60
+ .to_h
61
+ .compact
62
+
63
+ # if we have any levels, then create a class resolver, and each time a class is resolved, set the log level for
64
+ # that class to the specified level
65
+ if levels.any?
48
66
  resolver = Resolver.new
49
-
50
- resolver.bind(names) do |klass|
51
- logger.enable(klass, Logger::DEBUG)
67
+ levels.each do |level, names|
68
+ resolver.bind(names) do |klass|
69
+ logger.enable(klass, level)
70
+ end
52
71
  end
53
-
54
72
  return resolver
55
73
  end
56
74
  end
@@ -21,15 +21,20 @@
21
21
  require_relative 'filter'
22
22
 
23
23
  module Console
24
+ # A general sink which captures all events into a buffer.
24
25
  class Capture
25
26
  def initialize
26
- @events = []
27
+ @buffer = []
27
28
  end
28
29
 
29
- attr :events
30
+ attr :buffer
30
31
 
31
32
  def last
32
- @events.last
33
+ @buffer.last
34
+ end
35
+
36
+ def clear
37
+ @buffer.clear
33
38
  end
34
39
 
35
40
  def verbose!(value = true)
@@ -37,7 +42,7 @@ module Console
37
42
 
38
43
  def call(subject = nil, *arguments, severity: UNKNOWN, **options, &block)
39
44
  message = {
40
- time: Time.now.iso8601,
45
+ time: ::Time.now.iso8601,
41
46
  severity: severity,
42
47
  **options,
43
48
  }
@@ -60,7 +65,7 @@ module Console
60
65
  end
61
66
  end
62
67
 
63
- @events << message
68
+ @buffer << message
64
69
  end
65
70
  end
66
71
  end
@@ -20,3 +20,5 @@
20
20
 
21
21
  require_relative 'event/spawn'
22
22
  require_relative 'event/failure'
23
+ require_relative 'event/metric'
24
+ require_relative 'event/progress'
@@ -49,6 +49,10 @@ module Console
49
49
  terminal[:exception_backtrace] ||= terminal.style(:red)
50
50
  end
51
51
 
52
+ def to_h
53
+ {exception: @exception, root: @root}
54
+ end
55
+
52
56
  def format(output, terminal, verbose)
53
57
  format_exception(@exception, nil, output, terminal, verbose)
54
58
  end
@@ -24,6 +24,13 @@ module Console
24
24
  def self.register(terminal)
25
25
  end
26
26
 
27
+ def to_h
28
+ end
29
+
30
+ def as_json
31
+ to_h
32
+ end
33
+
27
34
  def format(buffer, terminal)
28
35
  end
29
36
  end
@@ -0,0 +1,49 @@
1
+ # Copyright, 2017, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in
11
+ # all copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ # THE SOFTWARE.
20
+
21
+ require_relative 'generic'
22
+
23
+ module Console
24
+ module Event
25
+ class Metric < Generic
26
+ def self.[](**parameters)
27
+ parameters.map(&self.method(:new))
28
+ end
29
+
30
+ def initialize(name, value, **tags)
31
+ @name = name
32
+ @value = value
33
+ @tags = tags
34
+ end
35
+
36
+ attr :name
37
+ attr :value
38
+ attr :tags
39
+
40
+ def to_h
41
+ {name: @name, value: @value, tags: @tags}
42
+ end
43
+
44
+ def format(output, terminal, verbose)
45
+ output.puts "#{@name}=#{@value} #{@tags.inspect}"
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,75 @@
1
+ # Copyright, 2017, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in
11
+ # all copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ # THE SOFTWARE.
20
+
21
+ require_relative 'generic'
22
+
23
+ module Console
24
+ module Event
25
+ class Progress < Generic
26
+ BLOCK = [
27
+ " ",
28
+ "▏",
29
+ "▎",
30
+ "▍",
31
+ "▌",
32
+ "▋",
33
+ "▊",
34
+ "▉",
35
+ "█",
36
+ ]
37
+
38
+ def initialize(current, total)
39
+ @current = current
40
+ @total = total
41
+ end
42
+
43
+ attr :current
44
+ attr :total
45
+
46
+ def value
47
+ @current.to_f / @total.to_f
48
+ end
49
+
50
+ def bar(value = self.value, width = 70)
51
+ blocks = width * value
52
+ full_blocks = blocks.floor
53
+ partial_block = ((blocks - full_blocks) * BLOCK.size).floor
54
+
55
+ if partial_block.zero?
56
+ BLOCK.last * full_blocks
57
+ else
58
+ "#{BLOCK.last * full_blocks}#{BLOCK[partial_block]}"
59
+ end.ljust(width)
60
+ end
61
+
62
+ def self.register(terminal)
63
+ terminal[:progress_bar] ||= terminal.style(:blue, :white)
64
+ end
65
+
66
+ def to_h
67
+ {current: @current, total: @total}
68
+ end
69
+
70
+ def format(output, terminal, verbose)
71
+ output.puts "#{terminal[:progress_bar]}#{self.bar}#{terminal.reset} #{sprintf('%6.2f', self.value * 100)}%"
72
+ end
73
+ end
74
+ end
75
+ end
@@ -24,6 +24,7 @@ module Console
24
24
  module Event
25
25
  class Spawn < Generic
26
26
  def self.for(*arguments, **options)
27
+ # Extract out the command environment:
27
28
  if arguments.first.is_a?(Hash)
28
29
  self.new(*arguments, **options)
29
30
  else
@@ -51,6 +52,10 @@ module Console
51
52
  terminal[:shell_command] ||= terminal.style(:blue, nil, :bold)
52
53
  end
53
54
 
55
+ def to_h
56
+ {environment: @environment, arguments: @arguments, options: @options}
57
+ end
58
+
54
59
  def format(output, terminal, verbose)
55
60
  arguments = @arguments.flatten.collect(&:to_s)
56
61
 
@@ -46,7 +46,7 @@ module Console
46
46
  end
47
47
 
48
48
  define_method("#{name}?") do
49
- @level >= level
49
+ @level <= level
50
50
  end
51
51
  end
52
52
  end
@@ -19,6 +19,7 @@
19
19
  # THE SOFTWARE.
20
20
 
21
21
  require_relative 'filter'
22
+ require_relative 'progress'
22
23
 
23
24
  module Console
24
25
  class Logger < Filter[debug: 0, info: 1, warn: 2, error: 3, fatal: 4]
@@ -27,5 +28,16 @@ module Console
27
28
  def initialize(output, **options)
28
29
  super(output, **options)
29
30
  end
31
+
32
+ def progress(subject, total, **options)
33
+ Progress.new(self, subject, total, **options)
34
+ end
35
+
36
+ # @deprecated Please use {progress}.
37
+ alias measure progress
38
+
39
+ def failure(subject, exception, *arguments, &block)
40
+ fatal(subject, *arguments, Event::Failure.new(exception), &block)
41
+ end
30
42
  end
31
43
  end
@@ -0,0 +1,140 @@
1
+ # Copyright, 2019, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in
11
+ # all copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ # THE SOFTWARE.
20
+
21
+ require_relative 'event/progress'
22
+
23
+ module Console
24
+ class Progress
25
+ def self.now
26
+ Process.clock_gettime(Process::CLOCK_MONOTONIC)
27
+ end
28
+
29
+ def initialize(output, subject, total = 0, minimum_output_duration: 1.0)
30
+ @output = output
31
+ @subject = subject
32
+
33
+ @start_time = Progress.now
34
+
35
+ @last_output_time = nil
36
+ @minimum_output_duration = 0.1
37
+
38
+ @current = 0
39
+ @total = total
40
+ end
41
+
42
+ attr :subject
43
+ attr :current
44
+ attr :total
45
+
46
+ def duration
47
+ Progress.now - @start_time
48
+ end
49
+
50
+ def progress
51
+ @current.to_f / @total.to_f
52
+ end
53
+
54
+ def remaining
55
+ @total - @current
56
+ end
57
+
58
+ def average_duration
59
+ if @current > 0
60
+ duration / @current
61
+ end
62
+ end
63
+
64
+ def estimated_remaining_time
65
+ if average_duration = self.average_duration
66
+ average_duration * remaining
67
+ end
68
+ end
69
+
70
+ def increment(amount = 1)
71
+ @current += amount
72
+
73
+ if output?
74
+ @output.info(@subject, self) {Event::Progress.new(@current, @total)}
75
+ @last_output_time = Progress.now
76
+ end
77
+
78
+ return self
79
+ end
80
+
81
+ def resize(total)
82
+ @total = total
83
+
84
+ @output.info(@subject, self) {Event::Progress.new(@current, @total)}
85
+ @last_output_time = Progress.now
86
+
87
+ return self
88
+ end
89
+
90
+ def mark(*arguments)
91
+ @output.info(@subject, *arguments)
92
+ end
93
+
94
+ def to_s
95
+ if estimated_remaining_time = self.estimated_remaining_time
96
+ "#{@current}/#{@total} completed in #{self.formatted_duration self.duration}, #{self.formatted_duration estimated_remaining_time} remaining."
97
+ else
98
+ "#{@current}/#{@total} completed, waiting for estimate..."
99
+ end
100
+ end
101
+
102
+ private
103
+
104
+ def duration_since_last_output
105
+ if @last_output_time
106
+ Progress.now - @last_output_time
107
+ end
108
+ end
109
+
110
+ def output?
111
+ if duration = duration_since_last_output
112
+ return duration > @minimum_output_duration
113
+ else
114
+ return true
115
+ end
116
+ end
117
+
118
+ def formatted_duration(duration)
119
+ if duration < 60.0
120
+ return "#{duration.round(2)}s"
121
+ end
122
+
123
+ duration /= 60.0
124
+
125
+ if duration < 60.0
126
+ return "#{duration.round}m"
127
+ end
128
+
129
+ duration /= 60.0
130
+
131
+ if duration < 60.0
132
+ return "#{duration.round(1)}h"
133
+ end
134
+
135
+ duration /= 24.0
136
+
137
+ return "#{duration.round(1)}d"
138
+ end
139
+ end
140
+ end
@@ -24,6 +24,8 @@ require_relative '../event'
24
24
  require_relative 'text'
25
25
  require_relative 'xterm'
26
26
 
27
+ require 'json'
28
+
27
29
  module Console
28
30
  module Terminal
29
31
  # This, and all related methods, is considered private.
@@ -77,7 +79,9 @@ module Console
77
79
  end
78
80
 
79
81
  attr :io
82
+
80
83
  attr_accessor :verbose
84
+
81
85
  attr :start
82
86
  attr :terminal
83
87
 
@@ -94,7 +98,7 @@ module Console
94
98
 
95
99
  UNKNOWN = 'unknown'
96
100
 
97
- def call(subject = nil, *arguments, name: nil, severity: UNKNOWN, &block)
101
+ def call(subject = nil, *arguments, name: nil, severity: UNKNOWN, **options, &block)
98
102
  prefix = build_prefix(name || severity.to_s)
99
103
  indent = " " * prefix.size
100
104
 
@@ -104,6 +108,10 @@ module Console
104
108
  format_subject(severity, prefix, subject, buffer)
105
109
  end
106
110
 
111
+ if options&.any?
112
+ format_options(options, buffer)
113
+ end
114
+
107
115
  arguments.each do |argument|
108
116
  format_argument(argument, buffer)
109
117
  end
@@ -121,6 +129,10 @@ module Console
121
129
 
122
130
  protected
123
131
 
132
+ def format_options(options, output)
133
+ format_value(options.to_json, output)
134
+ end
135
+
124
136
  def format_argument(argument, output)
125
137
  case argument
126
138
  when Exception
@@ -26,7 +26,7 @@ module Console
26
26
  class Text
27
27
  def initialize(output)
28
28
  @output = output
29
- @styles = {}
29
+ @styles = {reset: self.reset}
30
30
  end
31
31
 
32
32
  def [] key
@@ -47,25 +47,48 @@ module Console
47
47
  def reset
48
48
  end
49
49
 
50
- def write(*args, style: nil)
50
+ def write(*arguments, style: nil)
51
51
  if style and prefix = self[style]
52
52
  @output.write(prefix)
53
- @output.write(*args)
53
+ @output.write(*arguments)
54
54
  @output.write(self.reset)
55
55
  else
56
- @output.write(*args)
56
+ @output.write(*arguments)
57
57
  end
58
58
  end
59
59
 
60
- def puts(*args, style: nil)
60
+ def puts(*arguments, style: nil)
61
61
  if style and prefix = self[style]
62
62
  @output.write(prefix)
63
- @output.puts(*args)
63
+ @output.puts(*arguments)
64
64
  @output.write(self.reset)
65
65
  else
66
- @output.puts(*args)
66
+ @output.puts(*arguments)
67
67
  end
68
68
  end
69
+
70
+ # Print out the given arguments.
71
+ # When the argument is a symbol, look up the style and inject it into the output stream.
72
+ # When the argument is a proc/lambda, call it with self as the argument.
73
+ # When the argument is anything else, write it directly to the output.
74
+ def print(*arguments)
75
+ arguments.each do |argument|
76
+ case argument
77
+ when Symbol
78
+ @output.write(self[argument])
79
+ when Proc
80
+ argument.call(self)
81
+ else
82
+ @output.write(argument)
83
+ end
84
+ end
85
+ end
86
+
87
+ # Print out the arguments as per {#print}, followed by the reset sequence and a newline.
88
+ def print_line(*arguments)
89
+ print(*arguments)
90
+ @output.puts(self.reset)
91
+ end
69
92
  end
70
93
  end
71
94
  end
@@ -19,5 +19,5 @@
19
19
  # THE SOFTWARE.
20
20
 
21
21
  module Console
22
- VERSION = "1.7.2"
22
+ VERSION = "1.9.1"
23
23
  end
metadata CHANGED
@@ -1,17 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: console
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.7.2
4
+ version: 1.9.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-01-27 00:00:00.000000000 Z
11
+ date: 2020-10-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: covered
14
+ name: bake
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ">="
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: covered
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: rake
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -66,30 +80,25 @@ dependencies:
66
80
  - - "~>"
67
81
  - !ruby/object:Gem::Version
68
82
  version: '3.0'
69
- description:
83
+ description:
70
84
  email:
71
- - samuel.williams@oriontransfer.co.nz
72
85
  executables: []
73
86
  extensions: []
74
87
  extra_rdoc_files: []
75
88
  files:
76
- - ".editorconfig"
77
- - ".gitignore"
78
- - ".rspec"
79
- - ".travis.yml"
80
- - Gemfile
81
- - README.md
82
- - Rakefile
83
- - console.gemspec
89
+ - bake/console.rb
84
90
  - lib/console.rb
85
91
  - lib/console/buffer.rb
86
92
  - lib/console/capture.rb
87
93
  - lib/console/event.rb
88
94
  - lib/console/event/failure.rb
89
95
  - lib/console/event/generic.rb
96
+ - lib/console/event/metric.rb
97
+ - lib/console/event/progress.rb
90
98
  - lib/console/event/spawn.rb
91
99
  - lib/console/filter.rb
92
100
  - lib/console/logger.rb
101
+ - lib/console/progress.rb
93
102
  - lib/console/resolver.rb
94
103
  - lib/console/serialized/logger.rb
95
104
  - lib/console/split.rb
@@ -98,12 +107,11 @@ files:
98
107
  - lib/console/terminal/text.rb
99
108
  - lib/console/terminal/xterm.rb
100
109
  - lib/console/version.rb
101
- - proposal.md
102
110
  homepage: https://github.com/socketry/console
103
111
  licenses:
104
112
  - MIT
105
113
  metadata: {}
106
- post_install_message:
114
+ post_install_message:
107
115
  rdoc_options: []
108
116
  require_paths:
109
117
  - lib
@@ -111,7 +119,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
111
119
  requirements:
112
120
  - - ">="
113
121
  - !ruby/object:Gem::Version
114
- version: '0'
122
+ version: '2.5'
115
123
  required_rubygems_version: !ruby/object:Gem::Requirement
116
124
  requirements:
117
125
  - - ">="
@@ -119,7 +127,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
119
127
  version: '0'
120
128
  requirements: []
121
129
  rubygems_version: 3.1.2
122
- signing_key:
130
+ signing_key:
123
131
  specification_version: 4
124
132
  summary: Beautiful logging for Ruby.
125
133
  test_files: []
@@ -1,6 +0,0 @@
1
- root = true
2
-
3
- [*]
4
- indent_style = tab
5
- indent_size = 2
6
-
data/.gitignore DELETED
@@ -1,12 +0,0 @@
1
- /.bundle/
2
- /.yardoc
3
- /_yardoc/
4
- /coverage/
5
- /doc/
6
- /pkg/
7
- /spec/reports/
8
- /tmp/
9
-
10
- Gemfile.lock
11
- .rspec_status
12
- .covered.db
data/.rspec DELETED
@@ -1,4 +0,0 @@
1
- --format documentation
2
- --color
3
- --require spec_helper
4
- --warnings
@@ -1,19 +0,0 @@
1
- language: ruby
2
- dist: xenial
3
- cache: bundler
4
-
5
- matrix:
6
- include:
7
- - rvm: 2.4
8
- - rvm: 2.5
9
- - rvm: 2.6
10
- - rvm: 2.7
11
- - rvm: 2.6
12
- env: COVERAGE=PartialSummary,Coveralls
13
- - rvm: truffleruby
14
- - rvm: jruby-head
15
- - rvm: ruby-head
16
- allow_failures:
17
- - rvm: truffleruby
18
- - rvm: ruby-head
19
- - rvm: jruby-head
data/Gemfile DELETED
@@ -1,8 +0,0 @@
1
- source "https://rubygems.org"
2
-
3
- git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
-
5
- # Specify your gem's dependencies in console.gemspec
6
- gemspec
7
-
8
- gem "pry"
data/README.md DELETED
@@ -1,212 +0,0 @@
1
- # Console
2
-
3
- Provides beautiful console logging for Ruby applications. Implements fast, buffered log output.
4
-
5
- [![Build Status](https://travis-ci.com/socketry/console.svg)](http://travis-ci.com/socketry/console)
6
- [![Coverage Status](https://coveralls.io/repos/socketry/console/badge.svg)](https://coveralls.io/r/socketry/console)
7
-
8
- ## Motivation
9
-
10
- When Ruby decided to reverse the order of exception backtraces, I finally gave up using the built in logging and decided restore sanity to the output of my programs once and for all!
11
-
12
- ## Installation
13
-
14
- Add this line to your application's Gemfile:
15
-
16
- ```ruby
17
- gem 'console'
18
- ```
19
-
20
- And then execute:
21
-
22
- $ bundle
23
-
24
- ## Usage
25
-
26
- As your code executes, it generates interesting events which you want to know about. The general approach is to use an `Console::Logger` which outputs text to the terminal. The text is generated by inspecting the console that occurred.
27
-
28
- Capturing structured information allows it to be used in different ways. These events can be sent to a logger or some other system (e.g. web browser, syslog) and analysed in more detail.
29
-
30
- ### Default Logger
31
-
32
- Generally speaking, use `Console.logger` which is suitable for logging to the user's terminal.
33
-
34
- ### Environment Variables
35
-
36
- #### `CONSOLE_LEVEL=debug`
37
-
38
- Control the default logger level. You can set it to any of the supported log levels: `debug`, `info`, `warn`, `error`, `fatal`.
39
-
40
- #### `CONSOLE_DEBUG=MyClass,MyModule::MyClass`
41
-
42
- Enable debug logging for the specified class names. You can specify one or more class names which will be resolved at runtime.
43
-
44
- ### Module Integration
45
-
46
- ```ruby
47
- require 'console'
48
-
49
- # Set the log level:
50
- Console.logger.debug!
51
-
52
- module MyModule
53
- extend Console
54
-
55
- def self.test_logger
56
- logger.debug "GOTO LINE 1."
57
- logger.info "5 things your doctor won't tell you!"
58
- logger.warn "Something didn't work as expected!"
59
- logger.error "The matrix has two cats!"
60
- end
61
-
62
- test_logger
63
- end
64
- ```
65
-
66
- ### Class Integration
67
-
68
- ```ruby
69
- require 'console'
70
-
71
- # Set the log level:
72
- Console.logger.debug!
73
-
74
- class MyObject
75
- include Console
76
-
77
- def test_logger
78
- logger.debug "GOTO LINE 1."
79
- logger.info "5 things your doctor won't tell you!"
80
- logger.warn "Something didn't work as expected!"
81
- logger.error "The matrix has two cats!"
82
- end
83
- end
84
-
85
- MyObject.new.test_logger
86
- ```
87
-
88
- ### Subject Logging
89
-
90
- The first argument to the log method is the subject.
91
-
92
- ```ruby
93
- class Thing
94
- def call
95
- Console.logger.info(self) {"Something is going on"}
96
- end
97
- end
98
- ```
99
-
100
- Using this approach, you can turn on and off specific subjects by using the class name:
101
-
102
- ```ruby
103
- $ CONSOLE_DEBUG=Thing ./script.rb
104
- ```
105
-
106
- This will conditionally enable all log statements which have a subject of class `Thing`.
107
-
108
- ### Console Formatting
109
-
110
- Console classes are used to wrap data which can generate structured log messages:
111
-
112
- ```ruby
113
- require 'console'
114
-
115
- class MyConsole < Console::Generic
116
- def format(output, terminal, verbose)
117
- output.puts "My console text!"
118
- end
119
- end
120
-
121
- Console.logger.info("My Console", MyConsole.new)
122
- ```
123
-
124
- #### Failure Events
125
-
126
- `Console::Event::Failure` represents an exception and will log the message and backtrace recursively.
127
-
128
- #### Spawn Events
129
-
130
- `Console::Event::Spawn` represents the execution of a command, and will log the environment, arguments and options used to execute it.
131
-
132
- ### Custom Log Levels
133
-
134
- `Console::Filter` implements support for multiple log levels.
135
-
136
- ```ruby
137
- require 'console'
138
-
139
- MyLogger = Console::Filter[noise: 0, stuff: 1, broken: 2]
140
-
141
- # verbose: true - log severity/name/pid etc.
142
- logger = MyLogger.new(Console.logger, name: "Java", verbose: true)
143
-
144
- logger.broken("It's so janky.")
145
- ```
146
-
147
- ### Multiple Outputs
148
-
149
- Use `Console::Split` to log to multiple destinations.
150
-
151
- ```ruby
152
- require 'console/terminal'
153
- require 'console/serialized/logger'
154
- require 'console/logger'
155
- require 'console/split'
156
-
157
- terminal = Console::Terminal::Logger.new
158
- file = Console::Serialized::Logger.new(File.open("log.json", "a"))
159
-
160
- logger = Console::Logger.new(Console::Split[terminal, file])
161
-
162
- logger.info "I can go everywhere!"
163
- ```
164
-
165
- ### Custom Logger Output
166
-
167
- `Console::Logger` provides a default interface which is a drop in replacemnet for `Logger` and other similar implementations. The only method required for output is `#call(*arguments, **options, &block)`.
168
-
169
- ```ruby
170
- require 'console/logger'
171
-
172
- output = proc do |*arguments, **options, &block|
173
- puts "arguments: #{arguments.inspect} options: #{options.inspect} block: #{block.call}"
174
- end
175
-
176
- logger = Console::Logger.new(output)
177
-
178
- logger.info("Hello World!", meta: "data") {"block"}
179
- # => arguments: ["Hello World!"] options: {:severity=>:info, :meta=>"data"} block: block
180
- ```
181
-
182
- ## Contributing
183
-
184
- 1. Fork it
185
- 2. Create your feature branch (`git checkout -b my-new-feature`)
186
- 3. Commit your changes (`git commit -am 'Add some feature'`)
187
- 4. Push to the branch (`git push origin my-new-feature`)
188
- 5. Create new Pull Request
189
-
190
- ## License
191
-
192
- Released under the MIT license.
193
-
194
- Copyright, 2019, by [Samuel Williams](https://www.codeotaku.com).
195
-
196
- Permission is hereby granted, free of charge, to any person obtaining a copy
197
- of this software and associated documentation files (the "Software"), to deal
198
- in the Software without restriction, including without limitation the rights
199
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
200
- copies of the Software, and to permit persons to whom the Software is
201
- furnished to do so, subject to the following conditions:
202
-
203
- The above copyright notice and this permission notice shall be included in
204
- all copies or substantial portions of the Software.
205
-
206
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
207
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
208
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
209
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
210
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
211
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
212
- THE SOFTWARE.
data/Rakefile DELETED
@@ -1,13 +0,0 @@
1
- require "bundler/gem_tasks"
2
- require "rspec/core/rake_task"
3
-
4
- RSpec::Core::RakeTask.new(:spec)
5
-
6
- task :default => :spec
7
-
8
- task :console do
9
- require 'pry'
10
- require 'console'
11
-
12
- binding.pry
13
- end
@@ -1,25 +0,0 @@
1
-
2
- require_relative "lib/console/version"
3
-
4
- Gem::Specification.new do |spec|
5
- spec.name = "console"
6
- spec.version = Console::VERSION
7
- spec.licenses = ["MIT"]
8
- spec.authors = ["Samuel Williams"]
9
- spec.email = ["samuel.williams@oriontransfer.co.nz"]
10
-
11
- spec.summary = "Beautiful logging for Ruby."
12
- spec.homepage = "https://github.com/socketry/console"
13
-
14
- spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
15
- `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
16
- end
17
-
18
- spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
- spec.require_paths = ["lib"]
20
-
21
- spec.add_development_dependency "covered"
22
- spec.add_development_dependency "bundler"
23
- spec.add_development_dependency "rake", "~> 10.0"
24
- spec.add_development_dependency "rspec", "~> 3.0"
25
- end
@@ -1,84 +0,0 @@
1
- # Global Logger
2
-
3
- Configure what logging looks like globally:
4
-
5
- ```ruby
6
- Console.logger
7
- ```
8
-
9
- Other logger instances would inherit their initial configuration from the global logger.
10
-
11
- Rather than the output being configurable on the global logger, it would always route to `$stdout`. _Or perhaps no destinations should exist and you add one; there must be a way to attach a formatter to even the default destination._
12
-
13
- # Adding Destinations
14
-
15
- The global logger or any instance could log to multiple destinations:
16
-
17
- ```ruby
18
- Console.add(some_io, formatter: some_formatter)
19
- ```
20
-
21
- I _think_ that formatters would be defined on destinations. This would allow for writing in one format to `$stdout` and another to `syslog`, for example.
22
-
23
- # Logger Instances
24
-
25
- Named instances could be created with a given output:
26
-
27
- ```ruby
28
- connection_logger = Console.new(:connection, output: ...)
29
- ```
30
-
31
- Outputs would not reference an io object, but rather another named instance (defaulting to global). Again, Destinations + Formatters could be added to any instance. This would allow outputs to be chained.
32
-
33
- ## Instances As Subjects
34
-
35
- Perhaps an interesting idea is letting logger instance names be subjects, controllable from the global logger. In the example above, `:connection` would become a known subject that could be enabled/disabled from the global logger:
36
-
37
- ```ruby
38
- Console.disable(:connection)
39
- ```
40
-
41
- This lets us very easily disable the logging of events of a particular type.
42
-
43
- ---
44
-
45
- In [Pakyow's logger](https://gist.github.com/bryanp/0329d58c753f1fa6e99d970960ad006d#file-logger-rb), instances are created in these cases:
46
-
47
- * Environment: Single logger for the environment, named `:pkyw`.
48
- * Connection: Per-Request logger containing the connection id, named `:http`.
49
- * WebSocket: Per-WebSocket logger containing the WebSocket id, named `:sock`.
50
- * Async: The logger that async is configured with, named `:asnc`.
51
-
52
- Instances could be initialized with metadata that is passed with the console to the formatter:
53
-
54
- ```ruby
55
- connection_logger = Console.new(:http, output: ..., connection_id: "123")
56
- ```
57
-
58
- # Formatters
59
-
60
- Just a class with a `format` method that accepts an `console`, which is a hash or simple object containing the console data along with attached metadata (e.g. timestamp, metadata from the instance). Returns a string, and/or writes directly to the buffer.
61
-
62
- # Custom Levels
63
-
64
- Pakyow's logger uses the following levels:
65
-
66
- * all
67
- * verbose
68
- * debug
69
- * info
70
- * warn
71
- * error
72
- * fatal
73
- * unknown
74
- * off
75
-
76
- `all` and `off` aren't turned into logging methods in `Pakyow::Logger`, but rather the log level can be set to either one as an easy way to guarantee that all or no logs will be written, without knowing what the lowest and highest level of logging are in the system.
77
-
78
- Projects often have different needs, so making this easily configurable on both the global logger and individual logger instances would be amazing:
79
-
80
- ```ruby
81
- Console.levels(
82
- %i(all verbose debug info warn error fatal unknown off)
83
- )
84
- ```