mergit 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -27,7 +27,7 @@ Mergit uses simple text processing, therefore it can be tripped up. Some known
27
27
 
28
28
  Add this line to your application's Gemfile:
29
29
 
30
- gem 'mergit', '~> 1.0'
30
+ gem 'mergit', '~> 1.1'
31
31
 
32
32
  And then execute:
33
33
 
@@ -13,6 +13,10 @@ class Mergit
13
13
  # @return {Hash} A frozen hash with the rules for replacements.
14
14
  attr_reader :replacements
15
15
 
16
+ # All `require`d files will have 'MERGIT' start and end comments around them showing what file was included.
17
+ #
18
+ # The initial `:filename` or `:string` will not have 'MERGIT' comments.
19
+ #
16
20
  # @param [Array<Pathname, String>] search_path The list of directories to search.
17
21
  # @param [Hash] replacements A list of keywords to replace.
18
22
  # @param [Hash] options Either `:filename` or `:string` should be set.
@@ -24,7 +28,7 @@ class Mergit
24
28
  @output = StringIO.new
25
29
  begin
26
30
  if options.key?(:filename)
27
- scan_file(Pathname.new(options[:filename]).realpath)
31
+ Pathname.new(options[:filename]).open('r') { |fp| scan(fp.read) }
28
32
  elsif options.key?(:string)
29
33
  scan(options[:string])
30
34
  end
@@ -35,32 +39,17 @@ class Mergit
35
39
 
36
40
  # Finds a library using the {#search_path}
37
41
  #
38
- # @param [String] lib_name The name of the library to look for.
42
+ # @param [String, Pathname] filename The name of the library to look for.
39
43
  # @return [Nil, Pathname] Returns `nil` if it isn't found or a {http://rubydoc.info/stdlib/pathname/frames Pathname} if it is found.
40
- def find_requirement lib_name
44
+ def find_requirement filename
45
+ filename = Pathname.new filename
41
46
  @search_path.each do |directory|
42
- possible_path = directory + "#{lib_name}.rb"
47
+ possible_path = directory + filename.dirname + "#{filename.basename('.rb')}.rb"
43
48
  return possible_path.realpath if possible_path.file?
44
49
  end
45
50
  nil
46
51
  end
47
52
 
48
-
49
- # Finds a library using the {#search_path}
50
- #
51
- # This is identical to {#find_requirement} except it raises {Mergit::RequirementNotFound} if
52
- # it fails to find the library.
53
- #
54
- # @raise [Mergit::RequirementNotFound] if it can't find the library.
55
- # @param (see #find_requirement)
56
- # @return [Pathname] Returns the {http://rubydoc.info/stdlib/pathname/frames Pathname} of the library.
57
- # @see #find_requirement
58
- def find_requirement! lib_name
59
- find_requirement(lib_name).tap do |retval|
60
- raise Mergit::RequirementNotFound.new("Unabled to find require'd file: #{lib_name}") if retval.nil?
61
- end
62
- end
63
-
64
53
  ## Scans a single line of the file.
65
54
  #
66
55
  # It looks for things that need to be changed, and {#emit}s the resulting
@@ -72,13 +61,8 @@ class Mergit
72
61
  line.chomp!
73
62
  if line =~ /#\s*MERGIT:\s*skip\s*$/
74
63
  nil # do nothing
75
- elsif line =~ /^\s*require\s+'([^']+)'\s*$/ or line =~ /^\s*require\s+"([^"]+)"\s*$/
76
- requirement = find_requirement($1)
77
- if requirement.nil?
78
- emit line
79
- else
80
- scan_file requirement
81
- end
64
+ elsif line =~ /^\s*require\s+'([^']+)'/ or line =~ /^\s*require\s+"([^"]+)"/
65
+ scan_file($1) or emit(line)
82
66
  else
83
67
  replacements.each_key do |string_to_replace|
84
68
  line.gsub!(string_to_replace, replacements[string_to_replace])
@@ -91,27 +75,27 @@ class Mergit
91
75
  #
92
76
  # It passes each line of the file to {#scan_line} for parsing.
93
77
  #
78
+ # If the `filename` was already scanned, it'll do nothing and return `true`.
79
+ #
80
+ # If the `filename` doesn't exist in the {#search_path}, then it'll return `false`.
81
+ #
94
82
  # @param [Pathname] filename The file to scan.
95
- # @return [Nil]
83
+ # @return [FalseClass, TrueClass] Returns true if the file was emitted. Returns false if it cannot find the file in {#search_path}
96
84
  def scan_file filename
