grnline 0.0.2 → 0.0.3

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 44d56d43a90369f18d1aa19fdc07bf421dcecf5e
4
+ data.tar.gz: 5bbe730053f6f9f9e7f078c092db8f18ccda8329
5
+ SHA512:
6
+ metadata.gz: 0c52903b18b55ae289e9230148741617add595ce573f552e7290c7694fd7a4198a4d66c39b60574e3c7df535d694995aa6fb3ee6d0c393a8f2911ff642ae4407
7
+ data.tar.gz: cf0c35b7c52faadc58414278d4fd5fd93934e075dbdd3b556ae8de1887517ff47c88ebe91bbad34c0fcb8ac93dbade18ba81ca76c2dc9d2f7c7b9f993155885e
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # Grnline
2
2
 
3
+ [![Build Status](https://travis-ci.org/yoshihara/grnline.png?branch=master)](https://travis-ci.org/yoshihara/grnline)
4
+
3
5
  ## Description
4
6
 
5
7
  GrnLine is the wrapper for the interactive mode of [groonga](http://groonga.org/).
@@ -1,5 +1,19 @@
1
1
  # News
2
2
 
3
+ ## <a id="0-0-3">0.0.3</a>: 2013-11-23
4
+
5
+ ### Improvements
6
+
7
+ * Showed the build status image in Travis-CI.
8
+ * Added groonga's command parameters (e.g. "--name", "--table", "--output_columns"...) to the completion list.
9
+ * Added groonga's function (e.g. "now", "rand", "geo_distance"...) to the completion list.
10
+ * Supported command history. It is stored to the file "ENV['HOME']/.grnline-history".
11
+ * Added "*" in command-line prefix when you typed a continuous command.
12
+
13
+ ### Changes
14
+
15
+ * Removed "groonga" string from command-line prefix.
16
+
3
17
  ## <a id="0-0-2">0.0.2</a>: 2013-05-31
4
18
 
5
19
  ### Improvements
@@ -42,6 +42,7 @@ Gem::Specification.new do |spec|
42
42
  spec.add_development_dependency("bundler")
43
43
  spec.add_development_dependency("rake")
44
44
  spec.add_development_dependency("test-unit")
45
+ spec.add_development_dependency("test-unit-rr")
45
46
  spec.add_development_dependency("test-unit-notify")
46
47
  spec.add_development_dependency("redcarpet")
47
48
  end
@@ -0,0 +1,39 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module GrnLine
4
+ class History
5
+ attr_reader :lines
6
+
7
+ def initialize(file)
8
+ @history_file = file
9
+ @lines = []
10
+ end
11
+
12
+ def load
13
+ @lines = read
14
+ Readline::HISTORY.push(*@lines)
15
+ end
16
+
17
+ def save
18
+ saved_history = read
19
+ return if saved_history == @lines
20
+
21
+ new_history = (@lines + saved_history).uniq
22
+
23
+ File.open(@history_file, "w") do |file|
24
+ file.print(new_history.join("\n"))
25
+ end
26
+ end
27
+
28
+ def store(line)
29
+ @lines << line
30
+ end
31
+
32
+ private
33
+
34
+ def read
35
+ return [] unless File.exist?(@history_file)
36
+ File.readlines(@history_file).collect {|line| line.chomp}
37
+ end
38
+ end
39
+ end
@@ -14,7 +14,7 @@ module GrnLine
14
14
  @options.pager = "less"
15
15
  @options.groonga_arguments = []
16
16
  @options.output = $stdout
17
- @options.pretty_print = true
17
+ @options.use_pretty_print = true
18
18
  end
19
19
 
20
20
  def parse(argv)
@@ -60,8 +60,8 @@ module GrnLine
60
60
 
61
61
  parser.on("-p", "--[no-]pretty-print",
62
62
  "Pretty print responses from groonga.",
63
- "(#{@options.pretty_print})") do |pretty_print|
64
- @options.pretty_print = pretty_print
63
+ "(#{@options.use_pretty_print})") do |use_pretty_print|
64
+ @options.use_pretty_print = use_pretty_print
65
65
  end
66
66
 
67
67
  # TODO: supports pager for displaying results from groonga
@@ -1,5 +1,5 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
3
  module GrnLine
4
- VERSION = "0.0.2"
4
+ VERSION = "0.0.3"
5
5
  end
@@ -4,6 +4,7 @@ require "readline"
4
4
  require "json"
5
5
  require "open3"
6
6
  require "grnline/options-parser"
7
+ require "grnline/history"
7
8
 
8
9
  module GrnLine
9
10
  class Wrapper
@@ -17,8 +18,32 @@ module GrnLine
17
18
  "table_create", "table_list", "table_remove", "table_rename",
18
19
  "tokenize", "truncate"
19
20
  ]
21
+
22
+ GROONGA_VARIABLES = [
23
+ "--cache", "--columns", "--default_tokenizer", "--drilldown",
24
+ "--drilldown_limit", "--drilldown_offset",
25
+ "--drilldown_output_columns", "--drilldown_sortby", "--each",
26
+ "--filter", "--flags", "--id", "--ifexists", "--input_type",
27
+ "--key", "--key_type", "--level", "--limit", "--match_columns",
28
+ "--match_escalation_threshold", "--max", "--message", "--name",
29
+ "--new_name", "--normalizer", "--obj", "--offset",
30
+ "--output_columns", "--path", "--query", "--query_expander",
31
+ "--query_expansion", "--query_flags", "--scorer", "--seed",
32
+ "--sortby", "--source", "--string", "--table", "--tables",
33
+ "--target_name", "--threshold", "--tokenizer", "--type",
34
+ "--value_type", "--values"
35
+ ]
36
+
37
+ GROONGA_FUNCTIONS = [
38
+ "all_records", "edit_distance", "geo_distance", "geo_distance2",
39
+ "geo_distance3", "geo_in_circle", "geo_in_rectangle", "max",
40
+ "min", "now", "query", "rand", "snippet_html", "sub_filter"
41
+ ]
42
+
20
43
  GROONGA_SHUTDOWN_COMMANDS = ["quit", "shutdown"]
21
44
 
45
+ HISTORY_FILE = File.join(ENV["HOME"], ".grnline-history")
46
+
22
47
  class << self
23
48
  def run(argv)
24
49
  new.run(argv)
@@ -27,6 +52,8 @@ module GrnLine
27
52
 
28
53
  def initialize
29
54
  @options = nil
55
+ @history = GrnLine::History.new(HISTORY_FILE)
56
+ @commandline_prefix = ""
30
57
  setup_input_completion
31
58
  end
32
59
 
@@ -42,12 +69,18 @@ module GrnLine
42
69
 
43
70
  setup_interrupt_shutdown
44
71
 
45
- while(command = Readline.readline("groonga> ", true)) do
72
+ command = nil
73
+ @history.load
74
+
75
+ while(command = Readline.readline("#{@commandline_prefix}> ", true)) do
76
+ @history.store(Readline::HISTORY.to_a.last)
46
77
  process_command(command)
47
- exit(true) if GROONGA_SHUTDOWN_COMMANDS.include?(command)
78
+ break if GROONGA_SHUTDOWN_COMMANDS.include?(command)
48
79
  end
49
80
 
50
- shutdown_groonga
81
+ shutdown_groonga unless GROONGA_SHUTDOWN_COMMANDS.include?(command)
82
+ @history.save
83
+ true
51
84
  end
52
85
  end
53
86
 
@@ -72,7 +105,10 @@ module GrnLine
72
105
 
73
106
  if raw_response and not raw_response.empty?
74
107
  # TODO: support pretty print for formats except JSON
108
+ @commandline_prefix = ""
75
109
  output_response(raw_response)
110
+ else
111
+ @commandline_prefix = "*"
76
112
  end
77
113
  end
78
114
 
@@ -97,19 +133,23 @@ module GrnLine
97
133
  def output_response(raw_response)
98
134
  # TODO: support pretty print for formats except JSON
99
135
  response = raw_response
100
- if @options.pretty_print
136
+ if @options.use_pretty_print
101
137
  begin
102
138
  response = JSON.pretty_generate(JSON.parse(response))
103
139
  rescue
104
140
  end
105
141
  end
106
142
 
143
+ output(response)
144
+ end
145
+
146
+ def output(object)
107
147
  if @options.output.instance_of?(String)
108
148
  File.open(@options.output, "w") do |file|
109
- file.puts(response)
149
+ file.puts(object)
110
150
  end
111
151
  else
112
- @options.output.puts(response)
152
+ @options.output.puts(object)
113
153
  end
114
154
  end
115
155
 
@@ -127,19 +167,21 @@ module GrnLine
127
167
  def setup_interrupt_shutdown
128
168
  trap("INT") do
129
169
  shutdown_groonga
170
+ @history.save
130
171
  exit(true)
131
172
  end
132
173
  end
133
174
 
134
175
  def setup_input_completion
135
176
  Readline.completion_proc = lambda do |word|
136
- GROONGA_COMMANDS.grep(/\A#{Regexp.escape(word)}/)
177
+ completions = (GROONGA_COMMANDS + GROONGA_VARIABLES + GROONGA_FUNCTIONS)
178
+ completions.grep(/\A#{Regexp.escape(word)}/)
137
179
  end
138
180
  end
139
181
 
140
182
  def ensure_groonga_running
141
183
  if IO.select([@output], nil, nil, 1) and not @output.eof?
142
- puts(@output.read)
184
+ output(@output.read)
143
185
  return false
144
186
  end
145
187
  return true
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- coding: utf-8 -*-
3
+
4
+ case ARGV.first
5
+ when "not-running"
6
+ puts("not-running")
7
+ exit(false)
8
+
9
+ when "status"
10
+ output = ARGV.last
11
+ case output
12
+ when "true"
13
+ puts("status")
14
+ exit(true)
15
+ when "false"
16
+ STDERR.puts("status")
17
+ exit(false)
18
+ end
19
+
20
+ else
21
+ puts $stdin.gets.chomp
22
+ end
@@ -8,6 +8,7 @@ lib_dir = File.join(base_dir, "lib")
8
8
  test_dir = File.join(base_dir, "test")
9
9
 
10
10
  require "test-unit"
11
+ require "test/unit/rr"
11
12
  require "test/unit/notify"
12
13
 
13
14
  $LOAD_PATH.unshift(lib_dir)
@@ -0,0 +1,50 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require "grnline/history"
4
+ require "tempfile"
5
+
6
+ class TestHistory < Test::Unit::TestCase
7
+ def setup
8
+ @file = Tempfile.new("history")
9
+ @file.print(history)
10
+ @file.close
11
+ @history = GrnLine::History.new(@file.path)
12
+ end
13
+
14
+ def teardown
15
+ @file.close!
16
+ end
17
+
18
+ def test_load
19
+ @history.load
20
+ history_lines = history.split("\n")
21
+ assert_equal(history_lines, @history.lines)
22
+ assert_equal(history_lines, Readline::HISTORY.to_a)
23
+ end
24
+
25
+ def test_store
26
+ @history.store("test_command")
27
+
28
+ assert_equal(["test_command"], @history.lines)
29
+ end
30
+
31
+ def test_save
32
+ test_store
33
+
34
+ @history.save
35
+ expected_history = history + "test_command"
36
+
37
+ @file.open do |file|
38
+ assert_equal(expected_history, file.read)
39
+ end
40
+ end
41
+
42
+ def history
43
+ <<HISTORY
44
+ table_list
45
+ table_create SHOW
46
+ column_create --table SHOW --name title --type ShortText
47
+ select SHOW
48
+ HISTORY
49
+ end
50
+ end
@@ -12,7 +12,7 @@ class OptionsParserTest < Test::Unit::TestCase
12
12
  argv = @separator + ["--no-pretty-print"]
13
13
  options = @parser.parse(argv)
14
14
 
15
- assert_options(options, :pretty_print => false)
15
+ assert_options(options, :use_pretty_print => false)
16
16
  end
17
17
 
18
18
  def test_separator_in_both_arguments
@@ -49,11 +49,11 @@ class OptionsParserTest < Test::Unit::TestCase
49
49
  def assert_options(options, expected_options)
50
50
  output = expected_options[:output] || $stdout
51
51
  groonga_arguments = expected_options[:groonga_arguments] || []
52
- pretty_print = expected_options[:pretty_print]
53
- pretty_print = true if pretty_print.nil?
52
+ use_pretty_print = expected_options[:use_pretty_print]
53
+ use_pretty_print = true if use_pretty_print.nil?
54
54
 
55
55
  assert_equal(output, options.output)
56
56
  assert_equal(groonga_arguments, options.groonga_arguments)
57
- assert_equal(pretty_print, options.pretty_print)
57
+ assert_equal(use_pretty_print, options.use_pretty_print)
58
58
  end
59
59
  end
@@ -2,18 +2,91 @@
2
2
 
3
3
  require "grnline/wrapper"
4
4
  require "stringio"
5
+ require "tempfile"
5
6
  require "ostruct"
6
7
 
7
8
  class TestWrapper < Test::Unit::TestCase
8
9
  def setup
9
10
  @grnline = GrnLine::Wrapper.new
10
11
  @grnline.options = OpenStruct.new
11
- @output = StringIO.new
12
+ end
13
+
14
+ class RunTest < self
15
+ def setup
16
+ super
17
+ fake_groonga = File.join(File.dirname(__FILE__), "bin",
18
+ "fake-groonga.rb")
19
+ @stdout = Tempfile.new("output")
20
+ @grnline_arguments = [
21
+ "--groonga", fake_groonga,
22
+ "--output", @stdout.path
23
+ ]
24
+ end
25
+
26
+ private
27
+
28
+ def generate_argv(arguments)
29
+ arguments + [GrnLine::OptionsParser::SEPARATOR] + @grnline_arguments
30
+ end
31
+
32
+ def stdout_output
33
+ File.read(@stdout)
34
+ end
35
+
36
+ public
37
+
38
+ def test_not_running
39
+ argv = generate_argv(["not-running"])
40
+
41
+ assert_true(@grnline.run(argv))
42
+ assert_equal("not-running\n", stdout_output)
43
+ end
44
+
45
+ def test_ready
46
+ argv = generate_argv(["status", "true"])
47
+
48
+ assert_true(@grnline.run(argv))
49
+ assert_equal("status\n", stdout_output)
50
+ end
51
+
52
+ def test_not_ready
53
+ old_stderr = $stderr.dup
54
+ stderr = StringIO.new
55
+ $stderr = stderr
56
+
57
+ argv = generate_argv(["status", "false"])
58
+
59
+ assert_false(@grnline.run(argv))
60
+ assert_empty(stdout_output)
61
+ assert_equal("status\n", stderr.string)
62
+
63
+ $stderr = old_stderr
64
+ end
65
+
66
+ def test_running
67
+ description = "The_quit_commands_exits_running_groonga."
68
+ argv = generate_argv([])
69
+ mock(Readline).readline("> ", true) do
70
+ "quit"
71
+ end
72
+ mock(@grnline).process_command("quit") do
73
+ @stdout.puts(description)
74
+ @stdout.flush
75
+ end
76
+
77
+ assert_true(@grnline.run(argv))
78
+ assert_equal("#{description}\n", stdout_output)
79
+ end
12
80
  end
13
81
 
14
82
  class OutputResponseTest < self
83
+ def setup
84
+ super
85
+ @output = StringIO.new
86
+ end
87
+
15
88
  def test_prerry_print
16
- @grnline.options.pretty_print = true
89
+ @grnline.options.use_pretty_print = true
17
90
  @grnline.options.output = @output
18
91
 
19
92
  @grnline.send(:output_response, raw_response)
@@ -21,7 +94,7 @@ class TestWrapper < Test::Unit::TestCase
21
94
  end
22
95
 
23
96
  def test_no_prerry_print
24
- @grnline.options.pretty_print = false
97
+ @grnline.options.use_pretty_print = false
25
98
  @grnline.options.output = @output
26
99
 
27
100
  @grnline.send(:output_response, raw_response)
metadata CHANGED
@@ -1,135 +1,131 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: grnline
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
5
- prerelease:
4
+ version: 0.0.3
6
5
  platform: ruby
7
6
  authors:
8
7
  - Haruka Yoshihara
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-05-31 00:00:00.000000000 Z
11
+ date: 2013-11-23 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: json
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ! '>='
17
+ - - '>='
20
18
  - !ruby/object:Gem::Version
21
19
  version: '0'
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
- - - ! '>='
24
+ - - '>='
28
25
  - !ruby/object:Gem::Version
29
26
  version: '0'
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: packnga
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
- - - ! '>='
31
+ - - '>='
36
32
  - !ruby/object:Gem::Version
37
33
  version: '0'
38
34
  type: :development
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
- - - ! '>='
38
+ - - '>='
44
39
  - !ruby/object:Gem::Version
45
40
  version: '0'
46
41
  - !ruby/object:Gem::Dependency
47
42
  name: bundler
48
43
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
44
  requirements:
51
- - - ! '>='
45
+ - - '>='
52
46
  - !ruby/object:Gem::Version
53
47
  version: '0'
54
48
  type: :development
55
49
  prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
51
  requirements:
59
- - - ! '>='
52
+ - - '>='
60
53
  - !ruby/object:Gem::Version
61
54
  version: '0'
62
55
  - !ruby/object:Gem::Dependency
63
56
  name: rake
64
57
  requirement: !ruby/object:Gem::Requirement
65
- none: false
66
58
  requirements:
67
- - - ! '>='
59
+ - - '>='
68
60
  - !ruby/object:Gem::Version
69
61
  version: '0'
70
62
  type: :development
71
63
  prerelease: false
72
64
  version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
65
  requirements:
75
- - - ! '>='
66
+ - - '>='
76
67
  - !ruby/object:Gem::Version
77
68
  version: '0'
78
69
  - !ruby/object:Gem::Dependency
79
70
  name: test-unit
80
71
  requirement: !ruby/object:Gem::Requirement
81
- none: false
82
72
  requirements:
83
- - - ! '>='
73
+ - - '>='
84
74
  - !ruby/object:Gem::Version
85
75
  version: '0'
86
76
  type: :development
87
77
  prerelease: false
88
78
  version_requirements: !ruby/object:Gem::Requirement
89
- none: false
90
79
  requirements:
91
- - - ! '>='
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: test-unit-rr
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '>='
92
95
  - !ruby/object:Gem::Version
93
96
  version: '0'
94
97
  - !ruby/object:Gem::Dependency
95
98
  name: test-unit-notify
96
99
  requirement: !ruby/object:Gem::Requirement
97
- none: false
98
100
  requirements:
99
- - - ! '>='
101
+ - - '>='
100
102
  - !ruby/object:Gem::Version
101
103
  version: '0'
102
104
  type: :development
103
105
  prerelease: false
104
106
  version_requirements: !ruby/object:Gem::Requirement
105
- none: false
106
107
  requirements:
107
- - - ! '>='
108
+ - - '>='
108
109
  - !ruby/object:Gem::Version
109
110
  version: '0'
110
111
  - !ruby/object:Gem::Dependency
111
112
  name: redcarpet
112
113
  requirement: !ruby/object:Gem::Requirement
113
- none: false
114
114
  requirements:
115
- - - ! '>='
115
+ - - '>='
116
116
  - !ruby/object:Gem::Version
117
117
  version: '0'
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
- none: false
122
121
  requirements:
123
- - - ! '>='
122
+ - - '>='
124
123
  - !ruby/object:Gem::Version
125
124
  version: '0'
126
- description: ! 'GrnLine is created by Ruby.
127
-
125
+ description: |
126
+ GrnLine is created by Ruby.
128
127
  This uses [grnwrap](https://github.com/michisu/grnwrap) as a
129
-
130
128
  reference. grnwrap is created by Python.
131
-
132
- '
133
129
  email:
134
130
  - yshr04hrk@gmail.com
135
131
  executables:
@@ -143,48 +139,46 @@ files:
143
139
  - Rakefile
144
140
  - Gemfile
145
141
  - grnline.gemspec
142
+ - lib/grnline/history.rb
146
143
  - lib/grnline/options-parser.rb
147
144
  - lib/grnline/version.rb
148
145
  - lib/grnline/wrapper.rb
149
146
  - lib/grnline.rb
150
147
  - doc/text/news.md
148
+ - test/bin/fake-groonga.rb
151
149
  - test/run-test.rb
150
+ - test/test-history.rb
152
151
  - test/test-options-parser.rb
153
152
  - test/test-wrapper.rb
154
153
  - bin/grnline
155
154
  homepage:
156
155
  licenses:
157
156
  - MIT
157
+ metadata: {}
158
158
  post_install_message:
159
159
  rdoc_options: []
160
160
  require_paths:
161
161
  - lib
162
162
  required_ruby_version: !ruby/object:Gem::Requirement
163
- none: false
164
163
  requirements:
165
- - - ! '>='
164
+ - - '>='
166
165
  - !ruby/object:Gem::Version
167
166
  version: '0'
168
- segments:
169
- - 0
170
- hash: 855349197423195369
171
167
  required_rubygems_version: !ruby/object:Gem::Requirement
172
- none: false
173
168
  requirements:
174
- - - ! '>='
169
+ - - '>='
175
170
  - !ruby/object:Gem::Version
176
171
  version: '0'
177
- segments:
178
- - 0
179
- hash: 855349197423195369
180
172
  requirements: []
181
173
  rubyforge_project:
182
- rubygems_version: 1.8.23
174
+ rubygems_version: 2.0.3
183
175
  signing_key:
184
- specification_version: 3
176
+ specification_version: 4
185
177
  summary: GrnLine is the wrapper for the interactive mode of [groonga](http://groonga.org/).
186
178
  test_files:
179
+ - test/bin/fake-groonga.rb
187
180
  - test/run-test.rb
181
+ - test/test-history.rb
188
182
  - test/test-options-parser.rb
189
183
  - test/test-wrapper.rb
190
184
  has_rdoc: