irep 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 4005baa72a957f7853bff71888934e4ae7d0c847
4
+ data.tar.gz: 6b176c486806eff73de640603beac48f5f2f5d43
5
+ SHA512:
6
+ metadata.gz: fac2b782bcf6b62569be486a330291dcf449c84b444e80c84d4fe112eee80ea711823cde0e530bdbb820c927e089be3991627d9ee9079bc822f702c9224a0738
7
+ data.tar.gz: e735dcc4e556fec768dca48aa266829e23047b723556b8d42ccb95303d9fb5a66495e3c6b4375f053ee5fd269ea97875a93da1a73aad7a8f0f8aac3d7e58bab4
data/.commit_template ADDED
@@ -0,0 +1,20 @@
1
+
2
+
3
+ # ==== Emoji ====
4
+ # ✨ :sparkles: when adding feature, 機能を追加
5
+ # 🗑 :wastebasket: when removing feature, 機能を削除
6
+ # 🐛 :bug: when fixing a bug, バグ修正
7
+ # 🚀 :rocket: when improving performance, パフォーマンス改善
8
+ # ♻️ :recycle: refactoring, リファクタリング
9
+ # ✅ :white_check_mark: when adding tests, テスト追加
10
+ # 🔈 :speaker: when adding logging, ログを追加
11
+ # 🔇 :mute: when reducing logging, ログを削除
12
+ # 🔒 :lock: when dealing with security, セキュリティ関係
13
+ # ⬆️ :arrow_up: when upgrading dependencies, 依存関係をアップグレード
14
+ # ⬇️ :arrow_down: when downgrading dependencies, 依存関係をダウングレード
15
+ # 📝 :memo: when writing docs or notes, ドキュメントやメモの追加
16
+ # 🎉 :tada: release, リリース
17
+ # 🚧 :construction: work in progress*, 作業中*
18
+ #
19
+ # *deprecation
20
+
data/.gitignore ADDED
@@ -0,0 +1,10 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ /vendor/bundle
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in irep.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,23 @@
1
+ # Irep
2
+
3
+ *This project is under development...*
4
+
5
+ ## Installation
6
+
7
+ Install it yourself as:
8
+
9
+ $ gem install irep
10
+
11
+ ## Usage
12
+
13
+ TODO: Write usage instructions here
14
+
15
+ ## Development
16
+
17
+ After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
18
+
19
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
20
+
21
+ ## Contributing
22
+
23
+ Bug reports and pull requests are welcome on GitHub at https://github.com/shuuuuun/irep.
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rake/testtask'
3
+
4
+ Rake::TestTask.new(:test) do |test|
5
+ test.libs += %w(lib test)
6
+ test.test_files = FileList['test/**/test_*.rb']
7
+ test.verbose = true
8
+ end
data/bin/console ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "irep"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ require "pry"
10
+ Pry.start
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rainbow'
4
+
5
+ all_colors = %i(black red green yellow blue magenta cyan white aliceblue antiquewhite aqua aquamarine azure beige bisque blanchedalmond blueviolet brown burlywood cadetblue chartreuse chocolate coral cornflower cornsilk crimson darkblue darkcyan darkgoldenrod darkgray darkgreen darkkhaki darkmagenta darkolivegreen darkorange darkorchid darkred darksalmon darkseagreen darkslateblue darkslategray darkturquoise darkviolet deeppink deepskyblue dimgray dodgerblue firebrick floralwhite forestgreen fuchsia gainsboro ghostwhite gold goldenrod gray greenyellow honeydew hotpink indianred indigo ivory khaki lavender lavenderblush lawngreen lemonchiffon lightblue lightcoral lightcyan lightgoldenrod lightgray lightgreen lightpink lightsalmon lightseagreen lightskyblue lightslategray lightsteelblue lightyellow lime limegreen linen maroon mediumaquamarine mediumblue mediumorchid mediumpurple mediumseagreen mediumslateblue mediumspringgreen mediumturquoise mediumvioletred midnightblue mintcream mistyrose moccasin navajowhite navyblue oldlace olive olivedrab orange orangered orchid palegoldenrod palegreen paleturquoise palevioletred papayawhip peachpuff peru pink plum powderblue purple rebeccapurple rosybrown royalblue saddlebrown salmon sandybrown seagreen seashell sienna silver skyblue slateblue slategray snow springgreen steelblue tan teal thistle tomato turquoise violet webgray webgreen webmaroon webpurple wheat whitesmoke yellowgreen)
6
+
7
+ puts all_colors.map { |color| Rainbow(color).color(color) }.join(' ')
data/exe/irep ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'irep'
4
+
5
+ Irep::CLI.execute(STDOUT, ARGV)
data/irep.gemspec ADDED
@@ -0,0 +1,37 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'irep/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "irep"
8
+ spec.version = Irep::VERSION
9
+ spec.authors = ["motoki-shun"]
10
+ spec.email = ["shuuuuuny@gmail.com"]
11
+
12
+ spec.summary = "" # %q{TODO: Write a short summary, because Rubygems requires one.}
13
+ spec.description = "" # %q{TODO: Write a longer description or delete this line.}
14
+ spec.homepage = "" # "TODO: Put your gem's website or public repo URL here."
15
+
16
+ if spec.respond_to?(:metadata)
17
+ spec.metadata['allowed_push_host'] = 'https://rubygems.org'
18
+ else
19
+ raise "RubyGems 2.0 or newer is required to protect against " \
20
+ "public gem pushes."
21
+ end
22
+
23
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
24
+ f.match(%r{^(test|spec|features)/})
25
+ end
26
+ spec.bindir = "exe"
27
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
28
+ spec.require_paths = ["lib"]
29
+
30
+ spec.add_development_dependency "bundler", "~> 1.14"
31
+ spec.add_development_dependency "rake", "~> 10.0"
32
+ spec.add_development_dependency 'test-unit'
33
+ spec.add_development_dependency 'test-unit-rr'
34
+ spec.add_development_dependency 'pry'
35
+
36
+ spec.add_dependency 'rainbow'
37
+ end
data/lib/irep.rb ADDED
@@ -0,0 +1,8 @@
1
+ require "irep/version"
2
+ require "irep/cli"
3
+ require "irep/search"
4
+ require "irep/replace"
5
+
6
+ module Irep
7
+ # Your code goes here...
8
+ end
data/lib/irep/cli.rb ADDED
@@ -0,0 +1,77 @@
1
+ require 'optparse'
2
+ require 'irep/search'
3
+ require 'irep/replace'
4
+ require 'irep/interface'
5
+
6
+ module Irep
7
+ class CLI
8
+ def self.execute(stdout, argv = [])
9
+ # puts "argv: #{argv}"
10
+ opts, args = parse_options argv
11
+ # stdout.print parser.help
12
+ Interface.info "opts: #{opts}"
13
+ Interface.info "args: #{args}"
14
+
15
+ search_text = args[0]
16
+ replace_text = args[1]
17
+ unless search_text
18
+ usage 'invalid args.'
19
+ end
20
+
21
+ search = Search.new path: opts[:path], search_text: search_text
22
+ search.find_directory
23
+ search.find_filename
24
+ search.find_in_file_recursive
25
+
26
+ unless opts[:replace]
27
+ search.show_results
28
+ exit
29
+ end
30
+ Replace.replace_by_search_results_interactively search.results, search_text, replace_text
31
+ end
32
+
33
+ def self.parse_options(argv = [])
34
+ options = {
35
+ path: '.',
36
+ replace: true
37
+ }
38
+
39
+ parser.on('--[no-]replace') { |v| options[:replace] = v }
40
+ parser.on('--path VAL') { |v| options[:path] = v }
41
+ # parser.on('--only-search') { |v| options[:replace] = false }
42
+ # parser.on('--search') { |v| options[:replace] = false }
43
+ # parser.on('--interactive') { |v| options[:interactive] = v }
44
+ # parser.on('--directory VAL') { |v| options[:directory] = v }
45
+ # parser.on('--file VAL') { |v| options[:file] = v }
46
+ # parser.on('--count') { |v| options[:count] = true }
47
+ # parser.on('--files-without-matches') { |v| options[:files_without_matches] = true }
48
+ # parser.on('--literal') { |v| options[:literal] = true }
49
+ # parser.on('--regexp') { |v| options[:regexp] = true }
50
+ # parser.on('--smart-case') { |v| options[:smart_case] = true }
51
+ # parser.on('--ignore-case') { |v| options[:ignore_case] = true }
52
+ # parser.on('--strict-case') { |v| options[:strict_case] = true }
53
+ # parser.on('--show-hidden-files') { |v| options[:show_hidden_files] = true }
54
+ # parser.on('--dry-run') { |v| options[:dry_run] = true }
55
+ # parser.on('--verbose') { |v| options[:verbose] = true }
56
+
57
+ begin
58
+ # parser.parse!(argv)
59
+ arguments = parser.parse(argv)
60
+ rescue OptionParser::InvalidOption => e
61
+ usage e.message
62
+ end
63
+
64
+ [options, arguments]
65
+ end
66
+
67
+ def self.usage(msg = nil)
68
+ Interface.error "Error: #{msg}" if msg
69
+ puts parser.help
70
+ exit 1
71
+ end
72
+
73
+ def self.parser
74
+ @@parser ||= OptionParser.new
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,59 @@
1
+ require 'rainbow'
2
+
3
+ module Irep
4
+ class Interface
5
+ def initialize(cases: [], message:)
6
+ @cases = cases
7
+ @message = message
8
+ @quit = false
9
+ end
10
+
11
+ def listen(opts = {})
12
+ return if @quit
13
+ listening = true
14
+ while listening
15
+ puts "\n"
16
+ puts "path: #{opts[:path]}"
17
+ puts Rainbow("- #{opts[:preview]}").red if opts[:preview]
18
+ puts Rainbow("+ #{opts[:result_preview]}").green if opts[:result_preview]
19
+ # print 'Replace [y,n,q,a,d,/,j,J,g,e,?]? '
20
+ print Rainbow("#{@message} [#{@cases.map {|c| c[:cmd]}.join(',')}]? ").bold.lightskyblue
21
+ cmd = self.class.get_input
22
+ match_case = @cases.select {|c| c[:cmd] == cmd.downcase }.first
23
+ if match_case
24
+ match_case[:func].call(*opts[:proc_args]) if match_case[:func]
25
+ listening = false
26
+ else
27
+ msg = @cases.map { |c| "#{c[:cmd]} - #{c[:help]}" }.join("\n")
28
+ puts Rainbow("#{msg}").bold.maroon
29
+ end
30
+ end
31
+ end
32
+
33
+ def quit
34
+ @quit = true
35
+ end
36
+
37
+ def self.get_input
38
+ STDIN.gets.chomp
39
+ end
40
+
41
+ def self.show_search_results(path:, line:, preview:)
42
+ puts "\n"
43
+ puts Rainbow("#{path}").lightgreen
44
+ puts "#{Rainbow(line).darkgoldenrod}: #{preview}"
45
+ end
46
+
47
+ def self.error(text)
48
+ puts Rainbow(text).red
49
+ end
50
+
51
+ def self.info(text)
52
+ puts Rainbow(text).navajowhite
53
+ end
54
+
55
+ def self.debug(text)
56
+ puts Rainbow(text).saddlebrown
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,101 @@
1
+ require 'irep/interface'
2
+
3
+ module Irep
4
+ module Replace
5
+ extend self
6
+
7
+ def replace_by_search_results(search_results, search_text, replace_text)
8
+ # TODO: replace_by_search_results
9
+ end
10
+
11
+ def replace_by_search_results_interactively(search_results, search_text, replace_text)
12
+ search_results.each do |result|
13
+ next unless result[:preview]
14
+ result[:result_preview] = result[:preview].gsub(search_text, replace_text)
15
+ end
16
+ listened_results = listen_if_replace(search_results)
17
+ replace_in_file_by_results listened_results.select { |r| r[:type] == 'in_file' }, search_text, replace_text
18
+ listened_results.select { |r| r[:type] == 'filename' || r[:type] == 'directory' }.each do |result|
19
+ next unless result[:should_replace]
20
+ rename_path result[:path], search_text, replace_text
21
+ end
22
+ end
23
+
24
+ def rename_path(path, before, after)
25
+ File.rename path, path.gsub(before, after)
26
+ end
27
+
28
+ def replace_in_file(file_path, before, after='')
29
+ txt = File.read(file_path).gsub(before, after)
30
+ File.write(file_path, txt)
31
+ end
32
+
33
+ def replace_in_file_by_results(search_results, search_text, replace_text)
34
+ grouped_results = search_results.group_by { |r| r[:path] }
35
+ grouped_results.each do |path, results|
36
+ file_text = File.read(path)
37
+ # 文字列を特定位置で分割して配列にできたらいいかも?
38
+ result_index = 0
39
+ replaced_text = file_text.split(/(#{search_text})/).map do |text|
40
+ next text if text != search_text
41
+ result = results[result_index]
42
+ result_index += 1
43
+ if result.fetch(:should_replace, false)
44
+ replace_text
45
+ else
46
+ text
47
+ end
48
+ end.join('')
49
+ File.write(path, replaced_text)
50
+ end
51
+ end
52
+
53
+ private
54
+
55
+ def listen_if_replace(results)
56
+ interface = Interface.new(message: 'Replace', cases: [{
57
+ cmd: 'y',
58
+ help: 'yes, Replace it.',
59
+ func: proc { |result|
60
+ result[:should_replace] = true
61
+ }
62
+ }, {
63
+ cmd: 'n',
64
+ help: 'no, Don\'t replace it.',
65
+ }, {
66
+ cmd: 'q',
67
+ help: 'quit, Don\'t apply any replacement after this.',
68
+ func: proc {
69
+ interface.quit
70
+ }
71
+ }, {
72
+ cmd: 'a',
73
+ help: 'all, Apply all replacement after this.',
74
+ func: proc {
75
+ # TODO
76
+ }
77
+ # }, {
78
+ # cmd: 'h',
79
+ # help: 'help, Show this help.',
80
+ # func: proc {
81
+ # # TODO: help
82
+ # }
83
+ # }, {
84
+ # cmd: '?',
85
+ # help: 'help, Show this help.',
86
+ # func: proc {
87
+ # # TODO: help
88
+ # }
89
+ }])
90
+ results.each do |result|
91
+ interface.listen(
92
+ path: result[:path],
93
+ preview: result[:preview],
94
+ result_preview: result[:result_preview],
95
+ proc_args: [result]
96
+ )
97
+ end
98
+ results
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,118 @@
1
+ require 'irep/interface'
2
+
3
+ module Irep
4
+ class Search
5
+ attr_reader :results
6
+
7
+ def initialize(opts = {})
8
+ @results = []
9
+ @path = opts[:path]
10
+ @search_text = opts[:search_text]
11
+ @delimiter = "\n"
12
+ end
13
+
14
+ def find_directory
15
+ match_dir_list = target_directory_paths.select do |path|
16
+ path.include?(@search_text)
17
+ end
18
+ current_results = match_dir_list.map do |path|
19
+ {
20
+ type: 'directory',
21
+ path: path,
22
+ preview: path,
23
+ }
24
+ end
25
+ @results.concat current_results
26
+ end
27
+
28
+ def find_filename
29
+ match_file_list = target_file_paths.select do |path|
30
+ path.include?(@search_text)
31
+ end
32
+ current_results = match_file_list.map do |path|
33
+ {
34
+ type: 'filename',
35
+ path: path,
36
+ preview: path,
37
+ }
38
+ end
39
+ @results.concat current_results
40
+ end
41
+
42
+ def find_in_file_recursive
43
+ target_file_paths.each do |file_path|
44
+ find_in_file(file_path)
45
+ end
46
+ end
47
+
48
+ def find_in_file(file_path)
49
+ file_text = File.read(file_path)
50
+ file_text.force_encoding('UTF-8')
51
+ file_text.scrub!('?')
52
+ # 配列にしてeachだと遅そうな気がする。あとで確認してもいいかも。
53
+ # file_lines = file_text.split(@delimiter)
54
+ # file_lines.each do |line|
55
+ # end
56
+ match_data_list = match_global(file_text, @search_text)
57
+ current_results = match_data_list.map do |match_data|
58
+ line_num = match_line_num(file_text, match_data)
59
+ {
60
+ match_data: match_data,
61
+ type: 'in_file', # in_file, directory, filename
62
+ path: file_path, # 'path/to/file_or_directory'
63
+ offset: match_data.begin(0), # x 全体の何文字目か
64
+ line: line_num, # y, row 行数
65
+ colmun: match_colmun_num(file_text, match_data), # x, colmun その行の何文字目か
66
+ preview: extract_line(file_text, line_num, 1), # プレビュー表示するテキスト(マッチした行+数行)
67
+ }
68
+ end
69
+ @results.concat current_results
70
+ end
71
+
72
+ def show_results
73
+ Interface.error('no search results.') && return if @results.empty?
74
+ @results.each do |result|
75
+ Interface.show_search_results path: result[:path], line: result[:line], preview: result[:preview]
76
+ end
77
+ end
78
+
79
+ private
80
+
81
+ def target_file_paths
82
+ # TODO: ignore
83
+ paths = Dir.glob "#{@path}/**/*"
84
+ paths.reject { |path| File.directory?(path) }
85
+ end
86
+
87
+ def target_directory_paths
88
+ # TODO: ignore
89
+ paths = Dir.glob "#{@path}/**/*"
90
+ paths.select { |path| File.directory?(path) }
91
+ end
92
+
93
+ def extract_line(text, line_num, size)
94
+ text.split(@delimiter)[line_num - 1]
95
+ end
96
+
97
+ def match_line_num(text, match_data)
98
+ offset = match_data.begin(0)
99
+ text.slice(0..offset).count(@delimiter) + 1
100
+ end
101
+
102
+ def match_colmun_num(text, match_data)
103
+ offset = match_data.begin(0)
104
+ text.slice(0..offset).split(@delimiter).last.size - 1
105
+ end
106
+
107
+ def match_global(str, regexp)
108
+ match_data_list = []
109
+ match_data = str.match(regexp)
110
+ until match_data.nil?
111
+ match_data_list << match_data
112
+ offset = match_data.end(0)
113
+ match_data = str.match(regexp, offset)
114
+ end
115
+ match_data_list
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,3 @@
1
+ module Irep
2
+ VERSION = "0.1.0"
3
+ end
metadata ADDED
@@ -0,0 +1,145 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: irep
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - motoki-shun
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2017-07-29 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.14'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.14'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: test-unit
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: test-unit-rr
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: pry
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rainbow
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ description: ''
98
+ email:
99
+ - shuuuuuny@gmail.com
100
+ executables:
101
+ - irep
102
+ extensions: []
103
+ extra_rdoc_files: []
104
+ files:
105
+ - ".commit_template"
106
+ - ".gitignore"
107
+ - Gemfile
108
+ - README.md
109
+ - Rakefile
110
+ - bin/console
111
+ - bin/setup
112
+ - bin/show_rainbow_colors
113
+ - exe/irep
114
+ - irep.gemspec
115
+ - lib/irep.rb
116
+ - lib/irep/cli.rb
117
+ - lib/irep/interface.rb
118
+ - lib/irep/replace.rb
119
+ - lib/irep/search.rb
120
+ - lib/irep/version.rb
121
+ homepage: ''
122
+ licenses: []
123
+ metadata:
124
+ allowed_push_host: https://rubygems.org
125
+ post_install_message:
126
+ rdoc_options: []
127
+ require_paths:
128
+ - lib
129
+ required_ruby_version: !ruby/object:Gem::Requirement
130
+ requirements:
131
+ - - ">="
132
+ - !ruby/object:Gem::Version
133
+ version: '0'
134
+ required_rubygems_version: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ requirements: []
140
+ rubyforge_project:
141
+ rubygems_version: 2.6.11
142
+ signing_key:
143
+ specification_version: 4
144
+ summary: ''
145
+ test_files: []