rpatch 0.0.1 → 0.0.2

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/lib/rpatch/patch.rb CHANGED
@@ -2,9 +2,13 @@
2
2
  #
3
3
 
4
4
  require 'rpatch/error'
5
+ require 'rpatch/utils'
5
6
  require 'rpatch/entry'
6
7
 
7
8
  module Rpatch
9
+
10
+ REGEXP_VALID_HUNK_PREFIX = /^(@@| |-|\+|RE: |RE:-|\/ |\/-|<$|>$|\?( |-|\+|\/ |\/-|\/\+))/
11
+
8
12
  class Patch
9
13
  attr_reader :name, :level, :patch_entries
10
14
 
@@ -27,7 +31,7 @@ module Rpatch
27
31
  end
28
32
  patch_status
29
33
  rescue Exception => e
30
- STDERR.puts "Error: #{e.message}"
34
+ Tty.error e.message
31
35
  patch_status = false
32
36
  end
33
37
  end
@@ -55,7 +59,7 @@ module Rpatch
55
59
  patch_entry.patch_on_file(input, output) || patch_status = false
56
60
  end
57
61
  rescue Exception => e
58
- STDERR.puts "Error: #{e.message}"
62
+ Tty.error e.message
59
63
  patch_status = false
60
64
  end
61
65
  end
@@ -83,7 +87,7 @@ module Rpatch
83
87
  level = $2
84
88
  end
85
89
  unless filename.start_with? '#'
86
- apply_one(path, filename, level) || patch_status = false
90
+ apply_one(path, File.join(quilt_dir, filename), level) || patch_status = false
87
91
  end
88
92
  end
89
93
  end
@@ -101,19 +105,19 @@ module Rpatch
101
105
  entry_names = find_new_entry(lines[i..i+6])
102
106
  if entry_names
103
107
  @patch_entries << PatchEntry.new(entry_names[0], entry_names[1], @level)
104
- while not lines[i] =~ /^@@ / and lines[i]
108
+ while not lines[i] =~ /^@@/ and lines[i]
105
109
  i += 1
106
110
  end
107
111
  break unless i < lines.size
108
112
  end
109
113
 
110
114
  if @patch_entries.any?
111
- if lines[i] =~ /^(@@| |-|\+|RE: |RE:-)/
115
+ if lines[i] =~ REGEXP_VALID_HUNK_PREFIX
112
116
  @patch_entries.last.feed_line lines[i]
113
117
  elsif lines[i] =~ /^(Binary files |Only in)/
114
118
  # ignore
115
119
  else
116
- raise PatchFormatError, "Line #{i} of patch \"#{name}\" is invalid.\n\t=> #{lines[i].inspect}"
120
+ raise PatchFormatError, "Line #{i} of patch \"#{name}\" is invalid.\n=> #{lines[i].inspect}"
117
121
  end
118
122
  end
119
123
 
@@ -132,22 +136,27 @@ module Rpatch
132
136
  end
133
137
 
134
138
  def find_new_entry(lines)
135
- return nil if lines[0] =~ /^(@@| |-|\+|RE: |RE:-)/
136
139
  old = new = nil
137
- lines_dup = lines.dup
138
- line = lines_dup.shift
139
- line = lines_dup.shift if line =~ /^diff /
140
- line = lines_dup.shift if line =~ /^new file mode/
141
- line = lines_dup.shift if line =~ /^index /
142
- if line =~ /^--- (.+?)([\s]+[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}.*)?$/
143
- old = $1
144
- line = lines_dup.shift
145
- end
146
- if line =~ /^\+\+\+ (.+?)([\s]+[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}.*)?$/
147
- new = $1
148
- line = lines_dup.shift
140
+ lines = lines.dup
141
+ while lines.first
142
+ case lines.first
143
+ when /^--- (.+?)([\s]+[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}.*)?$/
144
+ old = $1
145
+ when /^\+\+\+ (.+?)([\s]+[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}.*)?$/
146
+ new = $1
147
+ when REGEXP_VALID_HUNK_PREFIX
148
+ break
149
+ when /^(diff |new file mode|index )/
150
+ # Ignore GNU/Git diff header
151
+ when /^(Index:|=+)/
152
+ # Ignore quilt patch header
153
+ else
154
+ # Ignore comments in the header
155
+ end
156
+ lines.shift
149
157
  end
