grnline 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: