kolla 0.0.4 → 0.1.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 80e3734cb140b8f92406cd59459951b530c430305f7e0c0a16d8ea6c9838df2a
4
- data.tar.gz: 798b79b8a32747efb219b8941e8790d7291d7b775d6bbff3c3027df21cb57dd6
3
+ metadata.gz: 98522a2e33c960997f0f916d48c56aeb29fdade6f153e5b1e6098b769b4cf6a4
4
+ data.tar.gz: 15ac9b7c46afb68861a8243155a30ac825c5e6071bc4fe567722b42edf0fc963
5
5
  SHA512:
6
- metadata.gz: 23077c2f3c679ba15337bd1c80564aaf7cf58fc6e063af7cd8bbb9477a1acaa5e12712c0164b79fb31cb519ba41b5f2b5c04f26e10d03ac56a834f0894514722
7
- data.tar.gz: 86d20de4ec7f56e55278cc44cca232443684a816e1c59690f6597bf43a29990415b4cd225ecbc7f73afa79ace5878da751b954527fc640b758bb7cebc57ededd
6
+ metadata.gz: f51517d99c73fdb2748ce884c8ebe7959771f586dcc95e10e4d56434a530ec64b7a9a6504835e2097e5d36064efcdbb6a338119b57e475573e5c29141f5c11db
7
+ data.tar.gz: 1a632a31c1667b7fad4b37693f4241fd0ed0a77a44958f50ef1dc2f5e7066c10c94dcc4f40548d66ca459561275e30805eaed0ad6b5cbdd4e0d16457f0e60c2d
data/README.md ADDED
@@ -0,0 +1,64 @@
1
+ # Kolla
2
+
3
+ Zero-dependency CLI that parses `db/schema.rb` and answers "what's in this table?" in under a second — without booting Rails.
4
+
5
+ ## Installation
6
+
7
+ ```
8
+ gem install kolla
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ List all tables:
14
+
15
+ ```
16
+ $ kolla
17
+ users
18
+ posts
19
+ comments
20
+ ```
21
+
22
+ Inspect a table:
23
+
24
+ ```
25
+ $ kolla users
26
+ name (string, null: false)
27
+ email (string)
28
+ life_in_seconds (bigint, default: 0)
29
+ admin (boolean, default: false)
30
+ created_at (datetime, null: false)
31
+ index: [email] (unique)
32
+ index: [name]
33
+ ```
34
+
35
+ Use a custom schema path:
36
+
37
+ ```
38
+ $ kolla -f path/to/schema.rb users
39
+ ```
40
+
41
+ ### Options
42
+
43
+ ```
44
+ -h, --help Show help
45
+ -v, --version Show version
46
+ -f, --file PATH Path to schema.rb (default: db/schema.rb)
47
+ ```
48
+
49
+ ## What gets filtered
50
+
51
+ Rails internal tables (`action_*`, `active_*`) are excluded from the table list.
52
+
53
+ ## Development
54
+
55
+ ```
56
+ git clone https://github.com/antonysastre/kolla.git
57
+ cd kolla
58
+ bundle install
59
+ rake test
60
+ ```
61
+
62
+ ## License
63
+
64
+ MIT
data/bin/kolla CHANGED
@@ -1,4 +1,34 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
- require 'kolla'
4
- ARGV.empty? ? Kolla.run : Kolla.run(ARGV)
4
+ require "kolla"
5
+
6
+ file_path = Kolla::Parser::DEFAULT_FILE
7
+
8
+ args = ARGV.dup
9
+ while args.first&.start_with?("-")
10
+ case args.shift
11
+ when "--help", "-h"
12
+ puts <<~USAGE
13
+ Usage: kolla [options] [TABLE_NAME]
14
+
15
+ Options:
16
+ -h, --help Show this help
17
+ -v, --version Show version
18
+ -f, --file PATH Path to schema.rb (default: db/schema.rb)
19
+
20
+ Examples:
21
+ kolla List all tables
22
+ kolla users Show fields for 'users' table
23
+ kolla -f path/schema.rb users
24
+ USAGE
25
+ exit 0
26
+ when "--version", "-v"
27
+ puts "kolla #{Kolla::VERSION}"
28
+ exit 0
29
+ when "--file", "-f"
30
+ file_path = args.shift
31
+ end
32
+ end
33
+
34
+ Kolla.run(args, file_path: file_path)
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kolla
4
+ class Error < StandardError; end
5
+ class SchemaNotFound < Error; end
6
+ class TableNotFound < Error; end
7
+ end
data/lib/kolla/parser.rb CHANGED
@@ -2,40 +2,88 @@
2
2
 
3
3
  module Kolla
4
4
  class Parser
5
- DEFAULT_FILE = File.join('db', 'schema.rb').freeze
5
+ DEFAULT_FILE = File.join("db", "schema.rb").freeze
6
+ IGNORED_PREFIXES = %w[action_ active_].freeze
6
7
 
7
- def initialize(file_path: DEFAULT_FILE, options: {})
8
+ Field = Struct.new(:name, :type, :constraints, keyword_init: true)
9
+ Index = Struct.new(:columns, :unique, keyword_init: true)
10
+
11
+ def initialize(file_path: DEFAULT_FILE)
8
12
  @file_path = File.expand_path(file_path)
9
- @options = options
13
+ @content = File.read(@file_path)
14
+ rescue Errno::ENOENT
15
+ raise SchemaNotFound, "Schema file not found at #{@file_path}"
10
16
  end
11
17
 
12
- def run!
13
- content = File.read(file_path)
14
- if options[:model_name]
15
- extract_fields(content, options[:model_name])
16
- else
17
- extract_tables(content)
18
- end
19
- rescue Errno::ENOENT
20
- Kolla.logger.warn "Schema file_path not found at #{file_path}"
18
+ def tables
19
+ matches = @content.scan(/create_table\s+"(\w+)"/)
20
+ matches.map(&:first).reject { |table| IGNORED_PREFIXES.any? { |prefix| table.start_with?(prefix) } }
21
21
  end
22
22
 
23
- private
23
+ def fields_for(name)
24
+ escaped = Regexp.escape(name)
25
+ table_regex = /create_table "#{escaped}".*?do \|t\|(.*?)end/m
26
+ match = @content.match(table_regex)
27
+ raise TableNotFound, "Table '#{name}' not found in schema" unless match
24
28
 
25
- def extract_tables(schema)
26
- matches = schema.scan(/create_table\s+"(\w+)"/)
27
- matches.map(&:first).reject { |table| table.start_with?('action_', 'active_') }
29
+ block = match[1]
30
+ fields = parse_fields(block)
31
+ indexes = parse_indexes(block)
32
+
33
+ format_output(name, fields, indexes)
28
34
  end
29
35
 
30
- def extract_fields(schema, table_name)
31
- table_regex = /create_table "#{table_name}".*?do \|t\|(.*?)end/m
32
- match = schema.match(table_regex)
33
- return [] unless match
36
+ private
37
+
38
+ def parse_fields(block)
39
+ field_regex = /t\.(\w+)\s+"(\w+)"(.*)/
40
+ block.scan(field_regex).filter_map do |type, name, rest|
41
+ next if type == "index"
42
+
43
+ constraints = []
44
+ constraints << "null: false" if rest.include?("null: false")
45
+ if (default_match = rest.match(/default:\s*("(?:[^"\\]|\\.)*"|[\w.]+)/))
46
+ constraints << "default: #{default_match[1]}"
47
+ end
48
+ Field.new(name: name, type: type, constraints: constraints)
49
+ end
50
+ end
34
51
 
35
- field_regex = /t\.(\w+)\s+"(\w+)"/
36
- match[1].scan(field_regex).map { |type, name| "#{name} (#{type})" }
52
+ def parse_indexes(block)
53
+ index_regex = /t\.index\s+\[([^\]]+)\](.*)$/
54
+ block.scan(index_regex).map do |columns, rest|
55
+ cols = columns.scan(/"(\w+)"/).flatten
56
+ Index.new(columns: cols, unique: rest.include?("unique: true"))
57
+ end
37
58
  end
38
59
 
39
- attr_reader :file_path, :options
60
+ def format_output(table_name, fields, indexes)
61
+ return [] if fields.empty? && indexes.empty?
62
+
63
+ name_width = fields.map { |f| f.name.length }.max
64
+ type_width = fields.map { |f| f.type.length }.max
65
+
66
+ lines = []
67
+ lines << table_name
68
+ lines << "\u2500" * [name_width + type_width + 5, table_name.length].max
69
+
70
+ fields.each do |f|
71
+ line = " #{f.name.ljust(name_width)} #{f.type.ljust(type_width)}"
72
+ line << " #{f.constraints.join(', ')}" unless f.constraints.empty?
73
+ lines << line
74
+ end
75
+
76
+ unless indexes.empty?
77
+ lines << ""
78
+ lines << " Indexes:"
79
+ indexes.each do |idx|
80
+ line = " [#{idx.columns.join(', ')}]"
81
+ line << " (unique)" if idx.unique
82
+ lines << line
83
+ end
84
+ end
85
+
86
+ lines
87
+ end
40
88
  end
41
89
  end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kolla
4
+ VERSION = "0.1.1"
5
+ end
data/lib/kolla.rb CHANGED
@@ -1,23 +1,24 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'logger'
3
+ if RUBY_VERSION < "3.0"
4
+ abort "kolla requires Ruby 3.0 or later (you have #{RUBY_VERSION})"
5
+ end
4
6
 
5
- # Kolla parses a file and reports matching results.
6
- module Kolla
7
- class << self
8
- attr_accessor :logger
9
- end
7
+ require_relative "kolla/version"
8
+ require_relative "kolla/errors"
9
+ require_relative "kolla/parser"
10
10
 
11
- self.logger = Logger.new($stdout)
11
+ module Kolla
12
+ def self.run(args = [], file_path: Parser::DEFAULT_FILE)
13
+ parser = Parser.new(file_path: file_path)
12
14
 
13
- def self.run(args = [])
14
- if !args[0].nil?
15
- model_name = args[0]
16
- puts Parser.new(options:{model_name:}).run!
15
+ if args.empty?
16
+ puts parser.tables
17
17
  else
18
- puts Parser.new.run!
18
+ puts parser.fields_for(args[0])
19
19
  end
20
+ rescue Kolla::Error => e
21
+ warn e.message
22
+ exit 1
20
23
  end
21
24
  end
22
-
23
- require 'kolla/parser'
metadata CHANGED
@@ -1,27 +1,35 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kolla
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Antony Sastre
8
+ autorequire:
8
9
  bindir: bin
9
10
  cert_chain: []
10
- date: 2025-02-15 00:00:00.000000000 Z
11
+ date: 2026-03-20 00:00:00.000000000 Z
11
12
  dependencies: []
13
+ description: Zero-dependency CLI that parses db/schema.rb and answers 'what's in this
14
+ table?' in under a second — without booting Rails.
12
15
  email: antony.sastre@gmail.com
13
16
  executables:
14
17
  - kolla
15
18
  extensions: []
16
19
  extra_rdoc_files: []
17
20
  files:
21
+ - README.md
18
22
  - bin/kolla
19
23
  - lib/kolla.rb
24
+ - lib/kolla/errors.rb
20
25
  - lib/kolla/parser.rb
26
+ - lib/kolla/version.rb
21
27
  homepage: https://rubygems.org/gems/kolla
22
28
  licenses:
23
29
  - MIT
24
- metadata: {}
30
+ metadata:
31
+ source_code_uri: https://github.com/antonysastre/kolla
32
+ post_install_message:
25
33
  rdoc_options: []
26
34
  require_paths:
27
35
  - lib
@@ -36,7 +44,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
36
44
  - !ruby/object:Gem::Version
37
45
  version: '0'
38
46
  requirements: []
39
- rubygems_version: 3.6.3
47
+ rubygems_version: 3.0.3.1
48
+ signing_key:
40
49
  specification_version: 4
41
- summary: Simple CLI utility tool to parse domain specific files and return reports.
50
+ summary: Simple CLI tool to parse Rails schema file and list its details.
42
51
  test_files: []