97
- relative_filename = if filename.relative?
98
- filename
99
- else
100
- filename.relative_path_from(Pathname.pwd)
101
- end
102
- if @visited_files.include? relative_filename
103
- return
104
- else
105
- @visited_files << relative_filename
106
- end
107
- emit "### MERGIT: Start of '#{relative_filename}'"
108
- filename.readlines.each { |line| scan_line line }
109
- emit "### MERGIT: End of '#{relative_filename}'"
85
+ filename_path = find_requirement(filename)
86
+ return false if filename_path.nil?
87
+ return true if @visited_files.include? filename_path
88
+
89
+ @visited_files << filename_path
90
+ emit "### MERGIT: Start of '#{filename}'"
91
+ filename_path.readlines.each { |line| scan_line line }
92
+ emit "### MERGIT: End of '#{filename}'"
93
+ return true
110
94
  end
111
95
 
112
96
  ## Scans a string
113
97
  #
114
- # It splits a string up into individual line via {#string_split} and
98
+ # It splits a string up into individual lines via {#string_split} and
115
99
  # passes them to {#scan_line}.
116
100
  #
117
101
  # @param [String] string The string to parse.
@@ -1,5 +1,5 @@
1
1
  # coding: utf-8
2
2
  class Mergit
3
3
  # The version of the Mergit Library.
4
- VERSION = "1.0.0"
4
+ VERSION = "1.1.0"
5
5
  end
@@ -0,0 +1,5 @@
1
+ puts "I'm requiring the no require file."
2
+
3
+ require 'no_requires'
4
+
5
+ puts "See!"
@@ -0,0 +1,3 @@
1
+ puts "Hi! I have no require lines."
2
+ puts "But I have lots to say!"
3
+ puts "Like 'supercalifragilisticexpialidocious'."
@@ -0,0 +1,2 @@
1
+ puts "I'm a ruby file that has a parent directory."
2
+ puts "I'm useful for testing relative paths."
@@ -2,87 +2,139 @@ require 'spec_helper'
2
2
  require 'mergit/processor'
3
3
 
4
4
  describe Mergit::Processor do
5
- let(:search_path) { [LIB_PATH] }
5
+ let(:search_path) { [EXAMPLE_DIR] }
6
6
  let(:replacements) { {} }
7
+ let(:do_not_close) { false } # Setting this to true prevents the @output being closed (and preventing further calls of scan_*())
8
+ let(:mergit_options) { { :string => '', :do_not_close => do_not_close } }
9
+ subject { Mergit::Processor.new(search_path, replacements, mergit_options) }
10
+
11
+ let(:no_requires_file) { EXAMPLE_DIR + 'no_requires.rb' }
12
+ let(:has_requires_file) { EXAMPLE_DIR + 'has_requires.rb' }
13
+ let(:relative_path_file) { EXAMPLE_DIR + 'relative' + 'path.rb' }
14
+
15
+ describe "#new" do
16
+ context "when passed a filename" do
17
+ after { Mergit::Processor.new(search_path, replacements, :filename => no_requires_file) }
18
+
19
+ it "should not add MERGIT comments" do
20
+ Mergit::Processor.any_instance.should_not_receive(:emit).with(/MERGIT/)
21
+ end
22
+ end
23
+ end
7
24
 
8
25
  describe "find_requirement" do
9
- subject { Mergit::Processor.new(search_path, replacements, :string => '') }
26
+ let(:expected_filename) { has_requires_file }
10
27
 
11
- context "with a known lib-file" do
12
- let(:lib_file) { Pathname.new File.expand_path('../../../lib/mergit.rb', __FILE__) }
13
- let(:lib_name) { lib_file.basename '.rb' }
28
+ shared_examples "find requirement" do
29
+ it "should return an absolute path" do
30
+ subject.find_requirement(filename).should be_absolute
31
+ end
14
32
 
15
- it "should find mergit.rb" do
16
- subject.find_requirement(lib_name).should eq(lib_file)
33
+ it "should return the expected Pathname" do
34
+ subject.find_requirement(filename).should eq(expected_filename)
17
35
  end
18
36
  end
19
37
 
38
+ context "with relative string filename" do
39
+ let(:filename) { expected_filename.basename('.rb').to_s }
40
+ it_behaves_like "find requirement"
41
+ end
42
+
43
+ context "with absolute string filename" do
44
+ let(:filename) { expected_filename.to_s }
45
+ it_behaves_like "find requirement"
46
+ end
47
+
48
+ context "with relative Pathname filename" do
49
+ let(:filename) { expected_filename.basename('.rb') }
50
+ it_behaves_like "find requirement"
51
+ end
52
+
53
+ context "with absolute Pathname filename" do
54
+ let(:filename) { expected_filename }
55
+ it_behaves_like "find requirement"
56
+ end
57
+
20
58
  it "should return nil if it doesn't exist" do
21
59
  subject.find_requirement('does-not-exist').should be_nil
22
60
  end
23
61
  end
24
62
 
25
- describe "find_requirement!" do
26
- subject { Mergit::Processor.new(search_path, replacements, :string => '') }
63
+ describe "scan_file" do
64
+ let(:do_not_close) { true }
27
65
 
28
- context "with a known lib-file" do
29
- let(:lib_file) { Pathname.new File.expand_path('../../../lib/mergit.rb', __FILE__) }
30
- let(:lib_name) { lib_file.basename '.rb' }
66
+ shared_examples "it emits a string that" do
67
+ before { subject.scan_file(path) }
31
68
 
32
- it "should find mergit.rb" do
33
- subject.find_requirement!(lib_name).should eq(lib_file)
69
+ it "should start with a MERGIT comment" do
70
+ subject.output.should =~ /\A### MERGIT: Start of '#{path}'$/
71
+ end
72
+
73
+ it "should end with a MERGIT comment" do
74
+ subject.output.should =~ /^### MERGIT: End of '#{path}'\Z/
34
75
  end
35
76
  end
36
77
 
37
- it "should raise an exception when it doesn't exist" do
38
- expect { subject.find_requirement!('does-not-exist') }.
39
- to raise_error(Mergit::RequirementNotFound)
78
+ context "with an absolute path" do
79
+ let(:path) { no_requires_file }
80
+ it_behaves_like "it emits a string that"
40
81
  end
41
- end
42
82
 
43
- describe "scan_file" do
44
- subject { Mergit::Processor.new(search_path, replacements, :string => '', :do_not_close => true) }
83
+ context "with a relative path" do
84
+ let(:path) { 'relative/path' }
85
+ it_behaves_like "it emits a string that"
86
+ end
45
87
 
46
88
  context "of an existing lib_file" do
47
- let(:lib_file) { Pathname.new('../../../lib/mergit/version.rb').expand_path(__FILE__) }
48
- let(:relative_lib_file) { 'lib/mergit/version.rb' }
49
- let(:lib_name) { lib_file.basename '.rb' }
89
+ let(:lib_file) { no_requires_file }
50
90
 
51
91
  it "should call .scan_line multiple times" do
52
- subject.should_receive(:scan_line).at_least(3).times
92
+ subject.should_receive(:scan_line).exactly(3).times
53
93
  subject.scan_file(lib_file)
54
94
  end
55
95
 
56
- context "then the output" do
57
- before { subject.scan_file(lib_file) }
58
- it "should start with the merget header" do
59
- subject.output.should =~ /\A### MERGIT: Start of '#{relative_lib_file}'$/
60
- end
61
-
62
- it "should end with the merget header" do
63
- subject.output.should =~ /^### MERGIT: End of '#{relative_lib_file}'\Z/
64
- end
96
+ it "should return true" do
97
+ subject.scan_file(lib_file).should be_true
98
+ end
65
99
 
66
- it "contain the contents of lib_file" do
67
- subject.output.should include(lib_file.read)
68
- end
100
+ it "contain the contents of lib_file" do
101
+ subject.scan_file(lib_file)
102
+ subject.output.should include(lib_file.read)
69
103
  end
70
104
  end
71
105
 
72
- context "with a lib_file that has a requires" do
73
- let(:required_content) { Pathname.new('../../../lib/mergit/version.rb').expand_path(__FILE__).read }
74
- let(:lib_file) { Pathname.new('../../../lib/mergit.rb').expand_path(__FILE__) }
75
- subject { Mergit::Processor.new(search_path, replacements, :string => '', :do_not_close => true) }
76
- before { subject.scan_file(lib_file) }
106
+ it "should call .find_requirement with the filename" do
107
+ subject.should_receive(:find_requirement).with('some_file_name')
108
+ subject.scan_file('some_file_name')
109
+ end
110
+
111
+ context "with a filename that contains a requires" do
112
+ let(:filename) { has_requires_file }
113
+ let(:required_file) { no_requires_file }
114
+ before { subject.scan_file(filename) }
77
115
 
78
116
  it "should contain the required file" do
79
- subject.output.should include(required_content)
117
+ subject.output.should include(required_file.read)
118
+ end
119
+ end
120
+
121
+ context "called a second time with the same filename" do
122
+ before { subject.scan_file(no_requires_file) }
123
+
124
+ it "should return true" do
125
+ subject.scan_file(no_requires_file).should be_true
126
+ end
127
+ end
128
+
129
+ context "with a filename that doesn't exist" do
130
+ it "should return false" do
131
+ subject.scan_file('file-does-not-exist').should be_false
80
132
  end
81
133
  end
82
134
  end
83
135
 
84
136
  describe "scan" do
85
- subject { Mergit::Processor.new(search_path, replacements, :string => '', :do_not_close => true) }
137
+ let(:do_not_close) { true }
86
138
 
87
139
  context "with a string" do
88
140
  let(:ruby_string) { "puts 'hello'\nrequire 'pathname'\n\nputs 'goodbye'\n" }
@@ -112,14 +164,22 @@ describe Mergit::Processor do
112
164
  end
113
165
 
114
166
  describe "scan_line" do
115
- subject { Mergit::Processor.new(search_path, replacements, :string => '', :do_not_close => true) }
167
+ let(:do_not_close) { true }
116
168
 
117
169
  context "given a single requires" do
118
- let(:ruby_string) { "require 'mergit/version'" }
170
+ let(:ruby_string) { "require 'no_requires'" }
119
171
  after { subject.scan_line ruby_string }
120
172
 
121
173
  it "should call scan_file()" do
122
- subject.should_receive(:scan_file).with(Pathname.new('../../../lib/mergit/version.rb').expand_path(__FILE__)).once
174
+ subject.should_receive(:scan_file).with('no_requires').once
175
+ end
176
+
177
+ context "that has a comment after it" do
178
+ let(:ruby_string) { "require 'no_requires' # this is a comment" }
179
+
180
+ it "should call scan_file()" do
181
+ subject.should_receive(:scan_file).with('no_requires').once
182
+ end
123
183
  end
124
184
  end
125
185
 
@@ -163,7 +223,6 @@ describe Mergit::Processor do
163
223
  end
164
224
 
165
225
  describe "string_split" do
166
- subject { Mergit::Processor.new(search_path, replacements, :string => '') }
167
226
  let(:example_parts) { [ 'one', '', 'two', 'three' ] }
168
227
 
169
228
  context "with unix newlines" do
@@ -182,15 +241,9 @@ describe Mergit::Processor do
182
241
  end
183
242
 
184
243
  context "with looping requires" do
244
+ let(:search_path) { [dir] }
245
+ let(:do_not_close) { true }
185
246
  let(:dir) { EXAMPLE_DIR + 'loop' }
186
- subject do
187
- Mergit::Processor.new(
188
- [ dir ],
189
- {},
190
- :string => '',
191
- :do_not_close => true
192
- )
193
- end
194
247
 
195
248
  it "should not go into an infinite loop" do
196
249
  subject.scan_file(dir + 'a.rb')
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mergit
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-04-18 00:00:00.000000000 Z
12
+ date: 2013-04-19 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -243,9 +243,12 @@ files:
243
243
  - lib/mergit/processor.rb
244
244
  - lib/mergit/version.rb
245
245
  - mergit.gemspec
246
+ - spec/examples/has_requires.rb
246
247
  - spec/examples/loop/a.rb
247
248
  - spec/examples/loop/b.rb
248
249
  - spec/examples/loop/c.rb
250
+ - spec/examples/no_requires.rb
251
+ - spec/examples/relative/path.rb
249
252
  - spec/mergit/processor_spec.rb
250
253
  - spec/mergit_spec.rb
251
254
  - spec/spec_helper.rb
@@ -264,7 +267,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
264
267
  version: '0'
265
268
  segments:
266
269
  - 0
267
- hash: 3687644075462403820
270
+ hash: -3347449453804380460
268
271
  required_rubygems_version: !ruby/object:Gem::Requirement
269
272
  none: false
270
273
  requirements:
@@ -273,7 +276,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
273
276
  version: '0'
274
277
  segments:
275
278
  - 0
276
- hash: 3687644075462403820
279
+ hash: -3347449453804380460
277
280
  requirements: []
278
281
  rubyforge_project:
279
282
  rubygems_version: 1.8.23
@@ -281,9 +284,12 @@ signing_key:
281
284
  specification_version: 3
282
285
  summary: Merge 'require'd files into one file.
283
286
  test_files:
287
+ - spec/examples/has_requires.rb
284
288
  - spec/examples/loop/a.rb
285
289
  - spec/examples/loop/b.rb
286
290
  - spec/examples/loop/c.rb
291
+ - spec/examples/no_requires.rb
292
+ - spec/examples/relative/path.rb
287
293
  - spec/mergit/processor_spec.rb
288
294
  - spec/mergit_spec.rb
289
295
  - spec/spec_helper.rb