rpatch 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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