broken 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/bin/broken +29 -0
- data/lib/broken.rb +184 -0
- data/lib/config.rb +132 -0
- metadata +60 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 7a5c05dfd27676a7ec939f35d91111bf5c83f963770d90458ed14934ef2c052f
|
4
|
+
data.tar.gz: db35fe7a20c2528e1ac6fc8c894d5064a3ad4597047524b034a5f353cab74aba
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 06bae52c7afb967efb6df80c24d8ad36df8732355ac4cb4c50cf5731b119d9af9bb4315f04531cd8e45ab7eea810f1eda9757afba7c5d8ab48bad2d961ead9a8
|
7
|
+
data.tar.gz: 9220bd2630a6a1250dfc186bde926f2c2f602fed6a1be15de7ccc74f01dc8cf5b0bdafdcc6115e550b157f765a48730f123cb1cdfd54531c62d0ec89e4c517c4
|
data/bin/broken
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
################################################################################
|
4
|
+
# Usage:
|
5
|
+
# broken <command>
|
6
|
+
#
|
7
|
+
# Example:
|
8
|
+
# broken rails server
|
9
|
+
################################################################################
|
10
|
+
|
11
|
+
ENV['BROKEN_ENABLED'] = Time.now.to_i.to_s
|
12
|
+
|
13
|
+
# Get flags from arguments.
|
14
|
+
args = []
|
15
|
+
flags = []
|
16
|
+
ARGV.each do |arg|
|
17
|
+
if arg.start_with? '@'
|
18
|
+
flags << arg.delete_prefix('@')
|
19
|
+
else
|
20
|
+
args << arg
|
21
|
+
end
|
22
|
+
end
|
23
|
+
ENV['BROKEN_FLAGS'] = flags.join " "
|
24
|
+
|
25
|
+
# Get user input.
|
26
|
+
command = args.join " "
|
27
|
+
|
28
|
+
# Action original command.
|
29
|
+
system command
|
data/lib/broken.rb
ADDED
@@ -0,0 +1,184 @@
|
|
1
|
+
require 'pastel'
|
2
|
+
require 'config'
|
3
|
+
|
4
|
+
module Broken
|
5
|
+
@@pastel = Pastel.new
|
6
|
+
@@config = Config.new
|
7
|
+
@@is_prying = false
|
8
|
+
|
9
|
+
def broken(message, status = :info, type = nil, context = nil)
|
10
|
+
if @@config.enabled
|
11
|
+
return if Broken.filter_status? status
|
12
|
+
return if Broken.filter_type? type
|
13
|
+
|
14
|
+
indent = Broken.render(message, status, type, context)
|
15
|
+
|
16
|
+
Broken.step(indent)
|
17
|
+
yield if block_given?
|
18
|
+
|
19
|
+
Broken.delay()
|
20
|
+
end
|
21
|
+
end
|
22
|
+
alias 🔥 broken
|
23
|
+
|
24
|
+
def self.render(message, status, type, context)
|
25
|
+
output = "🔥"
|
26
|
+
|
27
|
+
# Time.
|
28
|
+
time = Broken.format(Time.now().strftime("%k:%M"), color: :cyan)
|
29
|
+
output << " #{time}"
|
30
|
+
|
31
|
+
# Status.
|
32
|
+
config = @@config.statuses[status]
|
33
|
+
output << Broken.format(" #{config[:icon]} #{status.to_s}", config)
|
34
|
+
|
35
|
+
# Type.
|
36
|
+
if !@@config.types.nil? && @@config.types.has_key?(type)
|
37
|
+
config = @@config.types[type]
|
38
|
+
if config.has_key? :icon
|
39
|
+
output << Broken.format(" #{config[:icon]} #{type.to_s}", config)
|
40
|
+
else
|
41
|
+
output << Broken.format(" #{type.to_s}", config)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# Context.
|
46
|
+
output << Broken.format(" #{context}", styles: [:bold, :dim])
|
47
|
+
|
48
|
+
# Line break.
|
49
|
+
while message.start_with?('^')
|
50
|
+
message.delete_prefix!('^').strip!
|
51
|
+
unless @@config.status || @@config.type
|
52
|
+
output = "\n" + output
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# Indent.
|
57
|
+
indent = ''
|
58
|
+
while message.start_with?('>')
|
59
|
+
message.delete_prefix!('>').strip!
|
60
|
+
unless @@config.status || @@config.type
|
61
|
+
indent = indent + ' '
|
62
|
+
output = ' ' + output
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# Highlight numbers and methods.
|
67
|
+
words = []
|
68
|
+
message.split(/(#\d+|\w+\(\))/).each do |word|
|
69
|
+
if word.start_with?('#') || word.end_with?(')')
|
70
|
+
words << @@pastel.yellow(word)
|
71
|
+
else
|
72
|
+
words << word
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
puts output << " " + words.join()
|
77
|
+
|
78
|
+
return indent
|
79
|
+
end
|
80
|
+
|
81
|
+
def self.step(indent)
|
82
|
+
if @@config.step
|
83
|
+
puts "#{indent}🔥 Press ENTER to step or P to Pry:"
|
84
|
+
input = gets.chomp
|
85
|
+
binding while input == nil
|
86
|
+
if input.downcase == "p"
|
87
|
+
puts @@pastel.dim("Enter X to exit Pry or !!! to exit program.")
|
88
|
+
@@is_prying = true
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def self.filter_status? status
|
94
|
+
unless @@config.status.nil? || @@config.status.include?(status)
|
95
|
+
return true
|
96
|
+
end
|
97
|
+
|
98
|
+
false
|
99
|
+
end
|
100
|
+
|
101
|
+
def self.filter_type? type
|
102
|
+
unless @@config.type.nil? || @@config.type.include?(type)
|
103
|
+
return true
|
104
|
+
end
|
105
|
+
|
106
|
+
false
|
107
|
+
end
|
108
|
+
|
109
|
+
def self.delay()
|
110
|
+
if @@config.delay > 0
|
111
|
+
sleep(@@config.delay)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def self.is_prying?
|
116
|
+
@@config.step && @@is_prying
|
117
|
+
end
|
118
|
+
|
119
|
+
def self.format(text, config)
|
120
|
+
|
121
|
+
if config.has_key? :styles
|
122
|
+
# Change characters first.
|
123
|
+
config[:styles].each do |style|
|
124
|
+
case style
|
125
|
+
when :upcase
|
126
|
+
text = text.upcase
|
127
|
+
when :downcase
|
128
|
+
text = text.downcase
|
129
|
+
when :capitalize
|
130
|
+
text = text.capitalize
|
131
|
+
end
|
132
|
+
end
|
133
|
+
# Then apply styling.
|
134
|
+
config[:styles].each do |style|
|
135
|
+
case style
|
136
|
+
when :clear
|
137
|
+
text = @@pastel.clear(text)
|
138
|
+
when :bold
|
139
|
+
text = @@pastel.bold(text)
|
140
|
+
when :dim
|
141
|
+
text = @@pastel.dim(text)
|
142
|
+
when :italic
|
143
|
+
text = @@pastel.italic(text)
|
144
|
+
when :underline
|
145
|
+
text = @@pastel.underline(text)
|
146
|
+
when :inverse
|
147
|
+
text = @@pastel.inverse(text)
|
148
|
+
when :hidden
|
149
|
+
text = @@pastel.hidden(text)
|
150
|
+
when :strike, :strikethrough
|
151
|
+
text = @@pastel.strikethrough(text)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
if config.has_key? :color
|
157
|
+
case config[:color]
|
158
|
+
when :blue
|
159
|
+
text = @@pastel.bright_blue(text)
|
160
|
+
when :green
|
161
|
+
text = @@pastel.green(text)
|
162
|
+
when :yellow
|
163
|
+
text = @@pastel.yellow(text)
|
164
|
+
when :red
|
165
|
+
text = @@pastel.red(text)
|
166
|
+
when :purple, :magenta
|
167
|
+
text = @@pastel.magenta(text)
|
168
|
+
when :cyan
|
169
|
+
text = @@pastel.cyan(text)
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
text
|
174
|
+
end
|
175
|
+
|
176
|
+
# Override config from application.
|
177
|
+
def self.configure()
|
178
|
+
yield(@@config)
|
179
|
+
|
180
|
+
# Override config from flags on command line.
|
181
|
+
@@config.cli_configure()
|
182
|
+
end
|
183
|
+
|
184
|
+
end
|
data/lib/config.rb
ADDED
@@ -0,0 +1,132 @@
|
|
1
|
+
require 'set'
|
2
|
+
|
3
|
+
module Broken
|
4
|
+
|
5
|
+
##############################################################################
|
6
|
+
# Default config that can be overridden from the command line or application.
|
7
|
+
#
|
8
|
+
# @usage:
|
9
|
+
# Broken.configure do |config|
|
10
|
+
# config.<property> = <value>
|
11
|
+
# end
|
12
|
+
#
|
13
|
+
# @precedence:
|
14
|
+
# 3. Defaults - initialize()
|
15
|
+
# 2. Application - Broken.configure()
|
16
|
+
# 1. Command line flags - cli_configure()
|
17
|
+
##############################################################################
|
18
|
+
|
19
|
+
class Config
|
20
|
+
|
21
|
+
# Track errors and only show them once.
|
22
|
+
@@errors = Set.new
|
23
|
+
|
24
|
+
attr_accessor :enabled
|
25
|
+
attr_accessor :statuses
|
26
|
+
attr_accessor :types
|
27
|
+
# Flags.
|
28
|
+
attr_accessor :step
|
29
|
+
attr_accessor :status
|
30
|
+
attr_accessor :type
|
31
|
+
attr_accessor :delay
|
32
|
+
|
33
|
+
def initialize()
|
34
|
+
|
35
|
+
@statuses = {
|
36
|
+
:info => { icon: "ℹ", color: :blue, styles: [:upcase] },
|
37
|
+
:pass => { icon: "✔", color: :green, styles: [:upcase] },
|
38
|
+
:warn => { icon: "âš ", color: :yellow, styles: [:upcase] },
|
39
|
+
:fail => { icon: "⨯", color: :red, styles: [:upcase] },
|
40
|
+
:error => { icon: "!", color: :red, styles: [:upcase] },
|
41
|
+
:debug => { icon: "?", color: :purple, styles: [:upcase] },
|
42
|
+
}
|
43
|
+
|
44
|
+
@types = nil
|
45
|
+
|
46
|
+
# Broken is disabled by default, then enabled via the `broken` command.
|
47
|
+
# Or it can be permanently enabled, without the use of the `broken` command.
|
48
|
+
@enabled = false
|
49
|
+
|
50
|
+
##
|
51
|
+
# FLAGS.
|
52
|
+
#
|
53
|
+
# Flag defaults when not supplied via command line.
|
54
|
+
##
|
55
|
+
|
56
|
+
# Array of statuses to filter by, for example: [:warn, :error, :fail]
|
57
|
+
@status = nil
|
58
|
+
|
59
|
+
# Array of types to filter by, for example: [:cat, :dog, :tree]
|
60
|
+
@type = nil
|
61
|
+
|
62
|
+
# Integer or float representing amount of seconds to delay each broken() by.
|
63
|
+
@delay = 0
|
64
|
+
|
65
|
+
##
|
66
|
+
# PRIVATE.
|
67
|
+
##
|
68
|
+
|
69
|
+
# Boolean on whether or not to step through each broken() breakpoint.
|
70
|
+
# Setting to true here wont enable Pry, best to enable via command line.
|
71
|
+
@step = false
|
72
|
+
|
73
|
+
cli_configure()
|
74
|
+
end
|
75
|
+
|
76
|
+
# Override config from command line.
|
77
|
+
def cli_configure()
|
78
|
+
|
79
|
+
# Enable broken via the command line.
|
80
|
+
@enabled = true if ENV['BROKEN_ENABLED'] && ENV['BROKEN_ENABLED'].to_i >= (Time.now.to_i() - 1)
|
81
|
+
return unless @enabled
|
82
|
+
|
83
|
+
# Convert flag string to hash.
|
84
|
+
flags = {}
|
85
|
+
if ENV['BROKEN_FLAGS'] && !ENV['BROKEN_FLAGS'].empty?
|
86
|
+
ENV['BROKEN_FLAGS'].split().each do |flag|
|
87
|
+
values = flag.split('=')
|
88
|
+
|
89
|
+
key = values.shift.to_sym
|
90
|
+
|
91
|
+
# No arguments.
|
92
|
+
if values.empty?
|
93
|
+
flags[key] = nil
|
94
|
+
else
|
95
|
+
args = values.pop.split(',')
|
96
|
+
# Single argument.
|
97
|
+
if args.count == 1
|
98
|
+
flags[key] = args.first
|
99
|
+
# Multiple arguments.
|
100
|
+
else
|
101
|
+
flags[key] = args
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
@step = true if flags.has_key? :step
|
108
|
+
@status = Array(flags[:status]).map(&:to_sym) if valid? flags, :status
|
109
|
+
@type = Array(flags[:type]).map(&:to_sym) if valid? flags, :type
|
110
|
+
@delay = flags[:delay].to_f if valid? flags, :delay
|
111
|
+
end
|
112
|
+
|
113
|
+
def valid? flags, flag
|
114
|
+
# Has flag even been entered on the command line?
|
115
|
+
unless flags.has_key? flag
|
116
|
+
return false
|
117
|
+
end
|
118
|
+
|
119
|
+
if flags[flag].nil?
|
120
|
+
error = "🔥 ERROR: Invalid argument for @#{flag}."
|
121
|
+
unless @@errors.include? error
|
122
|
+
@@errors.add error
|
123
|
+
puts error
|
124
|
+
end
|
125
|
+
return false
|
126
|
+
end
|
127
|
+
|
128
|
+
true
|
129
|
+
end
|
130
|
+
|
131
|
+
end
|
132
|
+
end
|
metadata
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: broken
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Maedi Prichard
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2021-06-30 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: pastel
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
description: Console logs that are only visible after prefixing commands with 'broken'.
|
28
|
+
email: maediprichard@gmail.com
|
29
|
+
executables:
|
30
|
+
- broken
|
31
|
+
extensions: []
|
32
|
+
extra_rdoc_files: []
|
33
|
+
files:
|
34
|
+
- bin/broken
|
35
|
+
- lib/broken.rb
|
36
|
+
- lib/config.rb
|
37
|
+
homepage: https://reflekt.dev/broken
|
38
|
+
licenses:
|
39
|
+
- MPL-2.0
|
40
|
+
metadata: {}
|
41
|
+
post_install_message:
|
42
|
+
rdoc_options: []
|
43
|
+
require_paths:
|
44
|
+
- lib
|
45
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - ">="
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '0'
|
50
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
requirements: []
|
56
|
+
rubygems_version: 3.0.3
|
57
|
+
signing_key:
|
58
|
+
specification_version: 4
|
59
|
+
summary: "Shine a light on terminal commands. \U0001F525"
|
60
|
+
test_files: []
|