pax_global_header00006660000000000000000000000064142373116760014524gustar00rootroot0000000000000052 comment=fc6ecb94bc02b8b75003fc31f0a8b3e1e43cafcf ruby-console-1.15.3/000077500000000000000000000000001423731167600142345ustar00rootroot00000000000000ruby-console-1.15.3/.editorconfig000066400000000000000000000000641423731167600167110ustar00rootroot00000000000000root = true [*] indent_style = tab indent_size = 2 ruby-console-1.15.3/.github/000077500000000000000000000000001423731167600155745ustar00rootroot00000000000000ruby-console-1.15.3/.github/workflows/000077500000000000000000000000001423731167600176315ustar00rootroot00000000000000ruby-console-1.15.3/.github/workflows/development.yml000066400000000000000000000016331423731167600227010ustar00rootroot00000000000000name: Development on: [push, pull_request] jobs: test: name: ${{matrix.ruby}} on ${{matrix.os}} runs-on: ${{matrix.os}}-latest continue-on-error: ${{matrix.experimental}} strategy: matrix: os: - ubuntu - macos ruby: - "2.6" - "2.7" - "3.0" experimental: [false] env: [""] include: - os: ubuntu ruby: truffleruby experimental: true - os: ubuntu ruby: jruby experimental: true - os: ubuntu ruby: head experimental: true steps: - uses: actions/checkout@v2 - uses: ruby/setup-ruby@v1 with: ruby-version: ${{matrix.ruby}} bundler-cache: true - name: Run tests timeout-minutes: 5 run: ${{matrix.env}} bundle exec rspec ruby-console-1.15.3/.github/workflows/documentation.yml000066400000000000000000000012611423731167600232250ustar00rootroot00000000000000name: Documentation on: push: branches: - main env: BUNDLE_WITH: maintenance jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: ruby/setup-ruby@v1 with: ruby-version: 3.1 bundler-cache: true - name: Installing packages run: sudo apt-get install wget - name: Prepare GitHub Pages run: bundle exec bake github:pages:prepare --directory docs - name: Generate documentation timeout-minutes: 5 run: bundle exec bake utopia:project:static --force no - name: Deploy GitHub Pages run: bundle exec bake github:pages:commit --directory docs ruby-console-1.15.3/.gitignore000066400000000000000000000001721423731167600162240ustar00rootroot00000000000000/.bundle/ /.yardoc /_yardoc/ /coverage/ /doc/ /pkg/ /spec/reports/ /tmp/ /vendor/ /gems.locked .rspec_status .covered.db ruby-console-1.15.3/.rspec000066400000000000000000000001001423731167600153400ustar00rootroot00000000000000--format documentation --color --require spec_helper --warnings ruby-console-1.15.3/README.md000066400000000000000000000037741423731167600155260ustar00rootroot00000000000000# Console Provides beautiful console logging for Ruby applications. Implements fast, buffered log output. [![Development Status](https://github.com/socketry/console/workflows/Development/badge.svg)](https://github.com/socketry/console/actions?workflow=Development) ## Features - Thread safe global logger with per-fiber context. - Carry along context with nested loggers. - Enable/disable log levels per-class. - Detailed logging of exceptions. - Beautiful logging to the terminal or structured logging using JSON. ## Usage Please see the [project documentation](https://socketry.github.io/console). ## Contributing We welcome contributions to this project. 1. Fork it. 2. Create your feature branch (`git checkout -b my-new-feature`). 3. Commit your changes (`git commit -am 'Add some feature'`). 4. Push to the branch (`git push origin my-new-feature`). 5. Create new Pull Request. ## License Released under the MIT license. Copyright, 2019, by [Samuel Williams](https://www.codeotaku.com). Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ruby-console-1.15.3/bake.rb000066400000000000000000000003261423731167600154640ustar00rootroot00000000000000# frozen_string_literal: true def sample_progress_bar require_relative 'lib/console' measure = Console.logger.measure("Progress Bar", 10000) 10000.times do |i| sleep 0.001 measure.increment end end ruby-console-1.15.3/bake/000077500000000000000000000000001423731167600151365ustar00rootroot00000000000000ruby-console-1.15.3/bake/console.rb000066400000000000000000000004231423731167600171240ustar00rootroot00000000000000# frozen_string_literal: true # Increase the verbosity of the logger to info. def info require_relative '../lib/console' Console.logger.info! end # Increase the verbosity of the logger to debug. def debug require_relative '../lib/console' Console.logger.debug! end ruby-console-1.15.3/benchmark/000077500000000000000000000000001423731167600161665ustar00rootroot00000000000000ruby-console-1.15.3/benchmark/fiber_vs_thread.rb000077500000000000000000000042041423731167600216440ustar00rootroot00000000000000#!/usr/bin/env ruby # frozen_string_literal: true # Copyright, 2020, by Samuel G. D. Williams. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. require 'benchmark/ips' require 'fiber' # GC.disable puts RUBY_VERSION class Fiber attr_accessor :my_local end class MyObject attr_accessor :my_local end Benchmark.ips do |benchmark| benchmark.report("Hash\#[]=") do |count| hash = Hash.new while count > 0 hash[:my_local] = count count -= 1 end end benchmark.report("Thread\#[]=") do |count| thread = Thread.current while count > 0 thread[:my_local] = count count -= 1 end end benchmark.report("Thread\#thread_variable_set") do |count| thread = Thread.current while count > 0 thread.thread_variable_set(:my_local, count) count -= 1 end end benchmark.report("Fiber\#my_local=") do |count| fiber = Fiber.current while count > 0 fiber.my_local = count count -= 1 end end benchmark.report("MyObject\#my_local=") do |count| object = MyObject.new while count > 0 object.my_local = count count -= 1 end end benchmark.compare! end ruby-console-1.15.3/console.gemspec000066400000000000000000000016271423731167600172510ustar00rootroot00000000000000# frozen_string_literal: true require_relative "lib/console/version" Gem::Specification.new do |spec| spec.name = "console" spec.version = Console::VERSION spec.summary = "Beautiful logging for Ruby." spec.authors = ["Samuel Williams", "Robert Schulze", "Bryan Powell", "Michael Adams", "Cyril Roelandt", "Cédric Boutillier", "Olle Jonsson"] spec.license = "MIT" spec.cert_chain = ['release.cert'] spec.signing_key = File.expand_path('~/.gem/release.pem') spec.homepage = "https://github.com/socketry/console" spec.files = Dir.glob('{bake,lib}/**/*', File::FNM_DOTMATCH, base: __dir__) spec.required_ruby_version = ">= 2.5" spec.add_dependency "fiber-local" spec.add_development_dependency "bake" spec.add_development_dependency "bundler" spec.add_development_dependency "covered" spec.add_development_dependency "rake", "~> 10.0" spec.add_development_dependency "rspec", "~> 3.0" end ruby-console-1.15.3/gems.rb000066400000000000000000000003751423731167600155210ustar00rootroot00000000000000# frozen_string_literal: true source "https://rubygems.org" # Specify your gem's dependencies in console.gemspec gemspec group :maintenance, optional: true do gem "bake-gem" gem "bake-modernize" gem "bake-github-pages" gem "utopia-project" end ruby-console-1.15.3/guides/000077500000000000000000000000001423731167600155145ustar00rootroot00000000000000ruby-console-1.15.3/guides/getting-started/000077500000000000000000000000001423731167600206215ustar00rootroot00000000000000ruby-console-1.15.3/guides/getting-started/README.md000066400000000000000000000110751423731167600221040ustar00rootroot00000000000000# Getting Started This guide explains how to use `console` for logging. ## Installation Add the gem to your project: ~~~ bash $ bundle add console ~~~ ## Core Concepts `console` has several core concepts: - A log message which consists of a set of arguments and options, which includes a timestamp, severity, and other structured data. - A {ruby Console::Logger} instance which is the main entry point for logging for a specific system and writes data to a given output formatter. - An output instance such as {ruby Console::XTerm}, {ruby Console::Serialized::Logger} which formats these log messages and writes them to a specific output device. - An event instance, such as {ruby Console::Event::Progress} or {ruby Console::Event::Spawn} which represents a structured event within a system, which can be formatted in a specific way. ## Basic Logging Out of the box, {ruby Console.logger} is a globally shared logger that outputs to the current terminal via `stderr`. ~~~ ruby require 'console' Console.logger.info("Hello World") ~~~
  0.0s     info: Hello World [pid=219113] [2020-08-08 12:21:26 +1200]
The method name `info` indicates the severity level of the log message. You can filter out severity levels, and by default, `debug` messages are filtered out. Here are some examples of the different log levels: ~~~ ruby require 'console' Console.logger.debug("The input voltage has stabilized.") Console.logger.info("Making a request to the machine.") Console.logger.warn("The machine has detected a temperature anomaly.") Console.logger.error("The machine was unable to complete the request!") Console.logger.fatal("Depressurisation detected, evacuate the area!") ~~~ From the terminal, you can control the log level using the `CONSOLE_LEVEL` environment variable. To log all messages including `debug`: ~~~ bash $ CONSOLE_LEVEL=debug ./machine ~~~ Alternatively to restrict log messages to warnings and above: ~~~ bash $ CONSOLE_LEVEL=warn ./machine ~~~ If otherwise unspecified, Ruby's standard `$DEBUG` and `$VERBOSE` global variables will be checked and adjust the log level appropriately. ## Subject Logging The first argument to the log statement becomes the implicit subject of the log message. ~~~ ruby require 'console' class Machine include Console def initialize(voltage) @voltage = voltage.floor logger.info(self, "The input voltage has stabilized.") end end Machine.new(5.5) ~~~ The given subject, in this case `self`, is used on the first line, along with associated metadata, while the message itself appears on subsequent lines:
  0.0s     info: Machine [oid=0x3c] [pid=219041] [2020-08-08 12:17:33 +1200]
               | The input voltage has stabilized.
If you want to disable log messages which come from this particular class, you can execute your command: ~~~ bash $ CONSOLE_FATAL=Machine ./machine ~~~ This will prevent any log message which has a subject of class `Machine` from logging messages of a severity less than `fatal`. ## Exception Logging If your code has an unhandled exception, you may wish to log it. In order to log a full backtrace, you must log the subject followed by the exception. ~~~ ruby require 'console' class Cache include Console def initialize @entries = {} end def fetch(key) @entries.fetch(key) rescue => error logger.failure(self, error) end end Cache.new.fetch(:foo) ~~~ This will produce the following output:
  0.0s    fatal: Cache [oid=0x3c] [pid=220776] [2020-08-08 14:10:00 +1200]
               |   KeyError: key not found: :foo
               |   → cache.rb:11 in 'fetch'
               |     cache.rb:11 in 'fetch'
               |     cache.rb:17 in '<main>'
