broken 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. checksums.yaml +7 -0
  2. data/bin/broken +29 -0
  3. data/lib/broken.rb +184 -0
  4. data/lib/config.rb +132 -0
  5. 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: []