frett 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/.gemtest ADDED
File without changes
data/History.txt ADDED
@@ -0,0 +1,4 @@
1
+ === 0.0.1 2012-06-27
2
+
3
+ * 1 major enhancement:
4
+ * Initial release
data/Manifest.txt ADDED
@@ -0,0 +1,16 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.rdoc
4
+ Rakefile
5
+ bin/frett
6
+ bin/frett_service
7
+ lib/frett.rb
8
+ lib/frett/adapter.rb
9
+ lib/frett/cli.rb
10
+ lib/frett/config.rb
11
+ lib/frett/indexer.rb
12
+ lib/frett/search.rb
13
+ script/console
14
+ test/test_frett.rb
15
+ test/test_frett_cli.rb
16
+ test/test_helper.rb
data/README.rdoc ADDED
@@ -0,0 +1,55 @@
1
+ = frett
2
+
3
+ * http://github.com/dbldots/frett
4
+
5
+ == DESCRIPTION:
6
+
7
+ the goal of frett is to provide a much quicker search functionality than ack on large projects.
8
+ it's built on top of the 'ferret' and 'listen' gems.
9
+
10
+ == FEATURES/PROBLEMS:
11
+
12
+ * files changes are not tracked until the initial index has been build
13
+
14
+ == SYNOPSIS:
15
+
16
+ go to any folder you want to index for searching. then hit
17
+ * 'frett_service start' or
18
+ * 'frett_service start clean' to ensure the index is build from scratch
19
+ * 'frett_service status'
20
+
21
+ start your search using 'frett'. see
22
+ * 'frett -h' for usage instructions
23
+
24
+ == REQUIREMENTS:
25
+
26
+ frett uses the 'listen' gem. should work out of the box on any platform. (except windows?)
27
+
28
+ == INSTALL:
29
+
30
+ * gem install frett
31
+
32
+ == LICENSE:
33
+
34
+ (The MIT License)
35
+
36
+ Copyright (c) 2012 FIXME full name
37
+
38
+ Permission is hereby granted, free of charge, to any person obtaining
39
+ a copy of this software and associated documentation files (the
40
+ 'Software'), to deal in the Software without restriction, including
41
+ without limitation the rights to use, copy, modify, merge, publish,
42
+ distribute, sublicense, and/or sell copies of the Software, and to
43
+ permit persons to whom the Software is furnished to do so, subject to
44
+ the following conditions:
45
+
46
+ The above copyright notice and this permission notice shall be
47
+ included in all copies or substantial portions of the Software.
48
+
49
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
50
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
51
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
52
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
53
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
54
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
55
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,25 @@
1
+ require 'rubygems'
2
+ gem 'hoe', '>= 2.1.0'
3
+ require 'hoe'
4
+ require 'fileutils'
5
+ require './lib/frett'
6
+
7
+ Hoe.plugin :newgem
8
+
9
+ # Generate all the Rake tasks
10
+ # Run 'rake -T' to see list of generated tasks (from gem root directory)
11
+ $hoe = Hoe.spec 'frett' do
12
+ self.developer 'johannes-kostas goetzinger', 'dbldots@gmail.com'
13
+ self.extra_deps = [
14
+ ['daemons','>= 1.1.8'],
15
+ ['ferret','>= 0.11.8.4'],
16
+ ['listen','>= 0.4.7'],
17
+ ['ptools','>= 1.2.2'],
18
+ ['colorize','>= 0.5.8'],
19
+ ['mime-types','>= 1.19']
20
+ ]
21
+
22
+ end
23
+
24
+ require 'newgem/tasks'
25
+ Dir['tasks/**/*.rake'].each { |t| load t }
data/bin/frett ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Created on 2012-6-27.
4
+ # Copyright (c) 2012. All rights reserved.
5
+
6
+ require File.expand_path(File.dirname(__FILE__) + "/../lib/frett")
7
+ require File.expand_path(File.dirname(__FILE__) + "/../lib/frett/config")
8
+
9
+ Frett::Config.load_config(Dir.pwd)
10
+ Frett::CLI.execute(STDOUT, ARGV)
data/bin/frett_service ADDED
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Created on 2012-6-27.
4
+ # Copyright (c) 2012. All rights reserved.
5
+
6
+ require 'rubygems'
7
+ require "daemons"
8
+ require File.expand_path(File.dirname(__FILE__) + "/../lib/frett")
9
+ require File.expand_path(File.dirname(__FILE__) + "/../lib/frett/config")
10
+
11
+ Frett::Config.load_config(Dir.pwd)
12
+
13
+ Daemons.run_proc(Frett::Config.service_name,
14
+ :log_dir => Frett::Config.index_path,
15
+ :ARGV => ARGV,
16
+ :log_output => Frett::Config.log) do
17
+ Frett::Indexer.new(:clean => (ARGV.last == 'clean'))
18
+ end
@@ -0,0 +1,32 @@
1
+ require 'ferret'
2
+
3
+ class Frett::Adapter
4
+
5
+ def initialize(options = {})
6
+ new_index = options[:clean] || !Frett::Config.consider_mtime
7
+ unless File.directory?(Frett::Config.index_path)
8
+ new_index = true
9
+ Dir.mkdir(Frett::Config.index_path)
10
+ end
11
+ @index = Ferret::Index::Index.new(:path => Frett::Config.index_path, :create => new_index)
12
+ if new_index
13
+ File.open(Frett::Config.mtime_path, "w") {}
14
+ past = Time.local(1970,"jan",1,0,0,0)
15
+ File.utime(past, past, Frett::Config.mtime_path)
16
+ @index.field_infos.add_field :file, :store => :yes, :index => :untokenized, :term_vector => :no
17
+ @index.field_infos.add_field :content, :store => :yes, :index => :yes
18
+ @index.field_infos.add_field :line, :store => :yes, :index => :yes, :term_vector => :no
19
+ end
20
+ end
21
+
22
+ def write(&block)
23
+ yield(@index)
24
+ @index.optimize
25
+ File.utime(Time.now, Time.now, Frett::Config.mtime_path)
26
+ end
27
+
28
+ def read
29
+ yield(@index)
30
+ end
31
+
32
+ end
data/lib/frett/cli.rb ADDED
@@ -0,0 +1,59 @@
1
+ require 'optparse'
2
+
3
+ module Frett
4
+ class CLI
5
+ def self.execute(stdout, arguments=[])
6
+ options = {}
7
+ banner = "Usage: frett [options] 'search string' [directory path]"
8
+
9
+ optparse = OptionParser.new do|opts|
10
+ opts.banner = banner
11
+
12
+ options[:escape] = nil
13
+ opts.on( '-n', '--escape', 'escape special characters' ) do
14
+ options[:escape] = true
15
+ end
16
+ opts.on( '-N', '--no-escape',
17
+ 'don\'t escape special chars. you may want to use:',
18
+ '\'?\' for any character, \'*\' for multiple characters' ) do
19
+ options[:escape] = false
20
+ end
21
+
22
+ options[:use_wildcard] = nil
23
+ opts.on( '-w', '--use-wildcard', 'adds a \'*\' in front & to the end of your search string' ) do
24
+ options[:use_wildcard] = true
25
+ end
26
+ opts.on( '-W', '--no-wildcard', 'don\'t wildcard the search string' ) do
27
+ options[:use_wildcard] = false
28
+ end
29
+
30
+ options[:use_or] = nil
31
+ opts.on( '-o', '--use-or', 'build search query using OR for the terms of your search string' ) do
32
+ options[:use_or] = true
33
+ end
34
+ opts.on( '-a', '--use-and', 'build search query using AND for the terms of your search string' ) do
35
+ options[:use_or] = false
36
+ end
37
+
38
+ opts.on( '-h', '--help', 'Display this screen' ) do
39
+ puts opts
40
+ exit
41
+ end
42
+ end
43
+
44
+ optparse.parse!(arguments)
45
+ search_options = options.inject({}) { |hsh, (key, value)| value.nil? ? hsh : hsh.merge(key => value) }
46
+ path = File.join(Frett::Config.working_dir, arguments.last) if arguments.size > 1
47
+ arguments.pop if path && File.exist?(path)
48
+ needle = arguments.join(" ")
49
+
50
+ puts "WARNING: frett_service is NOT running..".red unless File.exist?(File.join(Frett::Config.working_dir, Frett::Config.service_name << ".pid"))
51
+
52
+ if needle.strip.empty?
53
+ puts banner
54
+ else
55
+ Frett::Search.new(search_options).search(needle, path)
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,42 @@
1
+ class Frett::Config
2
+
3
+ class << self
4
+ def default_options
5
+ {
6
+ :exclude => "^tags$|log\/|tmp\/",
7
+ :num_docs => 100000,
8
+ :directory => ".frett",
9
+ :log => true,
10
+ :consider_mtime => true,
11
+ :service_name => "frett_service",
12
+ :search => {
13
+ :use_wildcard => false,
14
+ :escape => true,
15
+ :use_or => false
16
+ }
17
+ }
18
+ end
19
+
20
+ def load_config(working_dir)
21
+ @options = default_options.merge(:working_dir => working_dir)
22
+ @options.merge!(YAML.load(File.read(self.config_path))) if File.exists?(self.config_path)
23
+ end
24
+
25
+ def index_path
26
+ File.join(File.expand_path(self.working_dir), self.directory)
27
+ end
28
+
29
+ def mtime_path
30
+ File.join(index_path, 'mtime')
31
+ end
32
+
33
+ def config_path
34
+ File.join(File.expand_path(self.working_dir), '.frett.yml')
35
+ end
36
+
37
+ def method_missing(meth, *args, &block)
38
+ @options[meth]
39
+ end
40
+ end
41
+
42
+ end
@@ -0,0 +1,105 @@
1
+ require 'listen'
2
+ require 'ptools'
3
+ require 'mime/types'
4
+ require 'colorize'
5
+
6
+ class Frett::Indexer
7
+
8
+ def initialize(options = {})
9
+ @options = options
10
+ index!
11
+
12
+ ::Listen.to(Frett::Config.working_dir) do |modified, added, removed|
13
+ modified.each do |filename|
14
+ update_file(filename)
15
+ end
16
+
17
+ added.each do |filename|
18
+ update_file(filename)
19
+ end
20
+
21
+ removed.each do |filename|
22
+ remove_file(filename)
23
+ end
24
+ end
25
+ end
26
+
27
+ def index!
28
+ adapter.write do |index|
29
+ Dir.glob(File.join(Frett::Config.working_dir, "**/*"), File::FNM_CASEFOLD) do |filename|
30
+ if process?(filename) && needs_index?(filename)
31
+ index_file(index, filename)
32
+ end
33
+ end
34
+ end
35
+ end
36
+
37
+ def remove_file(filename)
38
+ return if filename.include?(Frett::Config.directory)
39
+ adapter.write do |index|
40
+ remove_from_index(index, filename)
41
+ end
42
+ end
43
+
44
+ def update_file(filename)
45
+ return unless process?(filename)
46
+ adapter.write do |index|
47
+ remove_from_index(index, filename)
48
+ index_file(index, filename)
49
+ end
50
+ end
51
+
52
+ private
53
+
54
+ def index_file(index, filename)
55
+ puts "INDEX #{filename}".green
56
+ file = File.new(filename, 'r')
57
+ line = 1
58
+ now = Time.now.to_i
59
+ while (text = file.gets)
60
+ content = text.gsub(/\n/, "").strip
61
+ index << {
62
+ :line => line,
63
+ :content => content,
64
+ :file => filename
65
+ }
66
+ line += 1
67
+ end
68
+ end
69
+
70
+ def remove_from_index(index, filename)
71
+ query = Ferret::Search::PrefixQuery.new(:file, filename)
72
+ doc_ids = index.scan(query, :limit => Frett::Config.num_docs)
73
+ puts "DELETE #{doc_ids.size} entries for #{filename}".red
74
+ doc_ids.each do |doc_id|
75
+ index.delete(doc_id)
76
+ end
77
+ end
78
+
79
+ def needs_index?(filename)
80
+ return true unless Frett::Config.consider_mtime
81
+ File.mtime(filename) > File.mtime(Frett::Config.mtime_path)
82
+ end
83
+
84
+ def process?(filename)
85
+ File.file?(filename) &&
86
+ !filename.include?(Frett::Config.directory) &&
87
+ !filename.include?(Frett::Config.service_name) &&
88
+ !(filename =~ /.*\/(_darcs|\..+?)\/.*/) &&
89
+ !excluded?(filename) &&
90
+ !MIME::Types.of(filename).any? { |type| type.binary? } &&
91
+ !File.binary?(filename)
92
+ end
93
+
94
+ def excluded?(filename)
95
+ filename.gsub(File.join(Frett::Config.working_dir,"/"), '') =~ exclude_regexp
96
+ end
97
+
98
+ def exclude_regexp
99
+ @exclude_regexp ||= Regexp.new(Frett::Config.exclude)
100
+ end
101
+
102
+ def adapter
103
+ @adapter ||= Frett::Adapter.new(@options)
104
+ end
105
+ end
@@ -0,0 +1,45 @@
1
+ class Frett::Search
2
+
3
+ def initialize(options = {})
4
+ @options = Frett::Config.search.merge(:default_field => :content).
5
+ merge(options)
6
+ end
7
+
8
+ def search(needle, path = nil)
9
+ results = []
10
+ adapter.read do |index|
11
+ index.search_each(build_query(needle, path), :limit => Frett::Config.num_docs) do |doc_id, score|
12
+ results.push result(index[doc_id])
13
+ end
14
+ end
15
+
16
+ puts ( results.size == 1 ? "1 match" : "#{results.size} matches" ).white
17
+ results.flatten.map { |result_line| puts result_line }
18
+ end
19
+
20
+ private
21
+
22
+ def result(doc)
23
+ file = doc[:file].gsub!(File.join(Frett::Config.working_dir,"/"), '')
24
+ content = ( doc[:content].length > 200 ) ? ( doc[:content][0..77] + "..." ) : doc[:content]
25
+ ["", file.light_yellow, "#{doc[:line]}: #{content.light_blue}"]
26
+ end
27
+
28
+ def adapter
29
+ @adapter ||= Frett::Adapter.new
30
+ end
31
+
32
+ def build_query(needle, path)
33
+ needle = escape(needle) if @options[:escape]
34
+ needle = "*#{needle}*" if @options[:use_wildcard]
35
+ #parsed = Ferret::QueryParser.new(:default_field => @options[:default_field], :or_default => @options[:use_or]).
36
+ #parse(needle.downcase)
37
+ q = "content:#{needle.downcase}" << ( path ? " + file:#{path}*" : "" )
38
+ Ferret::QueryParser.new(:fields => [:content, :file], :tokenized_fields => :content, :or_default => @options[:use_or]).
39
+ parse(q)
40
+ end
41
+
42
+ def escape(needle)
43
+ Regexp.escape(needle).gsub(/([:~!<>="])/,'\\\\\1')
44
+ end
45
+ end
data/lib/frett.rb ADDED
@@ -0,0 +1,11 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+
4
+ module Frett
5
+ VERSION = '0.0.2'
6
+ end
7
+
8
+ require 'rubygems'
9
+ %w(config adapter cli indexer search).each do |file|
10
+ require File.join(File.expand_path(File.dirname(__FILE__)), "frett", file)
11
+ end
data/script/console ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ # File: script/console
3
+ irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
4
+
5
+ libs = " -r irb/completion"
6
+ # Perhaps use a console_lib to store any extra methods I may want available in the cosole
7
+ # libs << " -r #{File.dirname(__FILE__) + '/../lib/console_lib/console_logger.rb'}"
8
+ libs << " -r #{File.dirname(__FILE__) + '/../lib/frett.rb'}"
9
+ puts "Loading frett gem"
10
+ exec "#{irb} #{libs} --simple-prompt"
@@ -0,0 +1,11 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+
3
+ class TestFrett < Test::Unit::TestCase
4
+
5
+ def setup
6
+ end
7
+
8
+ def test_truth
9
+ assert true
10
+ end
11
+ end
@@ -0,0 +1,14 @@
1
+ require File.join(File.dirname(__FILE__), "test_helper.rb")
2
+ require 'frett/cli'
3
+
4
+ class TestFrettCli < Test::Unit::TestCase
5
+ def setup
6
+ Frett::CLI.execute(@stdout_io = StringIO.new, [])
7
+ @stdout_io.rewind
8
+ @stdout = @stdout_io.read
9
+ end
10
+
11
+ def test_print_default_output
12
+ assert_match(/To update this executable/, @stdout)
13
+ end
14
+ end
@@ -0,0 +1,3 @@
1
+ require 'stringio'
2
+ require 'test/unit'
3
+ require File.dirname(__FILE__) + '/../lib/frett'
metadata ADDED
@@ -0,0 +1,233 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: frett
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 2
10
+ version: 0.0.2
11
+ platform: ruby
12
+ authors:
13
+ - johannes-kostas goetzinger
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2012-07-03 00:00:00 +02:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: daemons
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 1
32
+ - 1
33
+ - 8
34
+ version: 1.1.8
35
+ type: :runtime
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: ferret
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ hash: 63
46
+ segments:
47
+ - 0
48
+ - 11
49
+ - 8
50
+ - 4
51
+ version: 0.11.8.4
52
+ type: :runtime
53
+ version_requirements: *id002
54
+ - !ruby/object:Gem::Dependency
55
+ name: listen
56
+ prerelease: false
57
+ requirement: &id003 !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ hash: 1
63
+ segments:
64
+ - 0
65
+ - 4
66
+ - 7
67
+ version: 0.4.7
68
+ type: :runtime
69
+ version_requirements: *id003
70
+ - !ruby/object:Gem::Dependency
71
+ name: ptools
72
+ prerelease: false
73
+ requirement: &id004 !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ hash: 27
79
+ segments:
80
+ - 1
81
+ - 2
82
+ - 2
83
+ version: 1.2.2
84
+ type: :runtime
85
+ version_requirements: *id004
86
+ - !ruby/object:Gem::Dependency
87
+ name: colorize
88
+ prerelease: false
89
+ requirement: &id005 !ruby/object:Gem::Requirement
90
+ none: false
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ hash: 27
95
+ segments:
96
+ - 0
97
+ - 5
98
+ - 8
99
+ version: 0.5.8
100
+ type: :runtime
101
+ version_requirements: *id005
102
+ - !ruby/object:Gem::Dependency
103
+ name: mime-types
104
+ prerelease: false
105
+ requirement: &id006 !ruby/object:Gem::Requirement
106
+ none: false
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ hash: 41
111
+ segments:
112
+ - 1
113
+ - 19
114
+ version: "1.19"
115
+ type: :runtime
116
+ version_requirements: *id006
117
+ - !ruby/object:Gem::Dependency
118
+ name: rdoc
119
+ prerelease: false
120
+ requirement: &id007 !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ~>
124
+ - !ruby/object:Gem::Version
125
+ hash: 19
126
+ segments:
127
+ - 3
128
+ - 10
129
+ version: "3.10"
130
+ type: :development
131
+ version_requirements: *id007
132
+ - !ruby/object:Gem::Dependency
133
+ name: newgem
134
+ prerelease: false
135
+ requirement: &id008 !ruby/object:Gem::Requirement
136
+ none: false
137
+ requirements:
138
+ - - ">="
139
+ - !ruby/object:Gem::Version
140
+ hash: 5
141
+ segments:
142
+ - 1
143
+ - 5
144
+ - 3
145
+ version: 1.5.3
146
+ type: :development
147
+ version_requirements: *id008
148
+ - !ruby/object:Gem::Dependency
149
+ name: hoe
150
+ prerelease: false
151
+ requirement: &id009 !ruby/object:Gem::Requirement
152
+ none: false
153
+ requirements:
154
+ - - ~>
155
+ - !ruby/object:Gem::Version
156
+ hash: 7
157
+ segments:
158
+ - 3
159
+ - 0
160
+ version: "3.0"
161
+ type: :development
162
+ version_requirements: *id009
163
+ description: |-
164
+ the goal of frett is to provide a much quicker search functionality than ack on large projects.
165
+ it's built on top of the 'ferret' and 'listen' gems.
166
+ email:
167
+ - dbldots@gmail.com
168
+ executables:
169
+ - frett
170
+ - frett_service
171
+ extensions: []
172
+
173
+ extra_rdoc_files:
174
+ - History.txt
175
+ - Manifest.txt
176
+ - README.rdoc
177
+ files:
178
+ - History.txt
179
+ - Manifest.txt
180
+ - README.rdoc
181
+ - Rakefile
182
+ - bin/frett
183
+ - bin/frett_service
184
+ - lib/frett.rb
185
+ - lib/frett/adapter.rb
186
+ - lib/frett/cli.rb
187
+ - lib/frett/config.rb
188
+ - lib/frett/indexer.rb
189
+ - lib/frett/search.rb
190
+ - script/console
191
+ - test/test_frett.rb
192
+ - test/test_frett_cli.rb
193
+ - test/test_helper.rb
194
+ - .gemtest
195
+ has_rdoc: true
196
+ homepage: http://github.com/dbldots/frett
197
+ licenses: []
198
+
199
+ post_install_message:
200
+ rdoc_options:
201
+ - --main
202
+ - README.rdoc
203
+ require_paths:
204
+ - lib
205
+ required_ruby_version: !ruby/object:Gem::Requirement
206
+ none: false
207
+ requirements:
208
+ - - ">="
209
+ - !ruby/object:Gem::Version
210
+ hash: 3
211
+ segments:
212
+ - 0
213
+ version: "0"
214
+ required_rubygems_version: !ruby/object:Gem::Requirement
215
+ none: false
216
+ requirements:
217
+ - - ">="
218
+ - !ruby/object:Gem::Version
219
+ hash: 3
220
+ segments:
221
+ - 0
222
+ version: "0"
223
+ requirements: []
224
+
225
+ rubyforge_project: frett
226
+ rubygems_version: 1.6.2
227
+ signing_key:
228
+ specification_version: 3
229
+ summary: the goal of frett is to provide a much quicker search functionality than ack on large projects
230
+ test_files:
231
+ - test/test_frett.rb
232
+ - test/test_frett_cli.rb
233
+ - test/test_helper.rb