## Program Structure Generally, all programs should use the global `Console.logger` instance. The per-class `include Console` allows you to All programs should generally use the global `Console.logger` instance. Generally, individual classes should not be catching and logging exceptions. Generally, individual classes should not be catching and logging exceptions. It makes for simpler code if this is handled in a few places near the top of your program. Exceptions should collect enough information such that logging them produces a detailed backtrace leading to the failure.ruby-console-1.15.3/guides/getting-started/old.md000066400000000000000000000106351423731167600217260ustar00rootroot00000000000000## Motivation 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\! ## Installation Add this line to your application's Gemfile: ``` ruby gem 'console' ``` And then execute: $ bundle ## Usage 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. 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. ### Default Logger Generally speaking, use `Console.logger` which is suitable for logging to the user's terminal. ### Environment Variables #### `CONSOLE_LEVEL=debug` Control the default logger level. You can set it to any of the supported log levels: `debug`, `info`, `warn`, `error`, `fatal`. #### `CONSOLE_DEBUG=MyClass,MyModule::MyClass` Enable debug logging for the specified class names. You can specify one or more class names which will be resolved at runtime. ### Module Integration ``` ruby require 'console' # Set the log level: Console.logger.debug! module MyModule extend Console def self.test_logger logger.debug "GOTO LINE 1." logger.info "5 things your doctor won't tell you!" logger.warn "Something didn't work as expected!" logger.error "The matrix has two cats!" end test_logger end ``` ### Class Integration ``` ruby require 'console' # Set the log level: Console.logger.debug! class MyObject include Console def test_logger logger.debug "GOTO LINE 1." logger.info "5 things your doctor won't tell you!" logger.warn "Something didn't work as expected!" logger.error "The matrix has two cats!" end end MyObject.new.test_logger ``` ### Subject Logging The first argument to the log method is the subject. ``` ruby class Thing def call Console.logger.info(self) {"Something is going on"} end end ``` Using this approach, you can turn on and off specific subjects by using the class name: ``` ruby $ CONSOLE_DEBUG=Thing ./script.rb ``` This will conditionally enable all log statements which have a subject of class `Thing`. ### Console Formatting Console classes are used to wrap data which can generate structured log messages: ``` ruby require 'console' class MyConsole < Console::Generic def format(output, terminal, verbose) output.puts "My console text!" end end Console.logger.info("My Console", MyConsole.new) ``` #### Failure Events `Console::Event::Failure` represents an exception and will log the message and backtrace recursively. #### Spawn Events `Console::Event::Spawn` represents the execution of a command, and will log the environment, arguments and options used to execute it. ### Custom Log Levels `Console::Filter` implements support for multiple log levels. ``` ruby require 'console' MyLogger = Console::Filter[noise: 0, stuff: 1, broken: 2] # verbose: true - log severity/name/pid etc. logger = MyLogger.new(Console.logger, name: "Java", verbose: true) logger.broken("It's so janky.") ``` ### Multiple Outputs Use `Console::Split` to log to multiple destinations. ``` ruby require 'console/terminal' require 'console/serialized/logger' require 'console/logger' require 'console/split' terminal = Console::Terminal::Logger.new file = Console::Serialized::Logger.new(File.open("log.json", "a")) logger = Console::Logger.new(Console::Split[terminal, file]) logger.info "I can go everywhere!" ``` ### Custom Logger Output `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)`. ``` ruby require 'console/logger' output = proc do |*arguments, **options, &block| puts "arguments: #{arguments.inspect} options: #{options.inspect} block: #{block.call}" end logger = Console::Logger.new(output) logger.info("Hello World!", meta: "data") {"block"} # => arguments: ["Hello World!"] options: {:severity=>:info, :meta=>"data"} block: block ``` ## Contributing 1. Fork it 2. Create your feature branch (`git checkout -b my-new-feature`) 3. Commit your changes (`git commit -am 'Add some feature'`) 4. Push to the branch (`git push origin my-new-feature`) 5. Create new Pull Request ruby-console-1.15.3/lib/000077500000000000000000000000001423731167600150025ustar00rootroot00000000000000ruby-console-1.15.3/lib/console.rb000066400000000000000000000027711423731167600170000ustar00rootroot00000000000000# frozen_string_literal: true # # Copyright, 2019, by Samuel G. D. Williams. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. require_relative 'console/version' require_relative 'console/logger' module Console def self.logger Logger.instance end def self.logger= instance Logger.instance= instance end def logger= logger @logger = logger end def logger @logger || Logger.instance end def self.extended(klass) klass.instance_variable_set(:@logger, nil) end end ruby-console-1.15.3/lib/console/000077500000000000000000000000001423731167600164445ustar00rootroot00000000000000ruby-console-1.15.3/lib/console/buffer.rb000066400000000000000000000026451423731167600202510ustar00rootroot00000000000000# frozen_string_literal: true # Copyright, 2017, by Samuel G. D. Williams. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. require 'stringio' module Console class Buffer < StringIO def initialize(prefix = nil) @prefix = prefix super() end def puts(*args, prefix: @prefix) args.each do |arg| self.write(prefix) if prefix super(arg) end end alias << puts end end ruby-console-1.15.3/lib/console/capture.rb000066400000000000000000000037731423731167600204460ustar00rootroot00000000000000# frozen_string_literal: true # Copyright, 2017, by Samuel G. D. Williams. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. require_relative 'filter' module Console # A general sink which captures all events into a buffer. class Capture def initialize @buffer = [] end attr :buffer def last @buffer.last end def include?(pattern) JSON.dump(@buffer).include?(pattern) end def clear @buffer.clear end def verbose!(value = true) end def call(subject = nil, *arguments, severity: UNKNOWN, **options, &block) message = { time: ::Time.now.iso8601, severity: severity, **options, } if subject message[:subject] = subject end if arguments.any? message[:arguments] = arguments end if block_given? if block.arity.zero? message[:message] = yield else buffer = StringIO.new yield buffer message[:message] = buffer.string end end @buffer << message end end end ruby-console-1.15.3/lib/console/clock.rb000066400000000000000000000032161423731167600200660ustar00rootroot00000000000000# frozen_string_literal: true # Copyright, 2021, by Samuel G. D. Williams. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. module Console module Clock def self.formatted_duration(duration) if duration < 60.0 return "#{duration.round(2)}s" end duration /= 60.0 if duration < 60.0 return "#{duration.round}m" end duration /= 60.0 if duration < 60.0 return "#{duration.round(1)}h" end duration /= 24.0 return "#{duration.round(1)}d" end # Get the current elapsed monotonic time. def self.now ::Process.clock_gettime(::Process::CLOCK_MONOTONIC) end end end ruby-console-1.15.3/lib/console/compatible/000077500000000000000000000000001423731167600205635ustar00rootroot00000000000000ruby-console-1.15.3/lib/console/compatible/logger.rb000066400000000000000000000043361423731167600223750ustar00rootroot00000000000000# frozen_string_literal: true # Copyright, 2021, by Samuel G. D. Williams. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. require 'logger' module Console module Compatible class Logger < ::Logger class LogDevice def initialize(subject, output) @subject = subject @output = output end def write(message) @output.call(@subject, message) end def call(*arguments, **options) @output.call(*arguments, **options) end def reopen end def close end end def initialize(subject, output) super(nil) @progname = subject @logdev = LogDevice.new(subject, output) end def add(severity, message = nil, progname = nil) severity ||= UNKNOWN if @logdev.nil? or severity < level return true end if progname.nil? progname = @progname end if message.nil? if block_given? message = yield else message = progname progname = @progname end end @logdev.call( progname, message, severity: format_severity(severity) ) return true end def format_severity(value) super.downcase.to_sym end end end end ruby-console-1.15.3/lib/console/event.rb000066400000000000000000000024161423731167600201150ustar00rootroot00000000000000# frozen_string_literal: true # Copyright, 2019, by Samuel G. D. Williams. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. require_relative 'event/spawn' require_relative 'event/failure' require_relative 'event/metric' require_relative 'event/progress' ruby-console-1.15.3/lib/console/event/000077500000000000000000000000001423731167600175655ustar00rootroot00000000000000ruby-console-1.15.3/lib/console/event/failure.rb000066400000000000000000000060561423731167600215500ustar00rootroot00000000000000# frozen_string_literal: true # # Copyright, 2019, by Samuel G. D. Williams. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. require_relative 'generic' module Console module Event class Failure < Generic def self.current_working_directory Dir.getwd rescue # e.g. Errno::EMFILE nil end def self.for(exception) self.new(exception, self.current_working_directory) end def initialize(exception, root = nil) @exception = exception @root = root end attr :exception attr :root def self.register(terminal) terminal[:exception_title] ||= terminal.style(:red, nil, :bold) terminal[:exception_detail] ||= terminal.style(:yellow) terminal[:exception_backtrace] ||= terminal.style(:red) terminal[:exception_backtrace_other] ||= terminal.style(:red, nil, :faint) terminal[:exception_message] ||= terminal.style(:default) end def to_h {exception: @exception, root: @root} end def format(output, terminal, verbose) format_exception(@exception, nil, output, terminal, verbose) end def format_exception(exception, prefix, output, terminal, verbose) lines = exception.message.lines.map(&:chomp) output.puts " #{prefix}#{terminal[:exception_title]}#{exception.class}#{terminal.reset}: #{lines.shift}" lines.each do |line| output.puts " #{terminal[:exception_detail]}#{line}#{terminal.reset}" end root_pattern = /^#{@root}\// if @root exception.backtrace&.each_with_index do |line, index| path, offset, message = line.split(":") style = :exception_backtrace # Make the path a bit more readable if root_pattern and path.sub!(root_pattern, "").nil? style = :exception_backtrace_other end output.puts " #{index == 0 ? "→" : " "} #{terminal[style]}#{path}:#{offset}#{terminal[:exception_message]} #{message}#{terminal.reset}" end if exception.cause format_exception(exception.cause, "Caused by ", output, terminal, verbose) end end end end end ruby-console-1.15.3/lib/console/event/generic.rb000066400000000000000000000026101423731167600215250ustar00rootroot00000000000000# frozen_string_literal: true # Copyright, 2019, by Samuel G. D. Williams. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. module Console module Event class Generic def self.register(terminal) end def to_h end def to_json(*arguments) JSON.generate([self.class, to_h], *arguments) end def format(buffer, terminal) end end end end ruby-console-1.15.3/lib/console/event/measure.rb000066400000000000000000000030001423731167600215440ustar00rootroot00000000000000# frozen_string_literal: true # Copyright, 2017, by Samuel G. D. Williams. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. require_relative 'metric' require_relative '../clock' module Console module Event class Enter < Generic def initialize(name) @name = name end def format(output, terminal, verbose) output.puts "→ #{@name}" end end class Exit < Metric def value_string "← #{@name} took #{Clock.formatted_duration(@value)}" end end end end ruby-console-1.15.3/lib/console/event/metric.rb000066400000000000000000000034221423731167600213760ustar00rootroot00000000000000# frozen_string_literal: true # Copyright, 2017, by Samuel G. D. Williams. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. require_relative 'generic' require_relative '../clock' module Console module Event class Metric < Generic def self.[](**parameters) parameters.map(&self.method(:new)) end def initialize(name, value, **tags) @name = name @value = value @tags = tags end attr :name attr :value attr :tags def to_h {name: @name, value: @value, tags: @tags} end def value_string "#{@name}: #{@value}" end def format(output, terminal, verbose) if @tags&.any? output.puts "#{value_string} #{@tags.inspect}" else output.puts value_string end end end end end ruby-console-1.15.3/lib/console/event/progress.rb000066400000000000000000000042451423731167600217630ustar00rootroot00000000000000# frozen_string_literal: true # Copyright, 2017, by Samuel G. D. Williams. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. require_relative 'generic' module Console module Event class Progress < Generic BLOCK = [ " ", "▏", "▎", "▍", "▌", "▋", "▊", "▉", "█", ] def initialize(current, total) @current = current @total = total end attr :current attr :total def value @current.to_f / @total.to_f end def bar(value = self.value, width = 70) blocks = width * value full_blocks = blocks.floor partial_block = ((blocks - full_blocks) * BLOCK.size).floor if partial_block.zero? BLOCK.last * full_blocks else "#{BLOCK.last * full_blocks}#{BLOCK[partial_block]}" end.ljust(width) end def self.register(terminal) terminal[:progress_bar] ||= terminal.style(:blue, :white) end def to_h {current: @current, total: @total} end def format(output, terminal, verbose) output.puts "#{terminal[:progress_bar]}#{self.bar}#{terminal.reset} #{sprintf('%6.2f', self.value * 100)}%" end end end end ruby-console-1.15.3/lib/console/event/spawn.rb000066400000000000000000000050071423731167600212440ustar00rootroot00000000000000# frozen_string_literal: true # Copyright, 2017, by Samuel G. D. Williams. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. require_relative 'generic' module Console module Event class Spawn < Generic def self.for(*arguments, **options) # Extract out the command environment: if arguments.first.is_a?(Hash) environment = arguments.shift self.new(environment, arguments, options) else self.new(nil, arguments, options) end end def initialize(environment, arguments, options) @environment = environment @arguments = arguments @options = options end attr :environment attr :arguments attr :options def chdir_string(options) if options and chdir = options[:chdir] " in #{chdir}" end end def self.register(terminal) terminal[:shell_command] ||= terminal.style(:blue, nil, :bold) end def to_h Hash.new.tap do |hash| hash[:environment] = @environment if @environment&.any? hash[:arguments] = @arguments if @arguments&.any? hash[:options] = @options if @options&.any? end end def format(output, terminal, verbose) arguments = @arguments.flatten.collect(&:to_s) output.puts " #{terminal[:shell_command]}#{arguments.join(' ')}#{terminal.reset}#{chdir_string(options)}" if verbose and @environment @environment.each do |key, value| output.puts " export #{key}=#{value}" end end end end end # Deprecated. Shell = Event::Spawn end ruby-console-1.15.3/lib/console/filter.rb000066400000000000000000000074351423731167600202670ustar00rootroot00000000000000# frozen_string_literal: true # Copyright, 2017, by Samuel G. D. Williams. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. require_relative 'buffer' module Console UNKNOWN = 'unknown' class Filter def self.[] **levels klass = Class.new(self) min_level, max_level = levels.values.minmax klass.instance_exec do const_set(:LEVELS, levels) const_set(:MINIMUM_LEVEL, min_level) const_set(:MAXIMUM_LEVEL, max_level) levels.each do |name, level| const_set(name.to_s.upcase, level) define_method(name) do |subject = nil, *arguments, **options, &block| if self.enabled?(subject, level) self.call(subject, *arguments, severity: name, **options, **@options, &block) end end define_method("#{name}!") do @level = level end define_method("#{name}?") do @level <= level end end end return klass end def initialize(output, verbose: true, level: self.class::DEFAULT_LEVEL, enabled: nil, **options) @output = output @verbose = verbose @level = level @subjects = {} @options = options if enabled enabled.each{|name| enable(name)} end end def with(level: @level, verbose: @verbose, **options) dup.tap do |logger| logger.level = level logger.verbose! if verbose logger.options = @options.merge(options) end end attr_accessor :output attr :verbose attr :level attr :subjects attr_accessor :options def level= level if level.is_a? Symbol @level = self.class::LEVELS[level] else @level = level end end def verbose!(value = true) @verbose = value @output.verbose!(value) end def off! @level = self.class::MAXIMUM_LEVEL + 1 end def all! @level = self.class::MINIMUM_LEVEL - 1 end # You can enable and disable logging for classes. This function checks if logging for a given subject is enabled. # @param subject [Object] the subject to check. def enabled?(subject, level = self.class::MINIMUM_LEVEL) if specific_level = @subjects[subject.class] return level >= specific_level end if level >= @level return true end end # Enable specific log level for the given class. # @param name [String, Class] The class to enable. def enable(subject, level = self.class::MINIMUM_LEVEL) unless subject.is_a?(Class) subject = subject.class end @subjects[subject] = level end # Disable specific logging for the specific class. # @param name [String, Class] The class to disable. def disable(subject) unless subject.is_a? Class subject = subject.class end @subjects.delete(subject) end def call(*arguments, **options, &block) @output.call(*arguments, **options, &block) end end end ruby-console-1.15.3/lib/console/logger.rb000066400000000000000000000060051423731167600202510ustar00rootroot00000000000000# frozen_string_literal: true # Copyright, 2017, by Samuel G. D. Williams. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. require_relative 'output' require_relative 'filter' require_relative 'measure' require_relative 'progress' require_relative 'resolver' require_relative 'terminal/logger' require_relative 'serialized/logger' require 'fiber/local' module Console class Logger < Filter[debug: 0, info: 1, warn: 2, error: 3, fatal: 4] extend Fiber::Local # Set the default log level based on `$DEBUG` and `$VERBOSE`. # You can also specify CONSOLE_LEVEL=debug or CONSOLE_LEVEL=info in environment. # https://mislav.net/2011/06/ruby-verbose-mode/ has more details about how it all fits together. def self.default_log_level(env = ENV) if level = env['CONSOLE_LEVEL'] LEVELS[level.to_sym] || level.to_i elsif $DEBUG DEBUG elsif $VERBOSE.nil? WARN else INFO end end # Controls verbose output using `$VERBOSE`. def self.verbose?(env = ENV) !$VERBOSE.nil? || env['CONSOLE_VERBOSE'] end def self.default_logger(output = $stderr, env = ENV, **options) if options[:verbose].nil? options[:verbose] = self.verbose?(env) end if options[:level].nil? options[:level] = self.default_log_level(env) end output = Output.new(output, env, **options) logger = self.new(output, **options) Resolver.default_resolver(logger) return logger end def self.local self.default_logger end DEFAULT_LEVEL = 1 def initialize(output, **options) super(output, **options) end def progress(subject, total, **options) Progress.new(self, subject, total, **options) end def measure(subject, name = "block", **tags, &block) measure = Measure.new(self, subject, **tags) if block_given? return measure.duration(name, &block) else return measure end end def failure(subject, exception, *arguments, &block) fatal(subject, *arguments, Event::Failure.new(exception), &block) end end end ruby-console-1.15.3/lib/console/measure.rb000066400000000000000000000032601423731167600204330ustar00rootroot00000000000000# frozen_string_literal: true # Copyright, 2017, by Samuel G. D. Williams. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. require_relative 'event/measure' require_relative 'clock' module Console class Measure def initialize(output, subject, **tags) @output = output @subject = subject @tags = tags end attr :tags # Measure the execution of a block of code. def duration(name, &block) @output.info(@subject) {Event::Enter.new(name)} start_time = Clock.now result = yield(self) duration = Clock.now - start_time @output.info(@subject) {Event::Exit.new(name, duration, **@tags)} return result end end end ruby-console-1.15.3/lib/console/output.rb000066400000000000000000000031421423731167600203310ustar00rootroot00000000000000# frozen_string_literal: true # Copyright, 2021, by Samuel G. D. Williams. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. require_relative 'output/default' require_relative 'output/json' require_relative 'output/text' require_relative 'output/xterm' module Console module Output def self.new(output = nil, env = ENV, **options) if names = env['CONSOLE_OUTPUT'] names = names.split(',').reverse names.inject(output) do |output, name| Output.const_get(name).new(output, **options) end else return Output::Default.new(output, **options) end end end end ruby-console-1.15.3/lib/console/output/000077500000000000000000000000001423731167600200045ustar00rootroot00000000000000ruby-console-1.15.3/lib/console/output/default.rb000066400000000000000000000026511423731167600217610ustar00rootroot00000000000000# frozen_string_literal: true # Copyright, 2021, by Samuel G. D. Williams. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. require_relative 'xterm' require_relative 'json' module Console module Output module Default def self.new(output, **options) output ||= $stderr if output.tty? XTerm.new(output, **options) else JSON.new(output, **options) end end end end end ruby-console-1.15.3/lib/console/output/json.rb000066400000000000000000000025301423731167600213020ustar00rootroot00000000000000# frozen_string_literal: true # Copyright, 2021, by Samuel G. D. Williams. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. require_relative '../serialized/logger' module Console module Output module JSON def self.new(output, **options) Serialized::Logger.new(output, format: ::JSON, **options) end end end end ruby-console-1.15.3/lib/console/output/sensitive.rb000066400000000000000000000055261423731167600223520ustar00rootroot00000000000000# frozen_string_literal: true # Copyright, 2021, by Samuel G. D. Williams. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. require_relative '../serialized/logger' module Console module Output class Sensitive def initialize(output, **options) @output = output end REDACT = / phone | email | full_?name | first_?name | last_?name | device_name | user_agent | zip | address | location | latitude | longitude | ip | gps | sex | gender | token | password /xi def redact?(text) text.match?(REDACT) end def redact_hash(arguments, filter) arguments.transform_values do |value| redact(value, filter) end end def redact_array(array, filter) array.map do |value| redact(value, filter) end end def redact(argument, filter) case argument when String if filter filter.call(argument) elsif redact?(argument) "[REDACTED]" else argument end when Array redact_array(argument, filter) when Hash redact_hash(argument, filter) else redact(argument.to_s, filter) end end class Filter def initialize(substitutions) @substitutions = substitutions @pattern = Regexp.union(substitutions.keys) end def call(text) text.gsub(@pattern, @substitutions) end end def call(subject = nil, *arguments, sensitive: true, **options, &block) if sensitive if sensitive.respond_to?(:call) filter = sensitive elsif sensitive.is_a?(Hash) filter = Filter.new(sensitive) end subject = redact(subject, filter) arguments = redact_array(arguments, filter) end @output.call(subject, *arguments, **options) end end end end ruby-console-1.15.3/lib/console/output/text.rb000066400000000000000000000025341423731167600213210ustar00rootroot00000000000000# frozen_string_literal: true # Copyright, 2021, by Samuel G. D. Williams. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. require_relative '../terminal/logger' module Console module Output module Text def self.new(output, **options) Terminal::Logger.new(output, format: Terminal::Text, **options) end end end end ruby-console-1.15.3/lib/console/output/xterm.rb000066400000000000000000000025361423731167600214760ustar00rootroot00000000000000# frozen_string_literal: true # Copyright, 2021, by Samuel G. D. Williams. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. require_relative '../terminal/logger' module Console module Output module XTerm def self.new(output, **options) Terminal::Logger.new(output, format: Terminal::XTerm, **options) end end end end ruby-console-1.15.3/lib/console/progress.rb000066400000000000000000000060251423731167600206400ustar00rootroot00000000000000# frozen_string_literal: true # Copyright, 2019, by Samuel G. D. Williams. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. require_relative 'event/progress' require_relative 'clock' module Console class Progress def self.now Process.clock_gettime(Process::CLOCK_MONOTONIC) end def initialize(output, subject, total = 0, minimum_output_duration: 1.0) @output = output @subject = subject @start_time = Progress.now @last_output_time = nil @minimum_output_duration = 0.1 @current = 0 @total = total end attr :subject attr :current attr :total def duration Progress.now - @start_time end def progress @current.to_f / @total.to_f end def remaining @total - @current end def average_duration if @current > 0 duration / @current end end def estimated_remaining_time if average_duration = self.average_duration average_duration * remaining end end def increment(amount = 1) @current += amount if output? @output.info(@subject, self) {Event::Progress.new(@current, @total)} @last_output_time = Progress.now end return self end def resize(total) @total = total @output.info(@subject, self) {Event::Progress.new(@current, @total)} @last_output_time = Progress.now return self end def mark(*arguments) @output.info(@subject, *arguments) end def to_s if estimated_remaining_time = self.estimated_remaining_time "#{@current}/#{@total} completed in #{Clock.formatted_duration(self.duration)}, #{Clock.formatted_duration(estimated_remaining_time)} remaining." else "#{@current}/#{@total} completed, waiting for estimate..." end end private def duration_since_last_output if @last_output_time Progress.now - @last_output_time end end def output? if remaining.zero? return true elsif duration = duration_since_last_output return duration > @minimum_output_duration else return true end end end end ruby-console-1.15.3/lib/console/resolver.rb000066400000000000000000000070331423731167600206350ustar00rootroot00000000000000# frozen_string_literal: true # Copyright, 2017, by Samuel G. D. Williams. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. require_relative 'filter' module Console class Resolver # You can change the log level for different classes using CONSOLE_$LEVEL env vars. # # e.g. `CONSOLE_WARN=Acorn,Banana CONSOLE_DEBUG=Cat` will set the log level for the classes Acorn and Banana to `warn` and Cat to `debug`. This overrides the default log level. # # You can enable all log levels for a given class by using `CONSOLE_ON=MyClass`. Similarly you can disable all logging using `CONSOLE_OFF=MyClass`. # # @parameter logger [Logger] A logger instance to set the logging levels on. # @parameter env [Hash] The environment to read levels from. # # @returns [Nil] If there were no custom logging levels specified in the environment. # @returns [Resolver] If there were custom logging levels, then the created resolver is returned. def self.default_resolver(logger, env = ENV) # Find all CONSOLE_$LEVEL variables from environment: levels = logger.class::LEVELS .map{|label, level| [level, env["CONSOLE_#{label.upcase}"]&.split(',')]} .to_h .compact off_klasses = env['CONSOLE_OFF']&.split(',') on_klasses = env['CONSOLE_ON']&.split(',') resolver = nil # If we have any levels, then create a class resolver, and each time a class is resolved, set the log level for that class to the specified level: if on_klasses&.any? resolver ||= Resolver.new resolver.bind(on_klasses) do |klass| logger.enable(klass, logger.class::MINIMUM_LEVEL - 1) end end if off_klasses&.any? resolver ||= Resolver.new resolver.bind(off_klasses) do |klass| logger.disable(klass) end end levels.each do |level, names| resolver ||= Resolver.new resolver.bind(names) do |klass| logger.enable(klass, level) end end return resolver end def initialize @names = {} @trace_point = TracePoint.new(:class, &self.method(:resolve)) end def bind(names, &block) names.each do |name| if klass = Object.const_get(name) rescue nil yield klass else @names[name] = block end end if @names.any? @trace_point.enable else @trace_point.disable end end def waiting? @trace_point.enabled? end def resolve(trace_point) if block = @names.delete(trace_point.self.to_s) block.call(trace_point.self) end if @names.empty? @trace_point.disable end end end end ruby-console-1.15.3/lib/console/serialized/000077500000000000000000000000001423731167600205775ustar00rootroot00000000000000ruby-console-1.15.3/lib/console/serialized/logger.rb000066400000000000000000000057421423731167600224130ustar00rootroot00000000000000# frozen_string_literal: true # Copyright, 2017, by Samuel G. D. Williams. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. require_relative '../buffer' require_relative '../filter' require 'time' require 'json' module Console module Serialized class Logger def initialize(io = $stderr, format: JSON, verbose: false, **options) @io = io @start = Time.now @format = format @verbose = verbose end attr :io attr :start attr :format def verbose!(value = true) @verbose = true end def dump(record) @format.dump(record) end def call(subject = nil, *arguments, severity: UNKNOWN, **options, &block) record = { time: Time.now.iso8601, severity: severity, class: subject.class, oid: subject.object_id, pid: Process.pid, } if subject record[:subject] = subject end message = arguments if block_given? if block.arity.zero? message << yield else buffer = StringIO.new yield buffer message << buffer.string end end if message.size == 1 record[:message] = message.first elsif message.any? record[:message] = message end if exception = find_exception(message) record[:error] = { kind: exception.class, message: exception.message, stack: format_stack(exception) } end record.update(options) @io.puts(self.dump(record)) end private def find_exception(message) message.find{|part| part.is_a?(Exception)} end def format_stack(exception) buffer = StringIO.new format_backtrace(exception, buffer) return buffer.string end def format_backtrace(exception, buffer) buffer.puts exception.backtrace if exception = exception.cause buffer.puts buffer.puts "Caused by: #{exception.class} #{exception.message}" format_backtrace(exception, buffer) end end end end end ruby-console-1.15.3/lib/console/split.rb000066400000000000000000000030401423731167600201210ustar00rootroot00000000000000# frozen_string_literal: true # Copyright, 2017, by Samuel G. D. Williams. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. module Console class Split def self.[] *outputs self.new(outputs) end def initialize(outputs) @outputs = outputs end def verbose!(value = true) @outputs.each{|output| output.verbose!(value)} end def call(level, subject = nil, *arguments, **options, &block) @outputs.each do |output| output.call(level, subject, *arguments, **options, &block) end end end end ruby-console-1.15.3/lib/console/terminal.rb000066400000000000000000000022571423731167600206120ustar00rootroot00000000000000# frozen_string_literal: true # Copyright, 2019, by Samuel G. D. Williams. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. require_relative 'terminal/logger' ruby-console-1.15.3/lib/console/terminal/000077500000000000000000000000001423731167600202575ustar00rootroot00000000000000ruby-console-1.15.3/lib/console/terminal/logger.rb000066400000000000000000000132041423731167600220630ustar00rootroot00000000000000# frozen_string_literal: true # Copyright, 2017, by Samuel G. D. Williams. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. require_relative '../buffer' require_relative '../event' require_relative 'text' require_relative 'xterm' require 'json' require 'fiber' module Console module Terminal # This, and all related methods, is considered private. CONSOLE_START_AT = 'CONSOLE_START_AT' # Exports CONSOLE_START which can be used to synchronize the start times of all child processes when they log using delta time. def self.start_at!(environment = ENV) if time_string = environment[CONSOLE_START_AT] start_at = Time.parse(time_string) rescue nil end unless start_at start_at = Time.now environment[CONSOLE_START_AT] = start_at.to_s end return start_at end def self.for(io) if io.isatty XTerm.new(io) else Text.new(io) end end class Logger def initialize(io = $stderr, verbose: nil, start_at: Terminal.start_at!, format: nil, **options) @io = io @start_at = start_at @terminal = format.nil? ? Terminal.for(io) : format.new(io) if verbose.nil? @verbose = !@terminal.colors? else @verbose = verbose end @terminal[:logger_suffix] ||= @terminal.style(:white, nil, :faint) @terminal[:subject] ||= @terminal.style(nil, nil, :bold) @terminal[:debug] = @terminal.style(:cyan) @terminal[:info] = @terminal.style(:green) @terminal[:warn] = @terminal.style(:yellow) @terminal[:error] = @terminal.style(:red) @terminal[:fatal] = @terminal[:error] self.register_defaults(@terminal) end attr :io attr_accessor :verbose attr :start attr :terminal def verbose!(value = true) @verbose = value end def register_defaults(terminal) Event.constants.each do |constant| klass = Event.const_get(constant) klass.register(terminal) end end UNKNOWN = :unknown def call(subject = nil, *arguments, name: nil, severity: UNKNOWN, **options, &block) prefix = build_prefix(name || severity.to_s) indent = " " * prefix.size buffer = Buffer.new("#{indent}| ") if subject format_subject(severity, prefix, subject, buffer) end if options&.any? format_options(options, buffer) end arguments.each do |argument| format_argument(argument, buffer) end if block_given? if block.arity.zero? format_argument(yield, buffer) else yield(buffer, @terminal) end end @io.write buffer.string end protected def format_options(options, output) format_value(options.to_json, output) end def format_argument(argument, output) case argument when Exception Event::Failure.for(argument).format(output, @terminal, @verbose) when Event::Generic argument.format(output, @terminal, @verbose) else format_value(argument, output) end end def format_subject(severity, prefix, subject, buffer) if subject.is_a?(String) format_string_subject(severity, prefix, subject, buffer) elsif subject.is_a?(Module) format_string_subject(severity, prefix, subject.to_s, buffer) else format_object_subject(severity, prefix, subject, buffer) end end def default_suffix(object = nil) buffer = +" #{@terminal[:logger_suffix]}" if object buffer << "[oid=0x#{object.object_id.to_s(16)}] " end buffer << "[ec=0x#{Fiber.current.object_id.to_s(16)}] [pid=#{Process.pid}] [#{::Time.now}]#{@terminal.reset}" end def format_object_subject(severity, prefix, subject, output) prefix_style = @terminal[severity] if @verbose suffix = default_suffix(subject) end prefix = "#{prefix_style}#{prefix}:#{@terminal.reset} " output.puts "#{@terminal[:subject]}#{subject.class}#{@terminal.reset}#{suffix}", prefix: prefix end def format_string_subject(severity, prefix, subject, output) prefix_style = @terminal[severity] if @verbose suffix = default_suffix end prefix = "#{prefix_style}#{prefix}:#{@terminal.reset} " output.puts "#{@terminal[:subject]}#{subject}#{@terminal.reset}#{suffix}", prefix: prefix end def format_value(value, output) string = value.to_s string.each_line do |line| output.puts "#{line}" end end def time_offset_prefix Clock.formatted_duration(Time.now - @start_at).rjust(6) end def build_prefix(name) if @verbose "#{time_offset_prefix} #{name.rjust(8)}" else time_offset_prefix end end end end end ruby-console-1.15.3/lib/console/terminal/text.rb000066400000000000000000000052541423731167600215760ustar00rootroot00000000000000# frozen_string_literal: true # Copyright, 2019, by Samuel G. D. Williams. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. require 'io/console' module Console # Styled terminal output. module Terminal class Text def initialize(output) @output = output @styles = {reset: self.reset} end def [] key @styles[key] end def []= key, value @styles[key] = value end def colors? false end def style(foreground, background = nil, *attributes) end def reset end def write(*arguments, style: nil) if style and prefix = self[style] @output.write(prefix) @output.write(*arguments) @output.write(self.reset) else @output.write(*arguments) end end def puts(*arguments, style: nil) if style and prefix = self[style] @output.write(prefix) @output.puts(*arguments) @output.write(self.reset) else @output.puts(*arguments) end end # Print out the given arguments. # When the argument is a symbol, look up the style and inject it into the output stream. # When the argument is a proc/lambda, call it with self as the argument. # When the argument is anything else, write it directly to the output. def print(*arguments) arguments.each do |argument| case argument when Symbol @output.write(self[argument]) when Proc argument.call(self) else @output.write(argument) end end end # Print out the arguments as per {#print}, followed by the reset sequence and a newline. def print_line(*arguments) print(*arguments) @output.puts(self.reset) end end end end ruby-console-1.15.3/lib/console/terminal/xterm.rb000066400000000000000000000041001423731167600217360ustar00rootroot00000000000000# frozen_string_literal: true # Copyright, 2019, by Samuel G. D. Williams. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. require 'io/console' require_relative 'text' module Console # Styled terminal output. module Terminal class XTerm < Text COLORS = { black: 0, red: 1, green: 2, yellow: 3, blue: 4, magenta: 5, cyan: 6, white: 7, default: 9, } ATTRIBUTES = { normal: 0, bold: 1, bright: 1, faint: 2, italic: 3, underline: 4, blink: 5, reverse: 7, hidden: 8, } def colors? true end def size @output.winsize end def style(foreground, background = nil, *attributes) tokens = [] if foreground tokens << 30 + COLORS.fetch(foreground) end if background tokens << 40 + COLORS.fetch(background) end attributes.each do |attribute| tokens << ATTRIBUTES.fetch(attribute){attribute.to_i} end return "\e[#{tokens.join(';')}m" end def reset "\e[0m" end end end end ruby-console-1.15.3/lib/console/version.rb000066400000000000000000000022631423731167600204610ustar00rootroot00000000000000# frozen_string_literal: true # Copyright, 2019, by Samuel G. D. Williams. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. module Console VERSION = "1.15.3" end ruby-console-1.15.3/release.cert000066400000000000000000000031331423731167600165330ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIIEhDCCAuygAwIBAgIBATANBgkqhkiG9w0BAQsFADA3MTUwMwYDVQQDDCxzYW11 ZWwud2lsbGlhbXMvREM9b3Jpb250cmFuc2Zlci9EQz1jby9EQz1uejAeFw0yMTA4 MTYwNjMzNDRaFw0yMjA4MTYwNjMzNDRaMDcxNTAzBgNVBAMMLHNhbXVlbC53aWxs aWFtcy9EQz1vcmlvbnRyYW5zZmVyL0RDPWNvL0RDPW56MIIBojANBgkqhkiG9w0B AQEFAAOCAY8AMIIBigKCAYEAyXLSS/cw+fXJ5e7hi+U/TeChPWeYdwJojDsFY1xr xvtqbTTL8gbLHz5LW3QD2nfwCv3qTlw0qI3Ie7a9VMJMbSvgVEGEfQirqIgJXWMj eNMDgKsMJtC7u/43abRKx7TCURW3iWyR19NRngsJJmaR51yGGGm2Kfsr+JtKKLtL L188Wm3f13KAx7QJU8qyuBnj1/gWem076hzdA7xi1DbrZrch9GCRz62xymJlrJHn 9iZEZ7AxrS7vokhMlzSr/XMUihx/8aFKtk+tMLClqxZSmBWIErWdicCGTULXCBNb E/mljo4zEVKhlTWpJklMIhr55ZRrSarKFuW7en0+tpJrfsYiAmXMJNi4XAYJH7uL rgJuJwSaa/dMz+VmUoo7VKtSfCoOI+6v5/z0sK3oT6sG6ZwyI47DBq2XqNC6tnAj w+XmCywiTQrFzMMAvcA7rPI4F0nU1rZId51rOvvfxaONp+wgTi4P8owZLw0/j0m4 8C20DYi6EYx4AHDXiLpElWh3AgMBAAGjgZowgZcwCQYDVR0TBAIwADALBgNVHQ8E BAMCBLAwHQYDVR0OBBYEFB6ZaeWKxQjGTI+pmz7cKRmMIywwMC4GA1UdEQQnMCWB I3NhbXVlbC53aWxsaWFtc0BvcmlvbnRyYW5zZmVyLmNvLm56MC4GA1UdEgQnMCWB I3NhbXVlbC53aWxsaWFtc0BvcmlvbnRyYW5zZmVyLmNvLm56MA0GCSqGSIb3DQEB CwUAA4IBgQBVoM+pu3dpdUhZM1w051iw5GfiqclAr1Psypf16Tiod/ho//4oAu6T 9fj3DPX/acWV9P/FScvqo4Qgv6g4VWO5ZU7z2JmPoTXZtYMunRAmQPFL/gSUc6aK vszMHIyhtyzRc6DnfW2AiVOjMBjaYv8xXZc9bduniRVPrLR4J7ozmGLh4o4uJp7w x9KCFaR8Lvn/r0oJWJOqb/DMAYI83YeN2Dlt3jpwrsmsONrtC5S3gOUle5afSGos bYt5ocnEpKSomR9ZtnCGljds/aeO1Xgpn2r9HHcjwnH346iNrnHmMlC7BtHUFPDg Ts92S47PTOXzwPBDsrFiq3VLbRjHSwf8rpqybQBH9MfzxGGxTaETQYOd6b4e4Ag6 y92abGna0bmIEb4+Tx9rQ10Uijh1POzvr/VTH4bbIPy9FbKrRsIQ24qDbNJRtOpE RAOsIl+HOBTb252nx1kIRN5hqQx272AJCbCjKx8egcUQKffFVVCI0nye09v5CK+a HiLJ8VOFx6w= -----END CERTIFICATE----- ruby-console-1.15.3/spec/000077500000000000000000000000001423731167600151665ustar00rootroot00000000000000ruby-console-1.15.3/spec/console/000077500000000000000000000000001423731167600166305ustar00rootroot00000000000000ruby-console-1.15.3/spec/console/capture_spec.rb000066400000000000000000000027351423731167600216410ustar00rootroot00000000000000# frozen_string_literal: true # Copyright, 2019, by Samuel G. D. Williams. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. require 'console/capture' RSpec.describe Console::Capture do subject {described_class.new} let(:logger) {Console::Logger.new(subject)} describe '#buffer' do it 'can access log buffer' do logger.info("Hello World!") last = subject.last expect(last).to include(severity: :info, subject: "Hello World!") end end end ruby-console-1.15.3/spec/console/compatible/000077500000000000000000000000001423731167600207475ustar00rootroot00000000000000ruby-console-1.15.3/spec/console/compatible/logger_spec.rb000066400000000000000000000031061423731167600235650ustar00rootroot00000000000000# frozen_string_literal: true # Copyright, 2019, by Samuel G. D. Williams. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. require 'console/compatible/logger' RSpec.describe Console::Compatible::Logger do let(:io) {StringIO.new} let(:output) {Console::Terminal::Logger.new(io)} let(:logger) {Console::Compatible::Logger.new("Test", output)} it "should log messages" do logger.info("Hello World") expect(io.string).to include("Hello World") end it "formats lower case severity string" do expect(logger.format_severity(1)).to be == :info end end ruby-console-1.15.3/spec/console/console_spec.rb000066400000000000000000000044631423731167600216400ustar00rootroot00000000000000# frozen_string_literal: true # Copyright, 2019, by Samuel G. D. Williams. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. require 'console' require_relative 'my_module' RSpec.describe Console do context MyModule do let(:io) {StringIO.new} let(:logger) {Console::Logger.new(Console::Terminal::Logger.new(io))} it "should log some messages" do MyModule.logger = logger MyModule.test_logger expect(io.string).to_not include("GOTO LINE 1") expect(io.string).to include("There be the dragons!") end it "should show debug messages" do MyModule.logger = logger MyModule.logger.debug! MyModule.test_logger expect(io.string).to include("GOTO LINE 1") end it "should log nested exceptions" do MyModule.logger = logger MyModule.logger.verbose! MyModule.log_error expect(io.string).to include("Caused by ArgumentError: It broken!") expect(MyModule.logger.debug?).to be == false expect(MyModule.logger.info?).to be == true end end describe '#logger' do let!(:original_logger) {described_class.logger} after do described_class.logger = original_logger end it 'sets and returns a logger' do logger = double(:logger) described_class.logger = logger expect(described_class.logger).to be(logger) end end end ruby-console-1.15.3/spec/console/event/000077500000000000000000000000001423731167600177515ustar00rootroot00000000000000ruby-console-1.15.3/spec/console/event/failure_spec.rb000066400000000000000000000043051423731167600227410ustar00rootroot00000000000000# frozen_string_literal: true require 'console' require 'console/capture' RSpec.describe Console::Event::Failure do let(:output) {StringIO.new} let(:terminal) {Console::Terminal.for(output)} let(:error) { RuntimeError.new("Test").tap {|e| e.set_backtrace([ "(irb):2:in `rescue in irb_binding'", "(irb):1:in `irb_binding'", "/path/to/root/.gem/ruby/2.5.7/gems/irb-1.2.7/lib/irb/workspace.rb:114:in `eval'", "/path/to/root/.gem/ruby/2.5.7/gems/irb-1.2.7/lib/irb/workspace.rb:114:in `evaluate'", "/path/to/root/.gem/ruby/2.5.7/gems/irb-1.2.7/lib/irb/context.rb:450:in `evaluate'", "/path/to/root/.gem/ruby/2.5.7/gems/irb-1.2.7/lib/irb.rb:541:in `block (2 levels) in eval_input'", "/path/to/root/.gem/ruby/2.5.7/gems/irb-1.2.7/lib/irb.rb:704:in `signal_status'", "/path/to/root/.gem/ruby/2.5.7/gems/irb-1.2.7/lib/irb.rb:538:in `block in eval_input'", "/path/to/root/.gem/ruby/2.5.7/gems/irb-1.2.7/lib/irb/ruby-lex.rb:166:in `block (2 levels) in each_top_level_statement'", "/path/to/root/.gem/ruby/2.5.7/gems/irb-1.2.7/lib/irb/ruby-lex.rb:151:in `loop'", "/path/to/root/.gem/ruby/2.5.7/gems/irb-1.2.7/lib/irb/ruby-lex.rb:151:in `block in each_top_level_statement'", "/path/to/root/.gem/ruby/2.5.7/gems/irb-1.2.7/lib/irb/ruby-lex.rb:150:in `catch'", "/path/to/root/.gem/ruby/2.5.7/gems/irb-1.2.7/lib/irb/ruby-lex.rb:150:in `each_top_level_statement'", "/path/to/root/.gem/ruby/2.5.7/gems/irb-1.2.7/lib/irb.rb:537:in `eval_input'", "/path/to/root/.gem/ruby/2.5.7/gems/irb-1.2.7/lib/irb.rb:472:in `block in run'", "/path/to/root/.gem/ruby/2.5.7/gems/irb-1.2.7/lib/irb.rb:471:in `catch'", "/path/to/root/.gem/ruby/2.5.7/gems/irb-1.2.7/lib/irb.rb:471:in `run'", "/path/to/root/.gem/ruby/2.5.7/gems/irb-1.2.7/lib/irb.rb:400:in `start'", "/path/to/root/.gem/ruby/2.5.7/gems/irb-1.2.7/exe/irb:11:in `'", "/path/to/root/.gem/ruby/2.5.7/bin/irb:23:in `load'", "/path/to/root/.gem/ruby/2.5.7/bin/irb:23:in `
'" ]) } } it "formats exception removing root path" do event = Console::Event::Failure.new(error, "/path/to/root") event.format(output, terminal, true) expect(output.string.lines[3..-1]).to all match(/^\s+\.gem/) end end ruby-console-1.15.3/spec/console/event/metric_spec.rb000066400000000000000000000027331423731167600226000ustar00rootroot00000000000000# frozen_string_literal: true # Copyright, 2019, by Samuel G. D. Williams. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. require 'console' require 'console/capture' RSpec.describe Console::Event::Metric do let(:output) {Console::Capture.new} let(:logger) {Console::Logger.new(output)} let(:event) {described_class.new(:x, 10)} it "can log event" do logger.info(self, event) expect(output.last).to include( arguments: [event], ) end end ruby-console-1.15.3/spec/console/logger_spec.rb000066400000000000000000000101071423731167600214450ustar00rootroot00000000000000# frozen_string_literal: true # Copyright, 2018, by Samuel G. D. Williams. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. require 'console/logger' require 'console/capture' RSpec.describe Console::Logger do let(:output) {Console::Capture.new} subject{described_class.new(output)} let(:message) {"Hello World"} describe '#with' do let(:nested) {subject.with(name: "nested", level: :debug)} it "should change level" do expect(nested.level).to be == 0 end it "should change name" do expect(nested.options[:name]).to be == "nested" end it "logs message with name" do nested.error(message) expect(output.last).to include( name: "nested", subject: message, ) end end context "with level" do let(:level) {0} subject{described_class.new(output, level: level)} it "should have specified log level" do expect(subject.level).to be == level end end context "default log level" do it "logs info" do expect(output).to receive(:call).with(message, severity: :info) subject.info(message) end it "doesn't log debug" do expect(output).to_not receive(:call) subject.debug(message) end end described_class::LEVELS.each do |name, level| it "can log #{name} messages" do expect(output).to receive(:call).with(message, severity: name) subject.level = level subject.send(name, message) end end describe '#enable' do let(:object) {Object.new} it "can enable specific subjects" do subject.warn! subject.enable(object) expect(subject).to be_enabled(object) expect(output).to receive(:call).with(object, message, severity: :debug) subject.debug(object, message) end end describe "#off!" do before do subject.off! end described_class::LEVELS.each do |name, level| it "doesn't log #{name} messages" do expect(output).to_not receive(:call) subject.send(name, message) expect(subject.send("#{name}?")).to be == false end end end describe "#all!" do before do subject.all! end described_class::LEVELS.each do |name, level| it "can log #{name} messages" do expect(output).to receive(:call).with(message, severity: name) subject.send(name, message) expect(subject.send("#{name}?")).to be == true end end end describe '.default_log_level' do let!(:debug) {$DEBUG} after {$DEBUG = debug} let!(:verbose) {$VERBOSE} after {$VERBOSE = verbose} it 'should set default log level' do $DEBUG = false $VERBOSE = 0 expect(Console::Logger.default_log_level).to be == Console::Logger::INFO end it 'should set default log level based on $DEBUG' do $DEBUG = true expect(Console::Logger.default_log_level).to be == Console::Logger::DEBUG end it 'should set default log level based on $VERBOSE' do $DEBUG = false $VERBOSE = true expect(Console::Logger.default_log_level).to be == Console::Logger::INFO end it 'can get log level from ENV' do expect(Console::Logger.default_log_level({'CONSOLE_LEVEL' => 'debug'})).to be == Console::Logger::DEBUG end end end ruby-console-1.15.3/spec/console/measure_spec.rb000066400000000000000000000032371423731167600216350ustar00rootroot00000000000000# frozen_string_literal: true # Copyright, 2019, by Samuel G. D. Williams. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. require 'console' RSpec.describe Console::Measure do describe '#increment' do it 'can create new measurement' do expect(Console.logger).to receive(:info) do |subject, &block| expect(block.call).to be_kind_of(Console::Event::Enter) expect(Console.logger).to receive(:info) do |subject, &block| expect(block.call).to be_kind_of(Console::Event::Exit) end end result = Console.logger.measure("My Measurement") do |measure| :result end expect(result).to be == :result end end end ruby-console-1.15.3/spec/console/my_module.rb000066400000000000000000000020371423731167600211510ustar00rootroot00000000000000# frozen_string_literal: true module MyModule extend Console def self.argument_error raise ArgumentError, "It broken!" end def self.nested_error argument_error rescue raise RuntimeError, "Magic smoke escaped!" end def self.log_error self.nested_error rescue logger.error(self, $!) end def self.test_logger logger.debug "1: GOTO LINE 2", "2: GOTO LINE 1" logger.info "Dear maintainer:" do |buffer| buffer.puts "Once you are done trying to 'optimize' this routine, and have realized what a terrible mistake that was, please increment the following counter as a warning to the next guy:" buffer.puts "total_hours_wasted_here = 42" end logger.warn "Something didn't work as expected!" logger.error "There be the dragons!", (raise RuntimeError, "Bits have been rotated incorrectly!" rescue $!) logger.info(self) {Console::Shell.for({LDFLAGS: "-lm"}, "gcc", "-o", "stuff.o", "stuff.c", chdir: "/tmp/compile")} logger.info(Object.new) {"Where would we be without Object.new?"} end test_logger end ruby-console-1.15.3/spec/console/output/000077500000000000000000000000001423731167600201705ustar00rootroot00000000000000ruby-console-1.15.3/spec/console/output/default_spec.rb000066400000000000000000000031351423731167600231550ustar00rootroot00000000000000# frozen_string_literal: true # Copyright, 2018, by Samuel G. D. Williams. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. require 'console/logger' require 'console/capture' RSpec.describe Console::Output::Default do let(:output) {Console::Capture.new} subject{described_class.new(output)} def final_output(output) if output.respond_to?(:output) final_output(output.output) else output end end context 'with unspecified output' do let(:output) {nil} it 'should output to $stderr by default' do expect(final_output(subject).io).to be $stderr end end end ruby-console-1.15.3/spec/console/output/sensitive_spec.rb000066400000000000000000000040721423731167600235430ustar00rootroot00000000000000# frozen_string_literal: true # Copyright, 2018, by Samuel G. D. Williams. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. require 'console/logger' require 'console/capture' require 'console/output/sensitive' RSpec.describe Console::Output::Sensitive do let(:output) {Console::Capture.new} subject{described_class.new(output)} it 'logs non-sensitive text' do subject.call("Hello World") expect(output).to include("Hello World") end it 'redacts sensitive text' do subject.call("first_name: Samuel Williams") expect(output).to_not include("Samuel Williams") end context 'with sensitive: false' do it 'bypasses redaction' do subject.call("first_name: Samuel Williams", sensitive: false) expect(output).to include("Samuel Williams") end end context 'with sensitive: Hash' do it 'filters specific tokens' do subject.call("first_name: Samuel Williams", sensitive: {"Samuel Williams" => "[First Name]"}) expect(output).to include("[First Name]") expect(output).to_not include("Samuel Williams") end end end ruby-console-1.15.3/spec/console/output_spec.rb000066400000000000000000000055441423731167600215370ustar00rootroot00000000000000# frozen_string_literal: true # Copyright, 2018, by Samuel G. D. Williams. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. require 'console/logger' require 'console/capture' class MyCustomOutput def initialize(output, **options) end end RSpec.describe Console::Output do describe '.new' do context 'when output to $stderr' do it 'should set the default to Terminal::Logger' do expect($stderr).to receive(:tty?).and_return(true) expect(Console::Output.new($stderr)).to be_a Console::Terminal::Logger end end it 'can set output to Serialized and format to JSON by ENV' do output = Console::Output.new(StringIO.new, {'CONSOLE_OUTPUT' => 'JSON'}) expect(output).to be_a Console::Serialized::Logger expect(output.format).to be == JSON end it 'can set output to Serialized using custom format by ENV' do output = Console::Output.new(StringIO.new, {'CONSOLE_OUTPUT' => 'MyCustomOutput'}) expect(output).to be_a MyCustomOutput end it 'raises error until the given format class is available' do expect { Console::Output.new(nil, {'CONSOLE_OUTPUT' => 'InvalidOutput'}) }.to raise_error(NameError, /Console::Output::InvalidOutput/) end it 'can force format to XTerm for non tty output by ENV' do io = StringIO.new expect(Console::Terminal).not_to receive(:for).with(io) output = Console::Output.new(io, {'CONSOLE_OUTPUT' => 'XTerm'}) expect(output).to be_a Console::Terminal::Logger expect(output.terminal).to be_a Console::Terminal::XTerm end it 'can force format to text for tty output by ENV using Text' do io = StringIO.new expect(Console::Terminal).not_to receive(:for).with(io) output = Console::Output.new(io, {'CONSOLE_OUTPUT' => 'Text'}) expect(output).to be_a Console::Terminal::Logger expect(output.terminal).to be_a Console::Terminal::Text end end end ruby-console-1.15.3/spec/console/progress_spec.rb000066400000000000000000000031131423731167600220310ustar00rootroot00000000000000# frozen_string_literal: true # Copyright, 2019, by Samuel G. D. Williams. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. require 'console' require 'console/progress' RSpec.describe Console::Progress do describe '#increment' do it 'can create new measurement' do progress = Console.logger.progress("My Measurement", 100) expect(progress.current).to be 0 expect(progress.total).to be 100 expect(progress.subject).to be == "My Measurement" expect(Console.logger).to receive(:info).and_call_original progress.increment(50) end end end ruby-console-1.15.3/spec/console/resolver_spec.rb000066400000000000000000000056111423731167600220330ustar00rootroot00000000000000# frozen_string_literal: true # Copyright, 2018, by Samuel G. D. Williams. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. require 'console/resolver' class Acorn; end class Banana; end class Cat; end class Dog; end RSpec.describe Console::Resolver do it "triggers when class is defined" do resolved = false subject.bind(["Console::Resolver::Foobar"]) do |klass| resolved = true end expect(subject).to be_waiting class Console::Resolver::Foobar end expect(subject).to_not be_waiting expect(resolved).to be true end it "triggers immediately if class is already defined" do resolved = false subject.bind(["Console::Resolver"]) do |klass| resolved = true end expect(subject).to_not be_waiting expect(resolved).to be true end describe '.default_resolver' do let(:logger) {Console.logger} it 'has no resolver if not required by environment' do expect(Console::Resolver.default_resolver(logger)).to be_nil end it 'can set custom log levels from environment' do expect(Console::Resolver.default_resolver(logger, {'CONSOLE_WARN' => 'Acorn,Banana', 'CONSOLE_DEBUG' => 'Cat'})).to be_a Console::Resolver expect(Console.logger.subjects[Acorn]).to be == Console::Logger::WARN expect(Console.logger.subjects[Banana]).to be == Console::Logger::WARN expect(Console.logger.subjects[Cat]).to be == Console::Logger::DEBUG end it 'can set "all" and "off" by environment' do expect(Console::Resolver.default_resolver(logger, { 'CONSOLE_ON' => 'Cat', 'CONSOLE_WARN' => 'Dog', 'CONSOLE_OFF' => 'Acorn,Banana' })).to be_a Console::Resolver expect(Console.logger.subjects[Acorn]).to be_nil expect(Console.logger.subjects[Banana]).to be_nil expect(Console.logger.subjects[Cat]).to be == Console::Logger::MINIMUM_LEVEL - 1 expect(Console.logger.subjects[Dog]).to be == Console::Logger::WARN end end end ruby-console-1.15.3/spec/console/serialized/000077500000000000000000000000001423731167600207635ustar00rootroot00000000000000ruby-console-1.15.3/spec/console/serialized/logger_spec.rb000066400000000000000000000044101423731167600236000ustar00rootroot00000000000000# frozen_string_literal: true # Copyright, 2018, by Samuel G. D. Williams. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. require 'console/serialized/logger' RSpec.describe Console::Serialized::Logger do let(:io) {StringIO.new} subject{described_class.new(io)} let(:message) {"Hello World"} let(:record) {JSON.parse(io.string, symbolize_names: true)} it "can log to buffer" do subject.call do |buffer| buffer << message end expect(record).to include :message expect(record[:message]).to be == message end it "can log options" do subject.call(name: "request-id") expect(record).to include(:name) expect(record[:name]).to be == "request-id" end context 'with structured event' do let(:event) {Console::Event::Spawn.for("ls -lah")} before do subject.call(event) end it "can log structured events" do expect(record).to include(:subject) expect(record[:subject]).to be == ["Console::Event::Spawn", {:arguments => ["ls -lah"]}] end end context 'with exception' do let(:error) {record[:error]} before do begin raise "Boom" rescue => error subject.call(self, error) end end it "can log excepion message" do expect(error).to include(:kind, :message, :stack) end end end ruby-console-1.15.3/spec/console/terminal/000077500000000000000000000000001423731167600204435ustar00rootroot00000000000000ruby-console-1.15.3/spec/console/terminal/logger_spec.rb000066400000000000000000000026751423731167600232730ustar00rootroot00000000000000# frozen_string_literal: true # Copyright, 2018, by Samuel G. D. Williams. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. require 'console/terminal/logger' RSpec.describe Console::Terminal::Logger do let(:io) {StringIO.new} subject{described_class.new(io)} let(:message) {"Hello World"} it "can log to buffer" do subject.call do |buffer| buffer << message end expect(io.string).to include message end end ruby-console-1.15.3/spec/console/terminal/xterm_spec.rb000066400000000000000000000046111423731167600231430ustar00rootroot00000000000000# frozen_string_literal: true # Copyright, 2019, by Samuel G. D. Williams. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. require 'console/terminal/xterm' RSpec.describe Console::Terminal::XTerm do let(:io) {StringIO.new} subject{described_class.new(io)} it "can generate simple style" do expect(subject.style(:blue)).to be == "\e[34m" end it "can generate complex style" do expect(subject.style(:blue, nil, :underline, :bold)).to be == "\e[34;4;1m" end it "can write text with specified style" do subject[:bold] = subject.style(nil, nil, :bold) subject.write("Hello World", style: :bold) expect(io.string).to be == "\e[1mHello World\e[0m" end it "can puts text with specified style" do subject[:bold] = subject.style(nil, nil, :bold) subject.puts("Hello World", style: :bold) expect(io.string.split(/\r?\n/)).to be == ["\e[1mHello World", "\e[0m"] end describe '#print' do it "can print using the specified style" do subject[:bold] = subject.style(nil, nil, :bold) subject.print(:bold, "Hello World") expect(io.string).to be == "\e[1mHello World" end end describe '#print_line' do it "can print a line using the specified style" do subject[:bold] = subject.style(nil, nil, :bold) subject.print_line(:bold, "Hello World") expect(io.string.split(/\r?\n/)).to be == ["\e[1mHello World\e[0m"] end end end ruby-console-1.15.3/spec/console_spec.rb000066400000000000000000000024111423731167600201650ustar00rootroot00000000000000# frozen_string_literal: true # Copyright, 2019, by Samuel G. D. Williams. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. require 'console' RSpec.describe Console do it "has a version number" do expect(Console::VERSION).not_to be nil end end ruby-console-1.15.3/spec/spec_helper.rb000066400000000000000000000006101423731167600200010ustar00rootroot00000000000000# frozen_string_literal: true require 'bundler/setup' require 'covered/rspec' RSpec.configure do |config| # Enable flags like --only-failures and --next-failure config.example_status_persistence_file_path = ".rspec_status" # Disable RSpec exposing methods globally on `Module` and `main` config.disable_monkey_patching! config.expect_with :rspec do |c| c.syntax = :expect end end