nazar 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 600c1b8f59fbfedf0f11a7746aa96cb9af9ae94f6c6ae6da310d338ff8b0a117
4
- data.tar.gz: 8cf464cc24d00907d3fbf04bdccab4634d7e9bbca1c956e333c75001571f7046
3
+ metadata.gz: f20eb7af67e1ef9f7acb2831217ce27b05f654b7f076b4c85f82910bfd1e67b7
4
+ data.tar.gz: 264bca42da833684146e1aeb1d711fffa7f8811055a7c785bb423e263c1a42b5
5
5
  SHA512:
6
- metadata.gz: 9975d9f6644f11d6fee412e41f83fda5e0d5a837143a54c84bca08956478bfafc24f8ac3abff252e34fe294c9c941265cc7b9154e128be5aa3e4f78ee4b61925
7
- data.tar.gz: caf173463acec8f81c7e5a12cac39764ab36f435bf79fd297dc2d7bcf871df34438c14c31a679b10141ea750eaed95e09b71242470ad0980085cb225e9f667cc
6
+ metadata.gz: '0779267b1cb0b41686eda05457056b451353f54164faaa8fbd18a0dd24828fbaaf75d6ab03b7d4aa11da340abf9cc9fdfdc3eb38a2174b9e684649848cdc897a'
7
+ data.tar.gz: e3a44313685cb330e4ad47cdcdbeaa11e584060816ebdaa8020726be55b49be90dc04373c6d3f3c0c9d3e23d9aa3bb7b1feb8a2752de6a864a3f5634d20e51d2
checksums.yaml.gz.sig ADDED
@@ -0,0 +1,2 @@
1
+ W��:�Uw� xk��Jx�SY���9`9�~s�]a�[y4��b�x��m��䠷���9Y��~꒡N#.��e�|�&��S#!#yg2f:����V�`�Ǻjq�;�/uJd����0bN����T��1�)��&�{$�k���@������ U��d�J�x@���_��bQ^A��9
2
+ #K�.�n%Kr)s��J��̌�{�8S��xM�P��'csb7g�柹�3`�g�|������̴#p鏠HƇ�yϢ5i���j.�M�9�`٣ Iz��?��W�l���}3��l��c�4�
data/.rubocop.yml ADDED
@@ -0,0 +1,4 @@
1
+ AllCops:
2
+ NewCops: enable
3
+ Style/Documentation:
4
+ Enabled: false
data/certs/krzyzak.pem ADDED
@@ -0,0 +1,27 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIEgjCCAuqgAwIBAgIBATANBgkqhkiG9w0BAQsFADA1MTMwMQYDVQQDDCptaWNo
3
+ YWwua3J6eXphbm93c2tpX2dpdGh1Yi9EQz1nbWFpbC9EQz1jb20wHhcNMjEwOTE3
4
+ MTYyMDMyWhcNMjIwOTE3MTYyMDMyWjA1MTMwMQYDVQQDDCptaWNoYWwua3J6eXph
5
+ bm93c2tpX2dpdGh1Yi9EQz1nbWFpbC9EQz1jb20wggGiMA0GCSqGSIb3DQEBAQUA
6
+ A4IBjwAwggGKAoIBgQDEWgTDpbt17SytlzKcnFAeiNeL95n0/kwX6ubyXItTDKlG
7
+ Tw4KuDrqp2rcEZZhbqVLfJX3NgAFpme6fC1sg6KfG6b5w6g+b9NBw4q1+gw1LS0J
8
+ SITmgZJrMOqsX6YLeMWK5+guFuj8dhHb18IbLgS6q/+cLHQvfWMz9m0Nz6bh7p1D
9
+ ydK1TaRk9QcSd9c0RoSQ8psqPoHMzqZ28+UceDMrpPPqzJXNfusibUvF/lETribm
10
+ pKEiwybVh5IouMcWs5gplukkreJyjnCX19aFk3yPlQZaNp1Uly9qgO5Q5Z4gmD4M
11
+ 24sZ5KxNrc7LCMC6D5KnkSPRo+nj7biIfAii6wrN7cdSValR3yJdczxSEiKBSr3Y
12
+ kxQT9c53i+ouYerAGlmVmW1AfsIyt6S0eRHpeYpYo2PwX9jcnUsCfYkKBpV1ZgWr
13
+ /unnOrhQT2noEzKHpi5A5kyj+woLMjHGZ8oSSwHNUurlgVGpj+K08Aci73KILTPd
14
+ modoWl+EM350UUcektUCAwEAAaOBnDCBmTAJBgNVHRMEAjAAMAsGA1UdDwQEAwIE
15
+ sDAdBgNVHQ4EFgQUdFw+GB412vZ1HGQ7vuKqB09p45wwLwYDVR0RBCgwJoEkbWlj
16
+ aGFsLmtyenl6YW5vd3NraStnaXRodWJAZ21haWwuY29tMC8GA1UdEgQoMCaBJG1p
17
+ Y2hhbC5rcnp5emFub3dza2krZ2l0aHViQGdtYWlsLmNvbTANBgkqhkiG9w0BAQsF
18
+ AAOCAYEAw0q3kANMgrsHJ76bt86tTfJhMFhqldTzlXE92nuM8wTonNTiuwNpbJW0
19
+ sd2mK/n0Lm4kfe/wt5uwtvggtxhmoH8Sac1VyLiVOj+/7jfymYbxfMCC8uGDsPX0
20
+ CU7u/Mp+Dr9U8PXIM+ICQ5PmhxZjK0BUXZlZ18shGI1mFY+v0FwjDNYgTgmiHAiW
21
+ rH93qOM3GH6L1NykkBnmwZyLtIYhEvMpWebqojW+A3wrhxrVUG7XiqMrn2vy0pZW
22
+ 9SRgzlg5M1H3rU+RJVp8ve5Nz1gfb0C5kXnOtvDQuLAX+8OzE/kPi8K0lCKvfJpC
23
+ 3HPm1Il1fZp5WMnGj4zsIIESYj9j0Q12x9yygZGPksZrgcbdho1lBaZTt0+eqTVq
24
+ JWaxXNTngvP87JEn1IlU2S+n2huSBtSd+h3UaubUMDUanTewtjfp1HOpGdN5qTsS
25
+ FlwFUDGjWAe8lcsjyGp1dox0FK91TAHdZW1op8LYnOcO2DM8Mgzu4Gp7mibATEnx
26
+ ooN2pwmH
27
+ -----END CERTIFICATE-----
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nazar
4
+ class CellFormatter
5
+ def initialize(value, type: :string)
6
+ @value = value
7
+ @type = type
8
+ end
9
+
10
+ def format
11
+ case type
12
+ when :boolean
13
+ format_boolean(value)
14
+ when :numeric
15
+ Pastel.new.bright_blue(value)
16
+ else
17
+ value.nil? ? format_nil : value.to_s
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ attr_reader :value, :type
24
+
25
+ def format_boolean(value)
26
+ return format_nil if value.nil?
27
+
28
+ true_value, false_value = Nazar.config.formatter.boolean
29
+ Formatter::TRUTHY_VALUES.include?(value) ? true_value : false_value
30
+ end
31
+
32
+ def format_nil
33
+ Pastel.new.dim(Nazar.config.formatter.nil)
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+ require 'nazar/formatter/active_record_interface'
3
+
4
+ module Nazar
5
+ module Formatter
6
+ class ActiveRecordCollection
7
+ include ActiveRecordInterface
8
+
9
+ def initialize(collection)
10
+ @collection = collection
11
+ @attributes = collection.first.attributes
12
+ @klass = collection.first.class
13
+ end
14
+
15
+ def summary
16
+ collection.size
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,19 @@
1
+ module Nazar
2
+ module Formatter
3
+ module ActiveRecordInterface
4
+ attr_reader :collection, :klass, :attributes
5
+
6
+ def headers
7
+ HeadersFormatter.new(attributes.keys).format
8
+ end
9
+
10
+ def cells
11
+ @cells ||= collection.map do |item|
12
+ item.attributes.map do |column, value|
13
+ CellFormatter.new(value, type: klass.type_for_attribute(column).type).format
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+ require 'nazar/formatter/active_record_interface'
3
+
4
+ module Nazar
5
+ module Formatter
6
+ class ActiveRecordItem
7
+ include ActiveRecordInterface
8
+
9
+ def initialize(item)
10
+ @collection = [item]
11
+ @attributes = item.attributes
12
+ @klass = item.class
13
+ end
14
+
15
+ def summary
16
+ false
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nazar
4
+ module Formatter
5
+ class CSVTable
6
+ attr_reader :collection
7
+
8
+ def initialize(collection)
9
+ @collection = collection
10
+ end
11
+
12
+ def headers
13
+ HeadersFormatter.new(collection.headers).format
14
+ end
15
+
16
+ def cells
17
+ @cells ||= collection.map do |item|
18
+ item.fields.map do |value|
19
+ CellFormatter.new(value, type: detect_type(value)).format
20
+ end
21
+ end
22
+ end
23
+
24
+ def summary
25
+ collection.size
26
+ end
27
+
28
+ private
29
+
30
+ BOOLEAN_VALUES = TRUTHY_VALUES + FALSY_VALUES
31
+
32
+ def detect_type(value)
33
+ case value
34
+ when ->(val) { BOOLEAN_VALUES.include?(val.to_s.downcase) }
35
+ :boolean
36
+ when Numeric
37
+ :numeric
38
+ else
39
+ :string
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nazar
4
+ module Formatter
5
+ TRUTHY_VALUES = ['true', 'yes', true].freeze
6
+ FALSY_VALUES = ['false', 'no', false].freeze
7
+ end
8
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nazar
4
+ class HeadersFormatter
5
+ def initialize(headers)
6
+ @headers = headers
7
+ end
8
+
9
+ def format
10
+ headers.map { |header| pastel.bold(header) }
11
+ end
12
+
13
+ private
14
+
15
+ attr_reader :headers
16
+
17
+ def pastel
18
+ @pastel ||= Pastel.new
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nazar
4
+ class Renderer
5
+ def initialize(data)
6
+ @data = data
7
+ end
8
+
9
+ def render
10
+ pager.page(view.render) if view.supported_data?
11
+ end
12
+
13
+ def pager
14
+ @pager ||= TTY::Pager::SystemPager.new(command: 'less -iMSx4 -FX')
15
+ end
16
+
17
+ private
18
+
19
+ attr_reader :data
20
+
21
+ def render_table?
22
+ view.enabled?
23
+ end
24
+
25
+ def view
26
+ @view ||= View.new(data)
27
+ end
28
+ end
29
+ end
data/lib/nazar/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Nazar
4
- VERSION = '0.0.1'
4
+ VERSION = '0.0.2'
5
5
  end
data/lib/nazar/view.rb ADDED
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nazar
4
+ class View
5
+ extend Forwardable
6
+
7
+ def_delegators :formatter, :headers, :cells, :summary
8
+
9
+ def initialize(data)
10
+ @data = data
11
+ end
12
+
13
+ def render
14
+ return unless supported_data?
15
+
16
+ add_summary if summary
17
+
18
+ table
19
+ end
20
+
21
+ def supported_data?
22
+ !!formatter_klass
23
+ end
24
+
25
+ private
26
+
27
+ attr_reader :data
28
+
29
+ def formatter_klass
30
+ case data
31
+ when acttive_record_collection?
32
+ Formatter::ActiveRecordCollection
33
+ when active_record_item?
34
+ Formatter::ActiveRecordItem
35
+ when CSV::Table
36
+ Formatter::CSVTable
37
+ end
38
+ end
39
+
40
+ def formatter
41
+ formatter_klass.new(data)
42
+ end
43
+
44
+ def acttive_record_collection?
45
+ proc do
46
+ data.is_a?(ActiveRecord::Associations::CollectionProxy) ||
47
+ data.is_a?(ActiveRecord::Relation) ||
48
+ (data.is_a?(Array) && data.first.is_a?(ActiveRecord::Base))
49
+ end
50
+ end
51
+
52
+ def active_record_item?
53
+ proc { data.is_a?(ActiveRecord::Base) }
54
+ end
55
+
56
+ def add_summary
57
+ table.add_separator
58
+ table.add_row [Pastel.new.bold('Total'), { value: summary, colspan: headers.size - 1 }]
59
+ end
60
+
61
+ def table
62
+ @table ||= Terminal::Table.new(
63
+ headings: headers,
64
+ rows: cells,
65
+ style: { border: :unicode_thick_edge }
66
+ )
67
+ end
68
+ end
69
+ end
data/lib/nazar.rb CHANGED
@@ -1,6 +1,68 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'active_record'
4
+ require 'csv'
5
+ require 'dry-configurable'
6
+ require 'terminal-table'
7
+ require 'pastel'
8
+ require 'tty-pager'
9
+
3
10
  require 'nazar/version'
11
+ require 'nazar/cell_formatter'
12
+ require 'nazar/headers_formatter'
13
+ require 'nazar/renderer'
14
+ require 'nazar/formatter'
15
+ require 'nazar/formatter/csv_table'
16
+ require 'nazar/formatter/active_record_collection'
17
+ require 'nazar/formatter/active_record_item'
18
+ require 'nazar/view'
4
19
 
5
20
  module Nazar
21
+ extend Dry::Configurable
22
+
23
+ setting :formatter do
24
+ setting :nil, default: '∅'
25
+ setting :boolean, default: ['✓', '✗']
26
+ end
27
+
28
+ def self.enable!
29
+ return if @enabled
30
+
31
+ enable_for_irb! if defined?(IRB)
32
+ enable_for_pry! if defined?(Pry)
33
+
34
+ @enabled = true
35
+ end
36
+
37
+ def self.enable_for_irb!
38
+ ::IRB::Irb.class_eval do
39
+ alias_method :__original_output_value__, :output_value
40
+ def output_value(omit = false) # rubocop:disable Style/OptionalBooleanParameter
41
+ ::Nazar::Renderer.new(@context.last_value).render || __original_output_value__(omit)
42
+ end
43
+ end
44
+ end
45
+
46
+ def self.enable_for_pry!
47
+ @__original_pry_print = Pry.config.print
48
+ Pry.config.print = proc do |output, value, instance|
49
+ output.puts Nazar::Renderer.new(value).render || @__original_pry_print.call(output, value, instance)
50
+ end
51
+ end
52
+
53
+ def self.disable!
54
+ return unless @enabled
55
+
56
+ disable_for_irb! if defined?(IRB)
57
+
58
+ @enabled = false
59
+ end
60
+
61
+ def self.disable_for_irb!
62
+ ::IRB::Irb.send(:alias_method, :output_value, :__original_output_value__)
63
+ end
64
+
65
+ def self.disable_for_pry!
66
+ nil
67
+ end
6
68
  end
data/nazar.gemspec CHANGED
@@ -23,8 +23,12 @@ Gem::Specification.new do |spec|
23
23
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
24
24
  spec.require_paths = ['lib']
25
25
 
26
+ spec.cert_chain = ['certs/krzyzak.pem']
27
+ spec.signing_key = File.expand_path("~/.ssh/gem-private_key.pem") if $0 =~ /gem\z/
28
+
26
29
  spec.add_development_dependency 'rubocop', '~> 1.21'
27
30
 
31
+ spec.add_runtime_dependency 'activerecord', '>= 3.0', '< 6.2'
28
32
  spec.add_runtime_dependency 'dry-configurable', '~> 0.12'
29
33
  spec.add_runtime_dependency 'pastel', '~> 0.8'
30
34
  spec.add_runtime_dependency 'terminal-table', '~> 3.0'
data.tar.gz.sig ADDED
Binary file
metadata CHANGED
@@ -1,13 +1,41 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nazar
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michał Krzyżanowski
8
8
  autorequire:
9
9
  bindir: exe
10
- cert_chain: []
10
+ cert_chain:
11
+ - |
12
+ -----BEGIN CERTIFICATE-----
13
+ MIIEgjCCAuqgAwIBAgIBATANBgkqhkiG9w0BAQsFADA1MTMwMQYDVQQDDCptaWNo
14
+ YWwua3J6eXphbm93c2tpX2dpdGh1Yi9EQz1nbWFpbC9EQz1jb20wHhcNMjEwOTE3
15
+ MTYyMDMyWhcNMjIwOTE3MTYyMDMyWjA1MTMwMQYDVQQDDCptaWNoYWwua3J6eXph
16
+ bm93c2tpX2dpdGh1Yi9EQz1nbWFpbC9EQz1jb20wggGiMA0GCSqGSIb3DQEBAQUA
17
+ A4IBjwAwggGKAoIBgQDEWgTDpbt17SytlzKcnFAeiNeL95n0/kwX6ubyXItTDKlG
18
+ Tw4KuDrqp2rcEZZhbqVLfJX3NgAFpme6fC1sg6KfG6b5w6g+b9NBw4q1+gw1LS0J
19
+ SITmgZJrMOqsX6YLeMWK5+guFuj8dhHb18IbLgS6q/+cLHQvfWMz9m0Nz6bh7p1D
20
+ ydK1TaRk9QcSd9c0RoSQ8psqPoHMzqZ28+UceDMrpPPqzJXNfusibUvF/lETribm
21
+ pKEiwybVh5IouMcWs5gplukkreJyjnCX19aFk3yPlQZaNp1Uly9qgO5Q5Z4gmD4M
22
+ 24sZ5KxNrc7LCMC6D5KnkSPRo+nj7biIfAii6wrN7cdSValR3yJdczxSEiKBSr3Y
23
+ kxQT9c53i+ouYerAGlmVmW1AfsIyt6S0eRHpeYpYo2PwX9jcnUsCfYkKBpV1ZgWr
24
+ /unnOrhQT2noEzKHpi5A5kyj+woLMjHGZ8oSSwHNUurlgVGpj+K08Aci73KILTPd
25
+ modoWl+EM350UUcektUCAwEAAaOBnDCBmTAJBgNVHRMEAjAAMAsGA1UdDwQEAwIE
26
+ sDAdBgNVHQ4EFgQUdFw+GB412vZ1HGQ7vuKqB09p45wwLwYDVR0RBCgwJoEkbWlj
27
+ aGFsLmtyenl6YW5vd3NraStnaXRodWJAZ21haWwuY29tMC8GA1UdEgQoMCaBJG1p
28
+ Y2hhbC5rcnp5emFub3dza2krZ2l0aHViQGdtYWlsLmNvbTANBgkqhkiG9w0BAQsF
29
+ AAOCAYEAw0q3kANMgrsHJ76bt86tTfJhMFhqldTzlXE92nuM8wTonNTiuwNpbJW0
30
+ sd2mK/n0Lm4kfe/wt5uwtvggtxhmoH8Sac1VyLiVOj+/7jfymYbxfMCC8uGDsPX0
31
+ CU7u/Mp+Dr9U8PXIM+ICQ5PmhxZjK0BUXZlZ18shGI1mFY+v0FwjDNYgTgmiHAiW
32
+ rH93qOM3GH6L1NykkBnmwZyLtIYhEvMpWebqojW+A3wrhxrVUG7XiqMrn2vy0pZW
33
+ 9SRgzlg5M1H3rU+RJVp8ve5Nz1gfb0C5kXnOtvDQuLAX+8OzE/kPi8K0lCKvfJpC
34
+ 3HPm1Il1fZp5WMnGj4zsIIESYj9j0Q12x9yygZGPksZrgcbdho1lBaZTt0+eqTVq
35
+ JWaxXNTngvP87JEn1IlU2S+n2huSBtSd+h3UaubUMDUanTewtjfp1HOpGdN5qTsS
36
+ FlwFUDGjWAe8lcsjyGp1dox0FK91TAHdZW1op8LYnOcO2DM8Mgzu4Gp7mibATEnx
37
+ ooN2pwmH
38
+ -----END CERTIFICATE-----
11
39
  date: 2021-09-17 00:00:00.000000000 Z
12
40
  dependencies:
13
41
  - !ruby/object:Gem::Dependency
@@ -24,6 +52,26 @@ dependencies:
24
52
  - - "~>"
25
53
  - !ruby/object:Gem::Version
26
54
  version: '1.21'
55
+ - !ruby/object:Gem::Dependency
56
+ name: activerecord
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '3.0'
62
+ - - "<"
63
+ - !ruby/object:Gem::Version
64
+ version: '6.2'
65
+ type: :runtime
66
+ prerelease: false
67
+ version_requirements: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: '3.0'
72
+ - - "<"
73
+ - !ruby/object:Gem::Version
74
+ version: '6.2'
27
75
  - !ruby/object:Gem::Dependency
28
76
  name: dry-configurable
29
77
  requirement: !ruby/object:Gem::Requirement
@@ -89,14 +137,25 @@ extra_rdoc_files: []
89
137
  files:
90
138
  - ".gitignore"
91
139
  - ".rspec"
140
+ - ".rubocop.yml"
92
141
  - Gemfile
93
142
  - LICENSE.txt
94
143
  - README.md
95
144
  - Rakefile
96
145
  - bin/console
97
146
  - bin/setup
147
+ - certs/krzyzak.pem
98
148
  - lib/nazar.rb
149
+ - lib/nazar/cell_formatter.rb
150
+ - lib/nazar/formatter.rb
151
+ - lib/nazar/formatter/active_record_collection.rb
152
+ - lib/nazar/formatter/active_record_interface.rb
153
+ - lib/nazar/formatter/active_record_item.rb
154
+ - lib/nazar/formatter/csv_table.rb
155
+ - lib/nazar/headers_formatter.rb
156
+ - lib/nazar/renderer.rb
99
157
  - lib/nazar/version.rb
158
+ - lib/nazar/view.rb
100
159
  - nazar.gemspec
101
160
  homepage: https://github.com/krzyzak/nazar
102
161
  licenses: []
metadata.gz.sig ADDED
Binary file