150
- if line =~ /^@@ / and old and new
158
+
159
+ if lines.first =~ /^@@/ and old and new
151
160
  [old, new]
152
161
  else
153
162
  nil
data/lib/rpatch/runner.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  require 'optparse'
2
- require 'rpatch/patch'
2
+ require 'rpatch/utils'
3
3
  require 'rpatch/version'
4
+ require 'rpatch/patch'
4
5
 
5
6
  module Rpatch
6
7
  class Runner
@@ -13,10 +14,12 @@ module Rpatch
13
14
  OptionParser.new do |opts|
14
15
  opts.banner = "Usage: rpatch [options] [originalfile [patchfile]]"
15
16
  opts.on("-p", "--strip num", "Patch level") {|v| patch_level = v.to_i}
16
- opts.on("-v", "--version", "Show version") do
17
+ opts.on("-V", "--version", "Show version") do
17
18
  puts "Version #{Rpatch::VERSION}"
18
19
  exit 0
19
20
  end
21
+ opts.on("-v", "--verbose", "More verbose") {Tty.options[:verbose] += 1}
22
+ opts.on("-q", "--quiet", "Less verbose") {Tty.options[:verbose] -= 1}
20
23
  opts.on_tail("-h", "--help", "Show this message") do
21
24
  puts opts
22
25
  exit 0
@@ -0,0 +1,121 @@
1
+ require 'rpatch/error'
2
+
3
+ module Rpatch
4
+
5
+ class Tty
6
+ class << self
7
+ def options
8
+ @options ||= {:verbose => 0}
9
+ end
10
+ def blue; bold 34; end
11
+ def white; bold 39; end
12
+ def red; underline 31; end
13
+ def yellow; underline 33 ; end
14
+ def reset; escape 0; end
15
+ def em; underline 39; end
16
+ def green; color 92 end
17
+ def gray; bold 30 end
18
+
19
+ def width
20
+ @width = begin
21
+ w = %x{stty size 2>/dev/null}.chomp.split.last.to_i.nonzero?
22
+ w ||= %x{tput cols 2>/dev/null}.to_i
23
+ w < 1 ? 80 : w
24
+ end
25
+ end
26
+
27
+ def die(*messages)
28
+ error messages
29
+ exit 1
30
+ end
31
+
32
+ def tty_puts(*args)
33
+ opts = args.last.is_a?(Hash) ? args.pop : {}
34
+
35
+ case (opts[:type] || :notice).to_s.downcase.to_sym
36
+ when :error
37
+ # always show errors
38
+ when :warning
39
+ return if verbose < -1
40
+ when :notice
41
+ return if verbose < 0
42
+ when :info
43
+ return if verbose < 1
44
+ when :debug
45
+ return if verbose < 2
46
+ end
47
+
48
+ lines = args.map{|m| m.to_s.split($/)}.flatten
49
+ prompt = opts[:type] ? "#{opts[:type].to_s.upcase}: " : ""
50
+ if opts[:type]
51
+ if STDERR.tty?
52
+ STDERR.write "#{Tty.red}#{prompt}#{Tty.reset}"
53
+ else
54
+ STDERR.write "#{prompt}"
55
+ end
56
+ end
57
+ if STDERR.tty? and opts[:color] and Tty.respond_to? opts[:color]
58
+ STDERR.puts "#{Tty.send(opts[:color])}#{lines.shift}#{Tty.reset}"
59
+ else
60
+ STDERR.puts lines.shift
61
+ end
62
+ spaces = " " * prompt.size
63
+ lines.each do |line|
64
+ STDERR.write spaces
65
+ if STDERR.tty? and opts[:color] and Tty.respond_to? opts[:color]
66
+ STDERR.puts "#{Tty.send(opts[:color])}#{line}#{Tty.reset}"
67
+ else
68
+ STDERR.puts line
69
+ end
70
+ end
71
+ end
72
+
73
+ def error(*messages)
74
+ tty_puts(*messages << {:type => :error, :color => :red})
75
+ end
76
+
77
+ def warning(*messages)
78
+ tty_puts(*messages << {:type => :warning, :color => :yellow})
79
+ end
80
+
81
+ def notice(*messages)
82
+ tty_puts(*messages << {:type => nil})
83
+ end
84
+
85
+ def info(*messages)
86
+ tty_puts(*messages << {:type => :info, :color => :green})
87
+ end
88
+
89
+ def debug(*messages)
90
+ tty_puts(*messages << {:type => :debug, :color => :blue})
91
+ end
92
+
93
+ private
94
+
95
+ def verbose
96
+ options[:verbose]
97
+ end
98
+
99
+ def color n
100
+ escape "0;#{n}"
101
+ end
102
+ def bold n
103
+ escape "1;#{n}"
104
+ end
105
+ def underline n
106
+ escape "4;#{n}"
107
+ end
108
+ def escape n
109
+ "\033[#{n}m" if $stdout.tty?
110
+ end
111
+
112
+ end
113
+ end
114
+ end
115
+
116
+ class String
117
+ def charat(n)
118
+ result = self.send "[]", n
119
+ RUBY_VERSION < "1.9" ? result.chr : result
120
+ end
121
+ end
@@ -1,3 +1,3 @@
1
1
  module Rpatch
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -5,23 +5,24 @@ require 'spec_helper'
5
5
  require 'stringio'
6
6
 
7
7
  describe Rpatch::Patch do
8
- let(:diff) do
9
- <<-EOF
8
+
9
+ it "regexp patterns test" do
10
+ diff = <<-EOF
10
11
  diff -ru before/readme.txt after/readme.txt
11
12
  --- a/readme.txt 2013-11-03 22:17:02.000000000 +0800
12
13
  +++ b/readme.txt 2013-11-03 21:10:46.000000000 +0800
13
14
  @@ remove two leading lines
14
15
  -I have a script to patch text files, it's more like
15
- RE:-.* Why not (patch|GNU patch)?
16
+ /-.* Why not (patch|GNU patch)?
16
17
  When I hack files using GNU patch,
17
- RE: sometimes fail because .*
18
+ / sometimes fail because .*
18
19
  @@ add copyright
19
20
  +/*
20
21
  + * Copyright (c) 2013 Jiang Xin
21
22
  + */
22
23
  +
23
24
  When I hack files using GNU patch,
24
- RE: sometimes fail because .*
25
+ / sometimes fail because .*
25
26
  @@ add notes
26
27
  +If patch can ignore blank lines, support regex patterns
27
28
  +in patch, it will be nice.
@@ -32,9 +33,7 @@ RE: sometimes fail because .*
32
33
  +--
33
34
  +jiangxin
34
35
  EOF
35
- end
36
36
 
37
- it "patch on file" do
38
37
  before = <<-EOF
39
38
  I have a script to patch text files, it's more like
40
39
  "grep" and "seed -s". Why not GNU patch?
@@ -69,5 +68,4 @@ jiangxin
69
68
  patch.apply_to(inputfile, outputfile)
70
69
  output.should == after
71
70
  end
72
-
73
71
  end
@@ -171,9 +171,16 @@ jiangxin
171
171
  before = ''
172
172
 
173
173
  diff = <<-EOF
174
- diff -ru before/readme.txt after/readme.txt
175
- --- a/readme.txt 2013-11-03 22:17:02.000000000 +0800
176
- +++ b/readme.txt 2013-11-03 21:10:46.000000000 +0800
174
+ Test for patching for new file
175
+
176
+ * note 1
177
+ * note 2
178
+ * note 3
179
+
180
+ Index: a/readme.txt
181
+ ===================================================================
182
+ --- /dev/null 2013-11-03 22:17:02.000000000 +0800
183
+ +++ b/readme.txt 2013-11-03 21:10:46.000000000 +0800
177
184
  @@ initial
178
185
  +hello
179
186
  +world
