munger 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/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ pkg/*
2
+ *.gem
3
+ .bundle
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in munger.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,24 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ munger (1.0.0)
5
+
6
+ GEM
7
+ remote: http://rubygems.org/
8
+ specs:
9
+ columnize (0.3.4)
10
+ linecache (0.46)
11
+ rbx-require-relative (> 0.0.4)
12
+ rbx-require-relative (0.0.5)
13
+ ruby-debug (0.10.4)
14
+ columnize (>= 0.1)
15
+ ruby-debug-base (~> 0.10.4.0)
16
+ ruby-debug-base (0.10.4)
17
+ linecache (>= 0.3)
18
+
19
+ PLATFORMS
20
+ ruby
21
+
22
+ DEPENDENCIES
23
+ munger!
24
+ ruby-debug
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ # The MIT License
2
+ #
3
+ # Copyright (c) 2008-2011 Bryan Stearns
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ # THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,11 @@
1
+ = munger: a file-modification library (& command-line utility)
2
+
3
+ Programmatically modify files: insert something before, after, or replacing
4
+ a line that matches a pattern, or just append at the end.
5
+
6
+ (More docs to come.)
7
+
8
+ == Copyright
9
+
10
+ Copyright (c) 2008-2011 Bryan Stearns. See LICENSE.txt for
11
+ further details.
data/Rakefile ADDED
@@ -0,0 +1,13 @@
1
+ require 'bundler'
2
+ require 'rake'
3
+ require 'rake/testtask'
4
+
5
+ Bundler::GemHelper.install_tasks
6
+
7
+ Rake::TestTask.new(:test) do |test|
8
+ test.libs << 'lib' << 'test'
9
+ test.pattern = 'test/**/test_*.rb'
10
+ test.verbose = true
11
+ end
12
+
13
+ task :default => :test
data/bin/munge ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+ munger_path = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+ $LOAD_PATH.unshift(munger_path) unless $LOAD_PATH.include?(munger_path)
4
+
5
+ require 'munger'
6
+ require 'munger/cli'
7
+ Munger::CLI.run!(*ARGV)
data/lib/munger/cli.rb ADDED
@@ -0,0 +1,55 @@
1
+ require 'rubygems'
2
+ require 'ruby-debug'
3
+ require 'optparse'
4
+
5
+ module Munger
6
+ class CLI
7
+ def self.run!(*args)
8
+ return self.new(*args).run
9
+ end
10
+
11
+ def initialize(*args)
12
+ @args = args
13
+ parse_args
14
+ end
15
+
16
+ def parse_args
17
+ @content = OptionParser.new do |opts|
18
+ opts.banner = "Usage: munge <options> CONTENT"
19
+ opts.on("--before PATTERN", "Insert before the line matching PATTERN") {|@pattern| set_mode(:before) }
20
+ opts.on("--after PATTERN", "Insert after the line matching PATTERN") {|@pattern| set_mode(:after) }
21
+ opts.on("--replace PATTERN", "Replace the line matching PATTERN") {|@pattern| set_mode(:replace) }
22
+ opts.on("--append", "Append to the file") { set_mode(:append) }
23
+ opts.on("--replace-or-append PATTERN", "Replace the line matching PATTERN, or append if not found") {|@pattern| set_mode(:replace_or_append) }
24
+
25
+ opts.on("--tag TAG", "Mark our insertion with this TAG") {|@tag|}
26
+ opts.on("--input INPUT", "The filename to read; '-' for stdin") \
27
+ {|@input_path|}
28
+ opts.on("--output OUTPUT", "The filename to write; '-' for stdout") {|@output_path|}
29
+ opts.on("--content CONTENT", "A file from which to read the content to insert; '-' for stdin") \
30
+ {|@content_path|}
31
+ opts.on("-v", "--verbose", "Increase verbosity") {|@verbose|}
32
+ end.parse!(@args).first
33
+
34
+ set_mode(:append) unless @mode
35
+ abort "No --input path specified" unless @input_path
36
+ abort "No --output path specified" unless @output_path
37
+ abort "Can't specify --content with CONTENT" if (@content != nil && @content_path != nil)
38
+ abort "No content specified" unless (@content || @content_path)
39
+
40
+ @options = Munger::Munge::OPTIONS.inject({}) do |h, option|
41
+ h[option] = instance_variable_get("@#{option}") rescue nil
42
+ h
43
+ end
44
+ end
45
+
46
+ def run
47
+ Munger::munge(@options)
48
+ end
49
+
50
+ def set_mode(new_mode)
51
+ abort("Only one --before|--after|--replace|--append allowed") if @mode
52
+ @mode = new_mode
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,107 @@
1
+ module Munger
2
+ def self.munge(options={})
3
+ content = Munger.raw_or_path(options, :content, :content_path)
4
+ input = Munger.raw_or_path(options, :input, :input_path)
5
+ munge = Munger::Munge.new(options)
6
+ output = munge.run(input, content)
7
+ Munger.raw_or_path(options, :output, :output_path, output)
8
+ end
9
+
10
+ class Munge
11
+ OPTIONS = [:mode, :pattern, :tag, :content, :content_path, :input,
12
+ :input_path, :output, :output_path, :path, :verbose]
13
+ attr_accessor *(OPTIONS + [:start_tag, :end_tag])
14
+
15
+ def initialize(options)
16
+ self.mode = options[:mode] || :append
17
+ self.pattern = Regexp.compile(options[:pattern]) unless mode == :append
18
+ self.tag = options[:tag] || ''
19
+ self.verbose = options[:verbose]
20
+
21
+ if verbose
22
+ settings = OPTIONS.map {|attr| "#{attr} = #{eval "#{attr}.inspect"}" }
23
+ puts settings.join(', ')
24
+ end
25
+ end
26
+
27
+ def run(input, content)
28
+ startTag = tag + " (munge start)"
29
+ endTag = tag + " (munge end)"
30
+ content = [startTag, content.rstrip, endTag].join("\n")
31
+
32
+ result = []
33
+ skipping = nil
34
+ needMatch = [:before, :replace, :after, :replace_or_append].include? mode
35
+ input.split("\n").each do |l|
36
+ if skipping
37
+ if l == endTag
38
+ puts "Done skipping: #{l}" if verbose
39
+ skipping = nil
40
+ if [:replace, :replace_or_append].include?(mode)
41
+ puts "Inserting content" if verbose
42
+ result << content
43
+ end
44
+ else
45
+ puts "Skipping: #{l}" if verbose
46
+ end
47
+ elsif l == startTag
48
+ puts "Start skipping: #{l}" if verbose
49
+ skipping = true
50
+ needMatch = nil
51
+ else
52
+ matched = needMatch && pattern.match(l)
53
+ if mode == :before && matched
54
+ puts "Matched (before): inserting before #{l}" if verbose
55
+ result << content
56
+ needMatch = nil
57
+ end
58
+ if [:replace, :replace_or_append].include?(mode) && matched
59
+ puts "Matched (#{mode}): replacing #{l}" if verbose
60
+ result << content
61
+ needMatch = nil
62
+ else
63
+ puts "Using existing line #{l}" if verbose
64
+ result << l
65
+ end
66
+ if mode == :after && matched
67
+ puts "Matched (after): inserting after #{l}" if verbose
68
+ result << content
69
+ needMatch = nil
70
+ end
71
+ end
72
+ end
73
+
74
+ if mode == :append or (mode == :replace_or_append && needMatch)
75
+ puts "Appending..." if verbose
76
+ result << content
77
+ end
78
+
79
+ result << "" # make sure we end with a newline
80
+ result.join("\n")
81
+ end
82
+ end
83
+
84
+ private
85
+ def self.raw_or_path(options, raw_sym, path_sym, data_to_write=nil)
86
+ raw_value = options.delete(raw_sym)
87
+ path = options.delete(path_sym)
88
+ path ||= options[:path]
89
+ if data_to_write # we're writing
90
+ if path == '-'
91
+ STDOUT.write(data_to_write)
92
+ elsif path
93
+ File.open(path, 'w') {|f| f.write(data_to_write) }
94
+ else
95
+ data_to_write # just return it.
96
+ end
97
+ else # we're reading
98
+ if raw_value
99
+ raw_value
100
+ elsif path == '-'
101
+ STDIN.read
102
+ else
103
+ File.read(path)
104
+ end
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,3 @@
1
+ module Munger
2
+ VERSION = "0.0.1"
3
+ end
data/lib/munger.rb ADDED
@@ -0,0 +1 @@
1
+ require 'munger/munge'
data/munger.gemspec ADDED
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "munger/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "munger"
7
+ s.version = Munger::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Bryan Stearns"]
10
+ s.email = ["bryanstearns@gmail.com"]
11
+ s.homepage = "http://github.com/bryanstearns/munger"
12
+ s.summary = %q{File-content munging library (& command-line utility)}
13
+ s.description = """
14
+ Programmatically modify files: insert something before, after, or replacing
15
+ a line that matches a pattern, or just at the end.
16
+ """
17
+
18
+ s.rubyforge_project = "munger"
19
+
20
+ s.files = `git ls-files`.split("\n")
21
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
22
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
23
+ s.require_paths = ["lib"]
24
+
25
+ s.add_development_dependency(%q<ruby-debug>, [">= 0"])
26
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,23 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+
4
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
5
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
6
+
7
+ #[File.join(File.dirname(__FILE__), '..', 'lib', 'munger'),
8
+ # File.dirname(__FILE__)].each do |path|
9
+ # path = File.expand_path(path)
10
+ # unless $LOAD_PATH.include?(path)
11
+ # # puts "test/helper: $LOAD_PATH << #{path}"
12
+ # $LOAD_PATH.unshift(path)
13
+ # end
14
+ #end
15
+
16
+ require 'munger'
17
+
18
+ class Test::Unit::TestCase
19
+ end
20
+
21
+ def my_assert_equal(expected, was)
22
+ assert expected == was, "--- Expected:\n#{expected}\n--- Was:\n#{was}"
23
+ end
data/test/mungee ADDED
@@ -0,0 +1,5 @@
1
+ Jackdaws
2
+ Love my big
3
+ Sphinx
4
+ Of Quartz.
5
+
@@ -0,0 +1,150 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ class TestMunger < Test::Unit::TestCase
4
+ def setup
5
+ @verbose = nil
6
+ @text = """Existing line number one
7
+ Existing line number two
8
+ Existing line number three
9
+ """
10
+ end
11
+
12
+ def test_before
13
+ @text = Munger::munge(:mode => :before,
14
+ :pattern => "line number one",
15
+ :tag => "# BeforeOneTest", :input => @text,
16
+ :content => "This goes before line one",
17
+ :verbose => @verbose)
18
+ my_assert_equal \
19
+ """# BeforeOneTest (munge start)
20
+ This goes before line one
21
+ # BeforeOneTest (munge end)
22
+ Existing line number one
23
+ Existing line number two
24
+ Existing line number three
25
+ """, @text
26
+
27
+ @text = Munger::munge(:mode => :before,
28
+ :pattern => "line number two",
29
+ :tag => "# BeforeTwoTest", :input => @text,
30
+ :content => "This goes before line two",
31
+ :verbose => @verbose)
32
+ my_assert_equal \
33
+ """# BeforeOneTest (munge start)
34
+ This goes before line one
35
+ # BeforeOneTest (munge end)
36
+ Existing line number one
37
+ # BeforeTwoTest (munge start)
38
+ This goes before line two
39
+ # BeforeTwoTest (munge end)
40
+ Existing line number two
41
+ Existing line number three
42
+ """, @text
43
+ end
44
+
45
+ def test_after
46
+ @text = Munger::munge(:mode => :after,
47
+ :pattern => "line number three",
48
+ :tag => "# AfterThreeTest", :input => @text,
49
+ :content => "This goes after line three",
50
+ :verbose => @verbose)
51
+ my_assert_equal \
52
+ """Existing line number one
53
+ Existing line number two
54
+ Existing line number three
55
+ # AfterThreeTest (munge start)
56
+ This goes after line three
57
+ # AfterThreeTest (munge end)
58
+ """, @text
59
+
60
+ @text = Munger::munge(:mode => :after,
61
+ :pattern => "line number three",
62
+ :tag => "# AfterThreeTest", :input => @text,
63
+ :content => "New stuff for after line three",
64
+ :verbose => @verbose)
65
+ my_assert_equal \
66
+ """Existing line number one
67
+ Existing line number two
68
+ Existing line number three
69
+ # AfterThreeTest (munge start)
70
+ New stuff for after line three
71
+ # AfterThreeTest (munge end)
72
+ """, @text
73
+ end
74
+
75
+ def test_replace
76
+ @text = Munger::munge(:mode => :replace, :tag => "# ReplaceTest",
77
+ :pattern => "line number two",
78
+ :input => @text,
79
+ :content => "This is some stuff to replace with",
80
+ :verbose => @verbose)
81
+ my_assert_equal \
82
+ """Existing line number one
83
+ # ReplaceTest (munge start)
84
+ This is some stuff to replace with
85
+ # ReplaceTest (munge end)
86
+ Existing line number three
87
+ """, @text
88
+ end
89
+
90
+ def test_replace_or_append_replacing
91
+ @text = Munger::munge(:mode => :replace_or_append,
92
+ :tag => "# ReplaceOrAppendTest",
93
+ :pattern => "line number two",
94
+ :input => @text,
95
+ :content => "This is some stuff to replace with",
96
+ :verbose => @verbose)
97
+ my_assert_equal \
98
+ """Existing line number one
99
+ # ReplaceOrAppendTest (munge start)
100
+ This is some stuff to replace with
101
+ # ReplaceOrAppendTest (munge end)
102
+ Existing line number three
103
+ """, @text
104
+ end
105
+
106
+ def test_replace_or_append_appending
107
+ @text = Munger::munge(:mode => :replace_or_append,
108
+ :tag => "# ReplaceOrAppendTest",
109
+ :pattern => "does not exist",
110
+ :input => @text,
111
+ :content => "This is some stuff to replace with",
112
+ :verbose => @verbose)
113
+ my_assert_equal \
114
+ """Existing line number one
115
+ Existing line number two
116
+ Existing line number three
117
+ # ReplaceOrAppendTest (munge start)
118
+ This is some stuff to replace with
119
+ # ReplaceOrAppendTest (munge end)
120
+ """, @text
121
+ end
122
+
123
+ def test_append
124
+ @text = Munger::munge(:mode => :append, :tag => "# AppendTest",
125
+ :input => @text,
126
+ :content => "This is some stuff to append",
127
+ :verbose => @verbose)
128
+ my_assert_equal \
129
+ """Existing line number one
130
+ Existing line number two
131
+ Existing line number three
132
+ # AppendTest (munge start)
133
+ This is some stuff to append
134
+ # AppendTest (munge end)
135
+ """, @text
136
+
137
+ @text = Munger::munge(:mode => :append, :tag => "# AppendTest",
138
+ :input => @text,
139
+ :content => "New stuff to append",
140
+ :verbose => @verbose)
141
+ my_assert_equal \
142
+ """Existing line number one
143
+ Existing line number two
144
+ Existing line number three
145
+ # AppendTest (munge start)
146
+ New stuff to append
147
+ # AppendTest (munge end)
148
+ """, @text
149
+ end
150
+ end
metadata ADDED
@@ -0,0 +1,99 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: munger
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Bryan Stearns
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-08-13 00:00:00 -07:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: ruby-debug
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
+ - 0
32
+ version: "0"
33
+ type: :development
34
+ version_requirements: *id001
35
+ description: |
36
+
37
+ Programmatically modify files: insert something before, after, or replacing
38
+ a line that matches a pattern, or just at the end.
39
+
40
+ email:
41
+ - bryanstearns@gmail.com
42
+ executables:
43
+ - munge
44
+ extensions: []
45
+
46
+ extra_rdoc_files: []
47
+
48
+ files:
49
+ - .gitignore
50
+ - Gemfile
51
+ - Gemfile.lock
52
+ - LICENSE.txt
53
+ - README.rdoc
54
+ - Rakefile
55
+ - bin/munge
56
+ - lib/munger.rb
57
+ - lib/munger/cli.rb
58
+ - lib/munger/munge.rb
59
+ - lib/munger/version.rb
60
+ - munger.gemspec
61
+ - test/helper.rb
62
+ - test/mungee
63
+ - test/test_munger.rb
64
+ has_rdoc: true
65
+ homepage: http://github.com/bryanstearns/munger
66
+ licenses: []
67
+
68
+ post_install_message:
69
+ rdoc_options: []
70
+
71
+ require_paths:
72
+ - lib
73
+ required_ruby_version: !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ hash: 3
79
+ segments:
80
+ - 0
81
+ version: "0"
82
+ required_rubygems_version: !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ hash: 3
88
+ segments:
89
+ - 0
90
+ version: "0"
91
+ requirements: []
92
+
93
+ rubyforge_project: munger
94
+ rubygems_version: 1.4.2
95
+ signing_key:
96
+ specification_version: 3
97
+ summary: File-content munging library (& command-line utility)
98
+ test_files: []
99
+