findr 0.0.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.
- data/bin/findr +6 -0
- data/findr.gemspec +43 -0
- data/lib/findr.rb +2 -0
- data/lib/findr/cli.rb +131 -0
- data/lib/findr/version.rb +3 -0
- metadata +53 -0
data/bin/findr
ADDED
data/findr.gemspec
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
|
2
|
+
# -*- encoding: utf-8 -*-
|
3
|
+
$:.push('lib')
|
4
|
+
require "findr/version"
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = "findr"
|
8
|
+
s.version = Findr::VERSION.dup
|
9
|
+
s.date = "2012-06-01"
|
10
|
+
s.summary = "A ruby find and replace tool for batch editing text files."
|
11
|
+
s.email = "Markus@ITstrauss.eu"
|
12
|
+
s.homepage = "https://github.com/mstrauss/findr"
|
13
|
+
s.authors = ['Markus Strauss']
|
14
|
+
|
15
|
+
s.description = <<-EOF
|
16
|
+
A ruby find and replace tool for batch editing text files.
|
17
|
+
EOF
|
18
|
+
|
19
|
+
dependencies = [
|
20
|
+
# Examples:
|
21
|
+
# [:runtime, "rack", "~> 1.1"],
|
22
|
+
# [:development, "rspec", "~> 2.1"],
|
23
|
+
]
|
24
|
+
|
25
|
+
s.files = Dir['**/*']
|
26
|
+
s.test_files = Dir['test/**/*'] + Dir['spec/**/*']
|
27
|
+
s.executables = Dir['bin/*'].map { |f| File.basename(f) }
|
28
|
+
s.require_paths = ["lib"]
|
29
|
+
|
30
|
+
|
31
|
+
## Make sure you can build the gem on older versions of RubyGems too:
|
32
|
+
s.rubygems_version = "1.8.11"
|
33
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
34
|
+
s.specification_version = 3 if s.respond_to? :specification_version
|
35
|
+
|
36
|
+
dependencies.each do |type, name, version|
|
37
|
+
if s.respond_to?("add_#{type}_dependency")
|
38
|
+
s.send("add_#{type}_dependency", name, version)
|
39
|
+
else
|
40
|
+
s.add_dependency(name, version)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
data/lib/findr.rb
ADDED
data/lib/findr/cli.rb
ADDED
@@ -0,0 +1,131 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'pathname'
|
3
|
+
require 'tempfile'
|
4
|
+
require 'optparse'
|
5
|
+
|
6
|
+
# this is deprecated on 1.9, but still works fine
|
7
|
+
require 'iconv'
|
8
|
+
|
9
|
+
module Findr
|
10
|
+
|
11
|
+
class CLI
|
12
|
+
|
13
|
+
def colorize(text, color_code)
|
14
|
+
"\e[#{color_code}m#{text}\e[0m"
|
15
|
+
end
|
16
|
+
|
17
|
+
def red(text); colorize(text, 31); end
|
18
|
+
def green(text); colorize(text, 32); end
|
19
|
+
def yellow(text); colorize(text, 33); end
|
20
|
+
def blue(text); colorize(text, 34); end
|
21
|
+
|
22
|
+
def banner
|
23
|
+
("Usage: #{Pathname($0).basename} [options] <search regex> [<replacement string>]" + $/) +
|
24
|
+
red("THIS PROGRAM COMES WITH NO WARRANTY WHATSOEVER. MAKE BACKUPS!")
|
25
|
+
end
|
26
|
+
|
27
|
+
def show_usage
|
28
|
+
puts(@option_parser.help)
|
29
|
+
exit
|
30
|
+
end
|
31
|
+
|
32
|
+
def execute(stdout, arguments=[])
|
33
|
+
# unless arguments[0]
|
34
|
+
# end
|
35
|
+
|
36
|
+
# default options
|
37
|
+
options = {}
|
38
|
+
options[:glob] = '*'
|
39
|
+
options[:coding] = 'utf-8'
|
40
|
+
|
41
|
+
@option_parser = OptionParser.new do |opts|
|
42
|
+
opts.on('-g', '--glob FILE SEARCH GLOB', 'e.g. "*.{rb,erb}"') do |glob|
|
43
|
+
options[:glob] = glob
|
44
|
+
end
|
45
|
+
opts.on('-x', '--execute', 'actually execute the replacement') do
|
46
|
+
options[:force] = true
|
47
|
+
end
|
48
|
+
opts.on('-c', '--coding FILE CODING SYSTEM', 'e.g. "latin-1"') do |coding|
|
49
|
+
options[:coding] = coding
|
50
|
+
end
|
51
|
+
end
|
52
|
+
@option_parser.banner = self.banner
|
53
|
+
@option_parser.parse!( arguments )
|
54
|
+
|
55
|
+
show_usage if arguments.size == 0
|
56
|
+
arguments.clone.each do |arg|
|
57
|
+
if !options[:find]
|
58
|
+
options[:find] = Regexp.compile( arg )
|
59
|
+
arguments.delete_at(0)
|
60
|
+
elsif !options[:replace]
|
61
|
+
options[:replace] = arg
|
62
|
+
arguments.delete_at(0)
|
63
|
+
else
|
64
|
+
show_usage
|
65
|
+
end
|
66
|
+
end
|
67
|
+
show_usage if arguments.size != 0
|
68
|
+
|
69
|
+
|
70
|
+
stdout.puts green "File inclusion glob: " + options[:glob]
|
71
|
+
stdout.puts green "Searching for regex " + options[:find].to_s
|
72
|
+
|
73
|
+
# some statistics
|
74
|
+
stats = {}
|
75
|
+
stats[:total_hits] = stats[:local_hits] = stats[:hit_files] = stats[:total_files] = 0
|
76
|
+
|
77
|
+
replacement_done = false
|
78
|
+
tempfile = nil
|
79
|
+
|
80
|
+
coding_to_utf8 = Iconv.new('utf-8', options[:coding])
|
81
|
+
utf8_to_coding = Iconv.new(options[:coding], 'utf-8')
|
82
|
+
|
83
|
+
Pathname.glob("**/#{options[:glob]}").each do |current_file|
|
84
|
+
next unless current_file.file?
|
85
|
+
stats[:total_files] += 1
|
86
|
+
stats[:local_hits] = 0
|
87
|
+
firstmatch = true
|
88
|
+
linenumber = 0
|
89
|
+
tempfile = Tempfile.new( 'current_file.basename' ) if options[:replace] && options[:force]
|
90
|
+
current_file.each_line do |l|
|
91
|
+
l = coding_to_utf8.iconv(l)
|
92
|
+
linenumber += 1
|
93
|
+
if l=~ options[:find]
|
94
|
+
stats[:local_hits] += 1
|
95
|
+
if firstmatch
|
96
|
+
stdout.puts red("#{current_file.cleanpath}:")
|
97
|
+
end
|
98
|
+
stdout.write( yellow( "%6d:" % [linenumber, l] ) )
|
99
|
+
stdout.puts l
|
100
|
+
firstmatch = false
|
101
|
+
if options[:replace]
|
102
|
+
stdout.write( blue( "%6d:" % [linenumber, l] ) )
|
103
|
+
l_repl = l.gsub( options[:find], options[:replace] )
|
104
|
+
tempfile.puts utf8_to_coding.iconv(l_repl) if tempfile
|
105
|
+
stdout.puts blue l_repl
|
106
|
+
replacement_done = true
|
107
|
+
end
|
108
|
+
elsif tempfile
|
109
|
+
tempfile.puts utf8_to_coding.iconv(l)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
if tempfile
|
113
|
+
tempfile.close
|
114
|
+
FileUtils.cp( tempfile.path, current_file ) if stats[:local_hits] > 0
|
115
|
+
tempfile.unlink
|
116
|
+
end
|
117
|
+
|
118
|
+
if stats[:local_hits] > 0
|
119
|
+
stats[:total_hits] += stats[:local_hits]
|
120
|
+
stats[:hit_files] += 1
|
121
|
+
end
|
122
|
+
|
123
|
+
end
|
124
|
+
|
125
|
+
# some statistics
|
126
|
+
stdout.puts green( "#{stats[:total_hits]} occurences (lines) in #{stats[:hit_files]} of #{stats[:total_files]} files found." )
|
127
|
+
end
|
128
|
+
|
129
|
+
end
|
130
|
+
|
131
|
+
end
|
metadata
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: findr
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Markus Strauss
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-06-01 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: ! 'A ruby find and replace tool for batch editing text files.
|
15
|
+
|
16
|
+
'
|
17
|
+
email: Markus@ITstrauss.eu
|
18
|
+
executables:
|
19
|
+
- findr
|
20
|
+
extensions: []
|
21
|
+
extra_rdoc_files: []
|
22
|
+
files:
|
23
|
+
- bin/findr
|
24
|
+
- findr.gemspec
|
25
|
+
- lib/findr/cli.rb
|
26
|
+
- lib/findr/version.rb
|
27
|
+
- lib/findr.rb
|
28
|
+
homepage: https://github.com/mstrauss/findr
|
29
|
+
licenses: []
|
30
|
+
post_install_message:
|
31
|
+
rdoc_options: []
|
32
|
+
require_paths:
|
33
|
+
- lib
|
34
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
35
|
+
none: false
|
36
|
+
requirements:
|
37
|
+
- - ! '>='
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0'
|
40
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
requirements: []
|
47
|
+
rubyforge_project:
|
48
|
+
rubygems_version: 1.8.11
|
49
|
+
signing_key:
|
50
|
+
specification_version: 3
|
51
|
+
summary: A ruby find and replace tool for batch editing text files.
|
52
|
+
test_files: []
|
53
|
+
has_rdoc:
|