@@ -0,0 +1,149 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+
4
+ require 'spec_helper'
5
+
6
+ describe Rpatch::PatchHunk do
7
+
8
+ it "patch has default location direction" do
9
+ diff = <<-EOF
10
+ +foo
11
+ +bar
12
+ EOF
13
+
14
+ before = <<-EOF
15
+ hello
16
+ world
17
+ EOF
18
+
19
+ after = <<-EOF
20
+ foo
21
+ bar
22
+ hello
23
+ world
24
+ EOF
25
+
26
+ hunk = Rpatch::PatchHunk.new('@@ description')
27
+ diff.split($/).each {|line| hunk.feed_line line.chomp}
28
+
29
+ hunk.match_after_patch(before.split($/)).should eq nil
30
+ hunk.match_before_patch(before.split($/)).should eq [0, 0]
31
+ result = hunk.patch(before.split($/))
32
+ (result * "\n" + "\n").should eq after
33
+ end
34
+
35
+ it "patch has head location direction" do
36
+ diff = <<-EOF
37
+ <
38
+ +foo
39
+ +bar
40
+ EOF
41
+
42
+ before = <<-EOF
43
+ hello
44
+ world
45
+ EOF
46
+
47
+ after = <<-EOF
48
+ foo
49
+ bar
50
+ hello
51
+ world
52
+ EOF
53
+
54
+ hunk = Rpatch::PatchHunk.new('@@ description')
55
+ diff.split($/).each {|line| hunk.feed_line line.chomp}
56
+
57
+ hunk.match_after_patch(before.split($/)).should eq nil
58
+ hunk.match_before_patch(before.split($/)).should eq [0, 0]
59
+ result = hunk.patch(before.split($/))
60
+ (result * "\n" + "\n").should eq after
61
+ end
62
+
63
+ it "patch has tail location direction" do
64
+ diff = <<-EOF
65
+ >
66
+ +foo
67
+ +bar
68
+ EOF
69
+
70
+ before = <<-EOF
71
+ hello
72
+ world
73
+ EOF
74
+
75
+ after = <<-EOF
76
+ hello
77
+ world
78
+ foo
79
+ bar
80
+ EOF
81
+
82
+ hunk = Rpatch::PatchHunk.new('@@ description')
83
+ diff.split($/).each {|line| hunk.feed_line line.chomp}
84
+
85
+ hunk.match_after_patch(before.split($/)).should eq nil
86
+ hunk.match_before_patch(before.split($/)).should eq [2, 0]
87
+ result = hunk.patch(before.split($/))
88
+ (result * "\n" + "\n").should eq after
89
+ end
90
+
91
+ it "patch has head location direction (2)" do
92
+ diff = <<-EOF
93
+ <
94
+ hello
95
+ +foo
96
+ +bar
97
+ EOF
98
+
99
+ before = <<-EOF
100
+ hello
101
+ hello
102
+ EOF
103
+
104
+ after = <<-EOF
105
+ hello
106
+ foo
107
+ bar
108
+ hello
109
+ EOF
110
+
111
+ hunk = Rpatch::PatchHunk.new('@@ description')
112
+ diff.split($/).each {|line| hunk.feed_line line.chomp}
113
+
114
+ hunk.match_after_patch(before.split($/)).should eq nil
115
+ hunk.match_before_patch(before.split($/)).should eq [0, 1]
116
+ result = hunk.patch(before.split($/))
117
+ (result * "\n" + "\n").should eq after
118
+ end
119
+
120
+ it "patch has tail location direction (2)" do
121
+ diff = <<-EOF
122
+ >
123
+ hello
124
+ +foo
125
+ +bar
126
+ EOF
127
+
128
+ before = <<-EOF
129
+ hello
130
+ hello
131
+ EOF
132
+
133
+ after = <<-EOF
134
+ hello
135
+ hello
136
+ foo
137
+ bar
138
+ EOF
139
+
140
+ hunk = Rpatch::PatchHunk.new('@@ description')
141
+ diff.split($/).each {|line| hunk.feed_line line.chomp}
142
+
143
+ hunk.match_after_patch(before.split($/)).should eq nil
144
+ hunk.match_before_patch(before.split($/)).should eq [1, 1]
145
+ result = hunk.patch(before.split($/))
146
+ (result * "\n" + "\n").should eq after
147
+ end
148
+
149
+ end